$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r56731 - in sandbox/ggl/formal_review_request: . boost boost/ggl boost/ggl/algorithms boost/ggl/algorithms/detail boost/ggl/algorithms/overlay boost/ggl/arithmetic boost/ggl/core boost/ggl/core/concepts boost/ggl/extensions boost/ggl/extensions/gis boost/ggl/extensions/gis/io boost/ggl/extensions/gis/io/wkt boost/ggl/extensions/gis/io/wkt/detail boost/ggl/extensions/io boost/ggl/extensions/io/svg boost/ggl/geometries boost/ggl/geometries/adapted boost/ggl/geometries/register boost/ggl/iterators boost/ggl/multi boost/ggl/multi/algorithms boost/ggl/multi/algorithms/detail boost/ggl/multi/algorithms/overlay boost/ggl/multi/core boost/ggl/multi/geometries boost/ggl/multi/iterators boost/ggl/policies boost/ggl/policies/relate boost/ggl/strategies boost/ggl/strategies/agnostic boost/ggl/strategies/cartesian boost/ggl/strategies/spherical boost/ggl/strategies/transform boost/ggl/util libs libs/test
From: barend.gehrels_at_[hidden]
Date: 2009-10-12 08:58:31
Author: barendgehrels
Date: 2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
New Revision: 56731
URL: http://svn.boost.org/trac/boost/changeset/56731
Log:
Added branch for formal review request
Added:
   sandbox/ggl/formal_review_request/
   sandbox/ggl/formal_review_request/boost/
   sandbox/ggl/formal_review_request/boost/ggl/
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/append.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/area.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/assign.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/buffer.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/centroid.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/clear.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/combine.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/convert.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/convex_hull.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/correct.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/detail/
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/detail/calculate_null.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/detail/not.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/disjoint.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/distance.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/envelope.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/equals.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/for_each.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/get_section.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/intermediate.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersection.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersection_linestring.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersects.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/length.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/make.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/num_points.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlaps.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/adapt_turns.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/copy_segments.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/enrich_intersection_points.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/get_intersection_points.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/intersection_point.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/merge_intersection_points.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/segment_identifier.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/self_intersection_points.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/traverse.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/perimeter.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/sectionalize.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/selected.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/simplify.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/transform.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/algorithms/within.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/arithmetic/
   sandbox/ggl/formal_review_request/boost/ggl/arithmetic/arithmetic.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/arithmetic/dot_product.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/
   sandbox/ggl/formal_review_request/boost/ggl/core/access.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/concepts/
   sandbox/ggl/formal_review_request/boost/ggl/core/concepts/box_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/concepts/linestring_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/concepts/nsphere_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/concepts/point_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/concepts/polygon_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/concepts/ring_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/concepts/segment_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/coordinate_dimension.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/coordinate_system.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/coordinate_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/cs.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/exception.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/exterior_ring.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/geometry_id.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/interior_rings.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/is_linear.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/is_multi.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/point_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/radian_access.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/radius.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/replace_point_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/reverse_dispatch.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/ring_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/tag.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/tags.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/core/topological_dimension.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/extensions/
   sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/
   sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/
   sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/
   sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/detail/
   sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/detail/wkt.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/detail/wkt_multi.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/read_wkt.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/read_wkt_multi.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/stream_wkt.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/wkt.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/write_wkt.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/write_wkt_multi.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/extensions/io/
   sandbox/ggl/formal_review_request/boost/ggl/extensions/io/svg/
   sandbox/ggl/formal_review_request/boost/ggl/extensions/io/svg/write_svg.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/extensions/io/svg/write_svg_multi.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/
   sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/
   sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/boost_array_as_linestring.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/boost_array_as_ring.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/c_array.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/c_array_cartesian.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/std_as_linestring.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/std_as_ring.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/tuple.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/tuple_cartesian.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/box.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/cartesian2d.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/cartesian3d.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/geometries.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/linear_ring.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/linestring.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/nsphere.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/point.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/point_xy.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/polygon.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/register/
   sandbox/ggl/formal_review_request/boost/ggl/geometries/register/box.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/register/linestring.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/register/point.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/register/register_box.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/register/register_point.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/register/ring.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/geometries/segment.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/ggl.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/iterators/
   sandbox/ggl/formal_review_request/boost/ggl/iterators/base.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/iterators/ever_circling_iterator.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/iterators/point_const_iterator.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/iterators/segment_iterator.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/area.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/centroid.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/convex_hull.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/correct.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/detail/
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/detail/modify_with_predicate.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/detail/multi_sum.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/distance.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/envelope.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/foreach.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/get_section.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/intersection.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/length.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/num_points.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/overlay/
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/overlay/copy_segments.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/overlay/get_intersection_points.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/perimeter.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/sectionalize.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/simplify.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/transform.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/within.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/core/
   sandbox/ggl/formal_review_request/boost/ggl/multi/core/geometry_id.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/core/is_multi.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/core/point_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/core/ring_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/core/tags.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/core/topological_dimension.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/geometries/
   sandbox/ggl/formal_review_request/boost/ggl/multi/geometries/multi_linestring.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/geometries/multi_point.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/geometries/multi_polygon.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/multi/iterators/
   sandbox/ggl/formal_review_request/boost/ggl/multi/iterators/point_const_iterator.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/policies/
   sandbox/ggl/formal_review_request/boost/ggl/policies/relate/
   sandbox/ggl/formal_review_request/boost/ggl/policies/relate/de9im.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/policies/relate/direction.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/policies/relate/intersection_points.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/policies/relate/tupled.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/
   sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/
   sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/agn_convex_hull.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/agn_simplify.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/agn_within.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/
   sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_area.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_centroid.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_compare.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_distance.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_envelope.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_intersect.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_side.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_within.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/distance_result.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/intersection_result.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/
   sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/haversine.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/sph_area.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/sph_envelope.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/strategies.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/strategy_traits.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/strategy_transform.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/transform/
   sandbox/ggl/formal_review_request/boost/ggl/strategies/transform/inverse_transformer.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/transform/map_transformer.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/strategies/transform/matrix_transformers.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/util/
   sandbox/ggl/formal_review_request/boost/ggl/util/as_range.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/util/assign_box_corner.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/util/copy.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/util/for_each_coordinate.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/util/get_cs_as_radian.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/util/less.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/util/loop.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/util/math.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/util/select_coordinate_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/util/select_most_precise.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/boost/ggl/util/write_dsv.hpp   (contents, props changed)
   sandbox/ggl/formal_review_request/libs/
   sandbox/ggl/formal_review_request/libs/test/
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/append.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/append.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,197 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_APPEND_HPP
+#define GGL_ALGORITHMS_APPEND_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/concept_check.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/core/tags.hpp>
+#include <ggl/util/copy.hpp>
+
+namespace ggl
+{
+
+namespace traits
+{
+
+/*!
+    \brief Traits class, optional, might be implemented to append a point
+    \details If a geometry type should not use the std "push_back" then it can specialize
+    the "use_std" traits class to false, it should then implement (a.o.) append_point
+    \ingroup traits
+    \par Geometries:
+        - linestring
+        - linear_ring
+    \par Specializations should provide:
+        - run
+ */
+template <typename G, typename P>
+struct append_point
+{
+};
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace append {
+
+template <typename G, typename P, bool Std>
+struct append_point {};
+
+template <typename G, typename P>
+struct append_point<G, P, true>
+{
+    static inline void apply(G& geometry, P const& point, int , int )
+    {
+        typename point_type<G>::type point_type;
+
+        copy_coordinates(point, point_type);
+        geometry.push_back(point_type);
+    }
+};
+
+template <typename G, typename P>
+struct append_point<G, P, false>
+{
+    static inline void apply(G& geometry, P const& point, int ring_index, int multi_index)
+    {
+        traits::append_point<G, P>::apply(geometry, point, ring_index, multi_index);
+    }
+};
+
+template <typename G, typename R, bool Std>
+struct append_range
+{
+    typedef typename boost::range_value<R>::type point_type;
+
+    static inline void apply(G& geometry, R const& range, int ring_index, int multi_index)
+    {
+        for (typename boost::range_const_iterator<R>::type it = boost::begin(range);
+             it != boost::end(range); ++it)
+        {
+            append_point<G, point_type, Std>::apply(geometry, *it, ring_index, multi_index);
+        }
+    }
+};
+
+template <typename P, typename T, bool Std>
+struct point_to_poly
+{
+    typedef typename ring_type<P>::type range_type;
+
+    static inline void apply(P& polygon, T const& point, int ring_index, int multi_index)
+    {
+        boost::ignore_unused_variable_warning(multi_index);
+
+        if (ring_index == -1)
+        {
+            append_point<range_type, T, Std>::apply(exterior_ring(polygon), point, -1, -1);
+        }
+        else if (ring_index < boost::size(interior_rings(polygon)))
+        {
+            append_point<range_type, T, Std>::apply(interior_rings(polygon)[ring_index], point, -1, -1);
+        }
+    }
+};
+
+template <typename P, typename R, bool Std>
+struct range_to_poly
+{
+    typedef typename ring_type<P>::type ring_type;
+
+    static inline void apply(P& polygon, R const& range, int ring_index, int multi_index)
+    {
+        if (ring_index == -1)
+        {
+            append_range<ring_type, R, Std>::apply(exterior_ring(polygon), range, -1, -1);
+        }
+        else if (ring_index < boost::size(interior_rings(polygon)))
+        {
+            append_range<ring_type, R, Std>::apply(interior_rings(polygon)[ring_index], range, -1, -1);
+        }
+    }
+};
+
+}} // namespace detail::append
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// (RoP = range or point, Std = use std library)
+
+// Default case (where RoP will be range/array/etc)
+template <typename Tag, typename TagRoP, typename G, typename RoP, bool Std>
+struct append : detail::append::append_range<G, RoP, Std> {};
+
+// Append a point to any geometry
+template <typename Tag, typename G, typename P, bool Std>
+struct append<Tag, point_tag, G, P, Std>
+    : detail::append::append_point<G, P, Std> {};
+
+// Never possible to append anything to a point/box/n-sphere
+template <typename TagRoP, typename P, typename RoP, bool Std>
+struct append<point_tag, TagRoP, P, RoP, Std> {};
+
+template <typename TagRoP, typename B, typename RoP, bool Std>
+struct append<box_tag, TagRoP, B, RoP, Std> {};
+
+template <typename TagRoP, typename N, typename RoP, bool Std>
+struct append<nsphere_tag, TagRoP, N, RoP, Std> {};
+
+template <typename P, typename TAG_R, typename R, bool Std>
+struct append<polygon_tag, TAG_R, P, R, Std>
+        : detail::append::range_to_poly<P, R, Std> {};
+
+template <typename P, typename T, bool Std>
+struct append<polygon_tag, point_tag, P, T, Std>
+        : detail::append::point_to_poly<P, T, Std> {};
+
+// Multi-linestring and multi-polygon might either implement traits or use standard...
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Appends one or more points to a linestring, linear-ring, polygon, multi
+    \ingroup access
+    \param geometry a geometry
+    \param range_or_point the point or range to add
+    \param ring_index the index of the ring in case of a polygon: exterior ring (-1, the default) or
+        interior ring index
+    \param multi_index reserved for multi polygons
+ */
+template <typename G, typename RoP>
+inline void append(G& geometry, const RoP& range_or_point,
+            int ring_index = -1, int multi_index = 0)
+{
+    typedef typename boost::remove_const<G>::type ncg_type;
+
+    dispatch::append
+        <
+            typename tag<G>::type,
+            typename tag<RoP>::type,
+            ncg_type,
+            RoP,
+            traits::use_std<ncg_type>::value
+        >::apply(geometry, range_or_point, ring_index, multi_index);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_APPEND_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/area.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/area.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,252 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_AREA_HPP
+#define GGL_ALGORITHMS_AREA_HPP
+
+#include <boost/concept/requires.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/detail/calculate_null.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/core/concepts/nsphere_concept.hpp>
+#include <ggl/strategies/strategies.hpp>
+#include <ggl/util/loop.hpp>
+#include <ggl/util/math.hpp>
+
+/*!
+\defgroup area area calculation
+
+\par Performance
+2776 * 1000 area calculations are done in 0.11 seconds (other libraries: 0.125 seconds, 0.125 seconds, 0.5 seconds)
+
+\par Coordinate systems and strategies
+Area calculation can be done in Cartesian and in spherical/geographic coordinate systems.
+
+\par Geometries
+The area algorithm calculates the surface area of all geometries having a surface:
+box, circle, polygon, multi_polygon. The units are the square of the units used for the points
+defining the surface. If the polygon is defined in meters, the area is in square meters.
+
+\par Example:
+Example showing area calculation of polygons built of xy-points and of latlong-points
+\dontinclude doxygen_examples.cpp
+\skip example_area_polygon()
+\line {
+\until }
+
+*/
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace area {
+
+template<typename B, typename S>
+struct box_area
+{
+    typedef typename coordinate_type<B>::type return_type;
+
+    static inline return_type apply(B const& b, S const&)
+    {
+        // Currently only works for Cartesian boxes
+        // Todo: use strategy
+        // Todo: use concept
+        assert_dimension<B, 2>();
+
+        return_type const dx = get<max_corner, 0>(b) - get<min_corner, 0>(b);
+        return_type const dy = get<max_corner, 1>(b) - get<min_corner, 1>(b);
+
+        return dx * dy;
+    }
+};
+
+
+template<typename C, typename S>
+struct circle_area
+{
+    typedef typename coordinate_type<C>::type coordinate_type;
+
+    // Returning the coordinate precision, but if integer, returning a double
+    typedef typename boost::mpl::if_c
+            <
+                boost::is_integral<coordinate_type>::type::value,
+                double,
+                coordinate_type
+            >::type return_type;
+
+    static inline return_type apply(C const& c, S const&)
+    {
+        // Currently only works for Cartesian circles
+        // Todo: use strategy
+        // Todo: use concept
+        assert_dimension<C, 2>();
+
+        return_type r = get_radius<0>(c);
+        r *= r * ggl::math::pi;
+        return r;
+    }
+};
+
+
+// Area of a linear linear_ring, assuming a closed linear_ring
+template<typename R, typename S>
+struct ring_area
+{
+    typedef typename S::return_type type;
+    static inline type apply(R const& ring, S const& strategy)
+    {
+        assert_dimension<R, 2>();
+
+        // A closed linear_ring has at least four points, if not there is no area
+        if (boost::size(ring) >= 4)
+        {
+            typename S::state_type state_type;
+            if (loop(ring, strategy, state_type))
+            {
+                return state_type.area();
+            }
+        }
+
+        return type();
+    }
+};
+
+// Area of a polygon, either clockwise or anticlockwise
+template<typename Polygon, typename Strategy>
+class polygon_area
+{
+    typedef typename Strategy::return_type type;
+    static inline type call_abs(type const& v)
+    {
+#if defined(NUMERIC_ADAPTOR_INCLUDED)
+        return boost::abs(v);
+#else
+        return std::abs(v);
+#endif
+    }
+
+public:
+    static inline type apply(Polygon const& poly,
+                    Strategy const& strategy)
+    {
+        assert_dimension<Polygon, 2>();
+
+        typedef typename ring_type<Polygon>::type ring_type;
+        typedef typename boost::range_const_iterator
+            <
+                typename interior_type<Polygon>::type
+            >::type iterator_type;
+
+        type a = call_abs(
+            ring_area<ring_type, Strategy>::apply(exterior_ring(poly), strategy));
+
+        for (iterator_type it = boost::begin(interior_rings(poly));
+             it != boost::end(interior_rings(poly)); ++it)
+        {
+            a -= call_abs(ring_area<ring_type, Strategy>::apply(*it, strategy));
+        }
+        return a;
+    }
+};
+
+}} // namespace detail::area
+
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+template <typename Tag, typename G, typename S>
+struct area : detail::calculate_null<typename S::return_type, G, S> {};
+
+
+template <typename G, typename S>
+struct area<box_tag, G, S> : detail::area::box_area<G, S> {};
+
+
+template <typename G, typename S>
+struct area<nsphere_tag, G, S> : detail::area::circle_area<G, S> {};
+
+
+// Area of ring currently returns area of closed rings but it might be argued
+// that it is 0.0, because a ring is just a line.
+template <typename G, typename S>
+struct area<ring_tag, G, S> : detail::area::ring_area<G, S> {};
+
+template <typename G, typename S>
+struct area<polygon_tag, G, S> : detail::area::polygon_area<G, S> {};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template <typename Geometry>
+struct area_result
+{
+    typedef typename point_type<Geometry>::type point_type;
+    typedef typename strategy_area
+        <
+            typename cs_tag<point_type>::type,
+            point_type
+        >::type strategy_type;
+    typedef typename strategy_type::return_type return_type;
+};
+
+/*!
+    \brief Calculate area of a geometry
+    \ingroup area
+    \details The function area returns the area of a polygon, ring, box or circle,
+    using the default area-calculation strategy. Strategies are
+    provided for cartesian ans spherical points
+    The geometries should correct, polygons should be closed and orientated clockwise, holes,
+    if any, must be orientated counter clockwise
+    \param geometry a geometry
+    \return the area
+ */
+template <typename Geometry>
+inline typename area_result<Geometry>::return_type area(Geometry const& geometry)
+{
+    typedef typename area_result<Geometry>::strategy_type strategy_type;
+
+    return dispatch::area
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            strategy_type
+        >::apply(geometry, strategy_type());
+}
+
+/*!
+    \brief Calculate area of a geometry using a strategy
+    \ingroup area
+    \details This version of area calculation takes a strategy
+    \param geometry a geometry
+    \param strategy the strategy to calculate area. Especially for spherical areas there are
+        some approaches.
+    \return the area
+ */
+template <typename Geometry, typename Strategy>
+inline typename Strategy::return_type area(
+        Geometry const& geometry, Strategy const& strategy)
+{
+    return dispatch::area
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            Strategy
+        >::apply(geometry, strategy);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_AREA_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/assign.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/assign.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,410 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_ASSIGN_HPP
+#define GGL_ALGORITHMS_ASSIGN_HPP
+
+#include <cstddef>
+
+#include <boost/concept/requires.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/numeric/conversion/bounds.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <ggl/algorithms/append.hpp>
+#include <ggl/algorithms/clear.hpp>
+#include <ggl/core/access.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/radius.hpp>
+#include <ggl/core/tags.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/util/copy.hpp>
+#include <ggl/util/for_each_coordinate.hpp>
+
+/*!
+\defgroup access access: get/set coordinate values, make objects, clear geometries, append point(s)
+\details There are many ways to edit geometries. It is possible to:
+- use the geometries themselves, so access point.x(). This is not done inside the library because it is agnostic
+ to geometry type. However, library users can use this as it is intuitive.
+- use the standard library, so use .push_back(point) or use inserters. This is also avoided inside the library.
+However, library users can use it if they are used to the standard library
+- use the functionality provided in this geometry library. These are the functions in this module.
+
+The library provides the following functions to edit geometries:
+- set to set one coordinate value
+- assign to set two or more coordinate values
+- make to construct and return geometries with specified coordinates.
+- append to append one or more points to a geometry
+- clear to remove all points from a geometry
+
+For getting coordinates it is similar:
+- get to get a coordinate value
+- or use the standard library
+- or use the geometries themselves
+
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace assign {
+
+template <typename C>
+struct assign_operation
+{
+    inline assign_operation(C const& value)
+        : m_value(value)
+    {}
+
+    template <typename P, std::size_t I>
+    inline void apply(P& point) const
+    {
+        set<I>(point, m_value);
+    }
+
+private:
+
+    C m_value;
+};
+
+
+/*!
+    \brief Assigns all coordinates of a specific point to a value
+    \ingroup access
+    \details
+    \param p Point
+    \param value Value which is assigned to all coordinates of point p
+ */
+template <typename P>
+inline void assign_value(P& p, typename coordinate_type<P>::type const& value)
+{
+    for_each_coordinate(p,
+            assign_operation<typename coordinate_type<P>::type>(value));
+}
+
+
+
+template <typename B, std::size_t C, std::size_t I, std::size_t D>
+struct initialize
+{
+    typedef typename coordinate_type<B>::type coordinate_type;
+
+    static inline void apply(B& box, const coordinate_type& value)
+    {
+        set<C, I>(box, value);
+        initialize<B, C, I + 1, D>::apply(box, value);
+    }
+};
+
+template <typename B, std::size_t C, std::size_t D>
+struct initialize<B, C, D, D>
+{
+    typedef typename coordinate_type<B>::type coordinate_type;
+
+    static inline void apply(B& box, const coordinate_type& value)
+    {
+        boost::ignore_unused_variable_warning(box);
+        boost::ignore_unused_variable_warning(value);
+    }
+};
+
+template <typename Point>
+struct assign_zero_point
+{
+    static inline void apply(Point& point)
+    {
+        typedef typename coordinate_type<Point>::type coordinate_type;
+        assign_value(point, 0);
+    }
+};
+
+
+template <typename Box>
+struct assign_inverse_box
+{
+    typedef typename point_type<Box>::type point_type;
+
+    static inline void apply(Box& box)
+    {
+        typedef typename coordinate_type<point_type>::type coordinate_type;
+
+        initialize
+            <
+                Box, min_corner, 0, dimension<Box>::type::value
+            >::apply(
+            box, boost::numeric::bounds<coordinate_type>::highest());
+        initialize
+            <
+                Box, max_corner, 0, dimension<Box>::type::value
+            >::apply(
+            box, boost::numeric::bounds<coordinate_type>::lowest());
+    }
+};
+
+template <typename Box>
+struct assign_zero_box
+{
+    static inline void apply(Box& box)
+    {
+        typedef typename coordinate_type<Box>::type coordinate_type;
+
+        initialize
+            <
+                Box, min_corner, 0, dimension<Box>::type::value
+            >::apply(box, coordinate_type());
+        initialize
+            <
+                Box, max_corner, 0, dimension<Box>::type::value
+            >::apply(box, coordinate_type());
+    }
+};
+
+
+
+
+}} // namespace detail::assign
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename GeometryTag, typename Geometry, std::size_t DimensionCount>
+struct assign {};
+
+template <typename P>
+struct assign<point_tag, P, 2>
+{
+    typedef typename coordinate_type<P>::type coordinate_type;
+
+    template <typename T>
+    static inline void apply(P& point, T const& c1, T const& c2)
+    {
+        set<0>(point, boost::numeric_cast<coordinate_type>(c1));
+        set<1>(point, boost::numeric_cast<coordinate_type>(c2));
+    }
+};
+
+template <typename P>
+struct assign<point_tag, P, 3>
+{
+    typedef typename coordinate_type<P>::type coordinate_type;
+
+    template <typename T>
+    static inline void apply(P& point, T const& c1, T const& c2, T const& c3)
+    {
+        set<0>(point, boost::numeric_cast<coordinate_type>(c1));
+        set<1>(point, boost::numeric_cast<coordinate_type>(c2));
+        set<2>(point, boost::numeric_cast<coordinate_type>(c3));
+    }
+};
+
+template <typename B>
+struct assign<box_tag, B, 2>
+{
+    typedef typename coordinate_type<B>::type coordinate_type;
+
+    // Here we assign 4 coordinates to a box.
+    // -> Most logical is: x1,y1,x2,y2
+    // In case the user reverses x1/x2 or y1/y2, we could reverse them (THAT IS NOT IMPLEMENTED)
+
+    // Note also comment in util/assign_box_corner ->
+    //   ("Most logical is LOWER, UPPER and sub-order LEFT, RIGHT")
+    //   (That is assigning 4 points from a box. So lower-left, lower-right, upper-left, upper-right)
+    template <typename T>
+    static inline void apply(B& box, T const& x1, T const& y1, T const& x2, T const& y2)
+    {
+        set<min_corner, 0>(box, boost::numeric_cast<coordinate_type>(x1));
+        set<min_corner, 1>(box, boost::numeric_cast<coordinate_type>(y1));
+        set<max_corner, 0>(box, boost::numeric_cast<coordinate_type>(x2));
+        set<max_corner, 1>(box, boost::numeric_cast<coordinate_type>(y2));
+    }
+};
+
+
+
+
+
+template <typename S>
+struct assign<nsphere_tag, S, 2>
+{
+    typedef typename coordinate_type<S>::type coordinate_type;
+    typedef typename radius_type<S>::type radius_type;
+
+    /// 2-value version for an n-sphere is valid for circle and sets the center
+    template <typename T>
+    static inline void apply(S& sphercle, T const& c1, T const& c2)
+    {
+        set<0>(sphercle, boost::numeric_cast<coordinate_type>(c1));
+        set<1>(sphercle, boost::numeric_cast<coordinate_type>(c2));
+    }
+
+    template <typename T, typename R>
+    static inline void apply(S& sphercle, T const& c1,
+        T const& c2, R const& radius)
+    {
+        set<0>(sphercle, boost::numeric_cast<coordinate_type>(c1));
+        set<1>(sphercle, boost::numeric_cast<coordinate_type>(c2));
+        set_radius<0>(sphercle, boost::numeric_cast<radius_type>(radius));
+    }
+};
+
+template <typename S>
+struct assign<nsphere_tag, S, 3>
+{
+    typedef typename coordinate_type<S>::type coordinate_type;
+    typedef typename radius_type<S>::type radius_type;
+
+    /// 4-value version for an n-sphere is valid for a sphere and sets the center and the radius
+    template <typename T>
+    static inline void apply(S& sphercle, T const& c1, T const& c2, T const& c3)
+    {
+        set<0>(sphercle, boost::numeric_cast<coordinate_type>(c1));
+        set<1>(sphercle, boost::numeric_cast<coordinate_type>(c2));
+        set<2>(sphercle, boost::numeric_cast<coordinate_type>(c3));
+    }
+
+    /// 4-value version for an n-sphere is valid for a sphere and sets the center and the radius
+    template <typename T, typename R>
+    static inline void apply(S& sphercle, T const& c1,
+        T const& c2, T const& c3, R const& radius)
+    {
+
+        set<0>(sphercle, boost::numeric_cast<coordinate_type>(c1));
+        set<1>(sphercle, boost::numeric_cast<coordinate_type>(c2));
+        set<2>(sphercle, boost::numeric_cast<coordinate_type>(c3));
+        set_radius<0>(sphercle, boost::numeric_cast<radius_type>(radius));
+    }
+
+};
+
+
+template <typename GeometryTag, typename Geometry>
+struct assign_zero {};
+
+
+template <typename Point>
+struct assign_zero<point_tag, Point>
+    : detail::assign::assign_zero_point<Point>
+{};
+
+template <typename Box>
+struct assign_zero<box_tag, Box>
+    : detail::assign::assign_zero_box<Box>
+{};
+
+
+template <typename GeometryTag, typename Geometry>
+struct assign_inverse {};
+
+template <typename Box>
+struct assign_inverse<box_tag, Box>
+    : detail::assign::assign_inverse_box<Box>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief assign two values to a 2D point
+    \ingroup access
+ */
+template <typename G, typename T>
+inline void assign(G& geometry, T const& c1, T const& c2)
+{
+    dispatch::assign
+        <
+            typename tag<G>::type,
+            G,
+            ggl::dimension<G>::type::value
+        >::apply(geometry, c1, c2);
+}
+
+/*!
+    \brief assign three values to a 3D point or the center + radius to a circle
+    \ingroup access
+ */
+template <typename G, typename T>
+inline void assign(G& geometry, T const& c1, T const& c2, T const& c3)
+{
+    dispatch::assign
+        <
+            typename tag<G>::type,
+            G,
+            ggl::dimension<G>::type::value
+        >::apply(geometry, c1, c2, c3);
+}
+
+/*!
+    \brief assign center + radius to a sphere
+    \ingroup access
+ */
+template <typename G, typename T>
+inline void assign(G& geometry, T const& c1, T const& c2, T const& c3, T const& c4)
+{
+    dispatch::assign
+        <
+            typename tag<G>::type,
+            G,
+            ggl::dimension<G>::type::value
+        >::apply(geometry, c1, c2, c3, c4);
+}
+
+
+/*!
+    \brief assign a range of points to a linestring, ring or polygon
+    \note The point-type of the range might be different from the point-type of the geometry
+    \ingroup access
+ */
+template <typename G, typename R>
+inline void assign(G& geometry, R const& range)
+{
+    clear(geometry);
+    ggl::append(geometry, range, -1, 0);
+}
+
+
+/*!
+    \brief assign to a box inverse infinite
+    \details The assign_inverse function initialize a 2D or 3D box with large coordinates, the
+    min corner is very large, the max corner is very small. This is a convenient starting point to
+    collect the minimum bounding box of a geometry.
+    \ingroup access
+ */
+template <typename G>
+inline void assign_inverse(G& geometry)
+{
+    dispatch::assign_inverse
+        <
+            typename tag<G>::type,
+            G
+        >::apply(geometry);
+}
+
+/*!
+    \brief assign zero values to a box, point
+    \ingroup access
+    \details The assign_zero function initializes a 2D or 3D point or box with coordinates of zero
+    \tparam G the geometry type
+ */
+template <typename G>
+inline void assign_zero(G& geometry)
+{
+    dispatch::assign_zero
+        <
+            typename tag<G>::type,
+            G
+        >::apply(geometry);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_ASSIGN_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/buffer.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/buffer.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,153 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_BUFFER_HPP
+#define GGL_ALGORITHMS_BUFFER_HPP
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <ggl/arithmetic/arithmetic.hpp>
+#include <ggl/core/concepts/box_concept.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/util/assign_box_corner.hpp>
+
+// Buffer functions
+// Was before: "grow" but then only for box
+// Now "buffer", but still only implemented for a box...
+
+/*!
+\defgroup buffer buffer calculation
+\par Source description:
+- OGC: Returns a geometric object that represents all Points whose distance
+from this geometric object is less than or equal to distance. Calculations are in the spatial reference system of
+this geometric object. Because of the limitations of linear interpolation, there will often be some relatively
+small error in this distance, but it should be near the resolution of the coordinates used
+\see http://en.wikipedia.org/wiki/Buffer_(GIS)
+*/
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace buffer {
+
+template <typename BoxIn, typename BoxOut, typename T, std::size_t C, std::size_t D, std::size_t N>
+struct box_loop
+{
+    typedef typename coordinate_type<BoxOut>::type coordinate_type;
+
+    static inline void apply(BoxIn const& box_in, T const& distance, BoxOut& box_out)
+    {
+        set<C, D>(box_out, boost::numeric_cast<coordinate_type>(get<C, D>(box_in) + distance));
+        box_loop<BoxIn, BoxOut, T, C, D + 1, N>::apply(box_in, distance, box_out);
+    }
+};
+
+template <typename BoxIn, typename BoxOut, typename T, std::size_t C, std::size_t N>
+struct box_loop<BoxIn, BoxOut, T, C, N, N>
+{
+    static inline void apply(BoxIn const&, T const&, BoxOut&) {}
+};
+
+// Extends a box with the same amount in all directions
+template<typename BoxIn, typename BoxOut, typename T>
+inline void buffer_box(BoxIn const& box_in, T const& distance, BoxOut& box_out)
+{
+    assert_dimension_equal<BoxIn, BoxOut>();
+
+    static const std::size_t N = dimension<BoxIn>::value;
+
+    box_loop<BoxIn, BoxOut, T, min_corner, 0, N>::apply(box_in, -distance, box_out);
+    box_loop<BoxIn, BoxOut, T, max_corner, 0, N>::apply(box_in, +distance, box_out);
+}
+
+}} // namespace detail::buffer
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename TagIn, typename TagOut, typename Input, typename T, typename Output>
+struct buffer {};
+
+
+template <typename BoxIn, typename T, typename BoxOut>
+struct buffer<box_tag, box_tag, BoxIn, T, BoxOut>
+{
+    static inline void apply(BoxIn const& box_in, T const& distance,
+                T const& chord_length, BoxIn& box_out)
+    {
+        detail::buffer::buffer_box(box_in, distance, box_out);
+    }
+};
+
+// Many things to do. Point is easy, other geometries require self intersections
+// For point, note that it should output as a polygon (like the rest). Buffers
+// of a set of geometries are often lateron combined using a "dissolve" operation.
+// Two points close to each other get a combined kidney shaped buffer then.
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Calculate buffer (= new geometry) around specified distance of geometry
+    \ingroup buffer
+    \param geometry_in input geometry
+    \param distance the distance used in buffer
+    \param chord_length length of the chord's in the generated arcs around points or bends
+    \param geometry_out buffered geometry
+    \note Currently only implemented for box, the trivial case, but still useful
+    \par Use case:
+        BOX + distance -> BOX: it is allowed that "geometry_out" the same object as "geometry_in"
+ */
+template <typename Input, typename Output, typename T>
+inline void buffer(const Input& geometry_in, Output& geometry_out,
+            T const& distance, T const& chord_length = -1)
+{
+    dispatch::buffer
+        <
+            typename tag<Input>::type,
+            typename tag<Output>::type,
+            Input,
+            T,
+            Output
+        >::apply(geometry_in, distance, chord_length, geometry_out);
+}
+
+/*!
+    \brief Calculate and return buffer (= new geometry) around specified distance of geometry
+    \ingroup buffer
+    \param geometry input geometry
+    \param distance the distance used in buffer
+    \param chord_length length of the chord's in the generated arcs around points or bends
+    \return the buffered geometry
+    \note See also: buffer
+ */
+template <typename Output, typename Input, typename T>
+Output make_buffer(const Input& geometry, T const& distance, T const& chord_length = -1)
+{
+    Output geometry_out;
+
+    dispatch::buffer
+        <
+            typename tag<Input>::type,
+            typename tag<Output>::type,
+            Input,
+            T,
+            Output
+        >::apply(geometry, distance, chord_length, geometry_out);
+
+    return geometry_out;
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_BUFFER_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/centroid.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/centroid.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,277 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_CENTROID_HPP
+#define GGL_ALGORITHMS_CENTROID_HPP
+
+#include <cstddef>
+
+#include <boost/concept/requires.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/exception.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/strategies/strategies.hpp>
+#include <ggl/util/copy.hpp>
+#include <ggl/util/loop.hpp>
+
+/*!
+\defgroup centroid centroid calculation
+\par Source descriptions:
+- OGC description: The mathematical centroid for this Surface as a Point. The result is not guaranteed to be on this Surface.
+- From Wikipedia: Informally, it is the "average" of all points
+\see http://en.wikipedia.org/wiki/Centroid
+\note The "centroid" functions are taking a non const reference to the centroid. The "make_centroid" functions
+return the centroid, the type has to be specified.
+
+\note There are versions where the centroid calculation strategy can be specified
+\par Geometries:
+- RING: \image html centroid_ring.png
+- BOX: the centroid of a 2D or 3D box is the center of the box
+- CIRCLE: the centroid of a circle or a sphere is its center
+- POLYGON \image html centroid_polygon.png
+- POINT, LINESTRING, SEGMENT: trying to calculate the centroid will result in a compilation error
+*/
+
+namespace ggl
+{
+
+class centroid_exception : public ggl::exception
+{
+public:
+
+    centroid_exception()  {}
+
+    virtual char const* what() const throw()
+    {
+        return "centroid calculation exception";
+    }
+};
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace centroid {
+
+/*!
+    \brief Generic function which checks if enough points are present
+*/
+template<typename P, typename R>
+inline bool ring_ok(R const& ring, P& c)
+{
+    std::size_t const n = boost::size(ring);
+    if (n > 1)
+    {
+        return true;
+    }
+    else if (n <= 0)
+    {
+        throw centroid_exception();
+    }
+    else
+    {
+        // n == 1: Take over the first point in a "coordinate neutral way"
+        copy_coordinates(ring.front(), c);
+        return false;
+    }
+    return true;
+}
+
+/*!
+    \brief Calculate the centroid of a ring.
+*/
+template<typename Ring, typename Point, typename Strategy>
+struct centroid_ring
+{
+    static inline void apply(Ring const& ring, Point& c, Strategy const& strategy)
+    {
+        if (ring_ok(ring, c))
+        {
+            typename Strategy::state_type state;
+            loop(ring, strategy, state);
+            state.centroid(c);
+        }
+    }
+};
+
+
+/*!
+    \brief Centroid of a polygon.
+    \note Because outer ring is clockwise, inners are counter clockwise,
+    triangle approach is OK and works for polygons with rings.
+*/
+template<typename Polygon, typename Point, typename Strategy>
+struct centroid_polygon
+{
+    static inline void apply(Polygon const& poly, Point& c, Strategy const& strategy)
+    {
+        if (ring_ok(exterior_ring(poly), c))
+        {
+            typename Strategy::state_type state;
+
+            loop(exterior_ring(poly), strategy, state);
+
+            typedef typename boost::range_const_iterator
+                <
+                    typename interior_type<Polygon>::type
+                >::type iterator_type;
+
+            for (iterator_type it = boost::begin(interior_rings(poly));
+                 it != boost::end(interior_rings(poly));
+                 ++it)
+            {
+                loop(*it, strategy, state);
+            }
+            state.centroid(c);
+        }
+    }
+};
+
+/*!
+    \brief Calculate centroid (==center) of a box
+    \todo Implement strategy
+*/
+template<typename Box, typename Point, typename Strategy>
+struct centroid_box
+{
+    static inline void apply(Box const& box, Point& c, Strategy const&)
+    {
+        // TODO: adapt using strategies
+        assert_dimension<Box, 2>();
+        set<0>(c, (get<min_corner, 0>(box) + get<max_corner, 0>(box)) / 2);
+        set<1>(c, (get<min_corner, 1>(box) + get<max_corner, 1>(box)) / 2);
+    }
+};
+
+}} // namespace detail::centroid
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename Geometry, typename Point, typename Strategy>
+struct centroid {};
+
+template <typename Box, typename Point, typename Strategy>
+struct centroid<box_tag, Box, Point, Strategy>
+    : detail::centroid::centroid_box<Box, Point, Strategy>
+{};
+
+template <typename Ring, typename Point, typename Strategy>
+struct centroid<ring_tag, Ring, Point, Strategy>
+    : detail::centroid::centroid_ring<Ring, Point, Strategy>
+{};
+
+template <typename Polygon, typename Point, typename Strategy>
+struct centroid<polygon_tag, Polygon, Point, Strategy>
+    : detail::centroid::centroid_polygon<Polygon, Point, Strategy>
+
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Calculate centroid
+    \ingroup centroid
+    \details The function centroid calculates the centroid of a geometry using the default strategy.
+    A polygon should be closed and orientated clockwise, holes, if any, must be orientated
+    counter clockwise
+    \param geometry a geometry (e.g. closed ring or polygon)
+    \param c reference to point which will contain the centroid
+    \exception centroid_exception if calculation is not successful, e.g. because polygon didn't contain points
+    \par Example:
+    Example showing centroid calculation
+    \dontinclude doxygen_examples.cpp
+    \skip example_centroid_polygon
+    \line {
+    \until }
+ */
+template<typename G, typename P>
+inline void centroid(const G& geometry, P& c)
+{
+    typedef typename point_type<G>::type point_type;
+    typedef typename strategy_centroid
+        <
+            typename cs_tag<point_type>::type,
+            P,
+            point_type
+        >::type strategy_type;
+
+    dispatch::centroid
+        <
+            typename tag<G>::type,
+            G,
+            P,
+            strategy_type
+        >::apply(geometry, c, strategy_type());
+}
+
+/*!
+    \brief Calculate centroid using a specified strategy
+    \ingroup centroid
+    \param geometry the geometry to calculate centroid from
+    \param c reference to point which will contain the centroid
+    \param strategy Calculation strategy for centroid
+    \exception centroid_exception if calculation is not successful, e.g. because polygon didn't contain points
+ */
+template<typename G, typename P, typename S>
+inline void centroid(const G& geometry, P& c, S const& strategy)
+{
+    dispatch::centroid
+        <
+            typename tag<G>::type,
+            G,
+            P,
+            S
+        >::apply(geometry, c, strategy);
+}
+
+// Versions returning a centroid
+
+/*!
+    \brief Calculate and return centroid
+    \ingroup centroid
+    \param geometry the geometry to calculate centroid from
+    \return the centroid
+    \exception centroid_exception if calculation is not successful, e.g. because polygon didn't contain points
+ */
+template<typename P, typename G>
+inline P make_centroid(const G& geometry)
+{
+    P c;
+    centroid(geometry, c);
+    return c;
+}
+
+/*!
+    \brief Calculate and return centroid
+    \ingroup centroid
+    \param geometry the geometry to calculate centroid from
+    \param strategy Calculation strategy for centroid
+    \return the centroid
+    \exception centroid_exception if calculation is not successful, e.g. because polygon didn't contain points
+ */
+template<typename P, typename G, typename S>
+inline P make_centroid(const G& geometry, S const& strategy)
+{
+    P c;
+    centroid(geometry, c, strategy);
+    return c;
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_CENTROID_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/clear.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/clear.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,161 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_CLEAR_HPP
+#define GGL_ALGORITHMS_CLEAR_HPP
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+
+namespace ggl
+{
+
+// This traits is currently NOT defined in ../core/ but here, just because it default
+// does not have to be implemented
+namespace traits
+{
+
+/*!
+    \brief Traits class, optional, might be implemented to clear a geometry
+    \details If a geometry type should not use the std ".clear()" then it can specialize
+    the "use_std" traits class to false, it should then implement (a.o.) clear
+    \ingroup traits
+    \par Geometries:
+        - linestring
+        - linear_ring
+    \par Specializations should provide:
+        - apply
+ */
+template <typename G>
+struct clear
+{
+};
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace clear {
+
+template <typename G>
+struct use_std_clear
+{
+    static inline void apply(G& geometry)
+    {
+        geometry.clear();
+    }
+};
+
+template <typename G>
+struct use_traits_clear
+{
+    static inline void apply(G& geometry)
+    {
+        traits::clear<G>::apply(geometry);
+    }
+};
+
+template <typename P>
+struct polygon_clear
+{
+    static inline void apply(P& polygon)
+    {
+        interior_rings(polygon).clear();
+        exterior_ring(polygon).clear();
+    }
+};
+
+template <typename G>
+struct no_action
+{
+    static inline void apply(G& geometry)
+    {
+    }
+};
+
+}} // namespace detail::clear
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, bool Std, typename G>
+struct clear
+{};
+
+// True (default for all geometry types, unless otherwise implemented in traits)
+// uses std::clear
+template <typename Tag, typename G>
+struct clear<Tag, true, G>
+    : detail::clear::use_std_clear<G>
+{};
+
+// If any geometry specializes use_std<G> to false, specialize to use the traits clear.
+template <typename Tag, typename G>
+struct clear<Tag, false, G>
+    : detail::clear::use_traits_clear<G>
+{};
+
+// Point/box/nsphere/segment do not have clear. So specialize to do nothing.
+template <typename G>
+struct clear<point_tag, true, G>
+    : detail::clear::no_action<G>
+{};
+
+template <typename G>
+struct clear<box_tag, true, G>
+    : detail::clear::no_action<G>
+{};
+
+template <typename G>
+struct clear<segment_tag, true, G>
+    : detail::clear::no_action<G>
+{};
+
+
+template <typename G>
+struct clear<nsphere_tag, true, G>
+    : detail::clear::no_action<G>
+{};
+
+
+// Polygon can (indirectly) use std for clear
+template <typename P>
+struct clear<polygon_tag, true, P>
+    : detail::clear::polygon_clear<P>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Clears a linestring, linear ring or polygon (exterior+interiors) or multi*
+    \details Generic function to clear a geometry
+    \ingroup access
+    \note points and boxes cannot be cleared, instead they can be set to zero by "assign_zero"
+*/
+template <typename G>
+inline void clear(G& geometry)
+{
+    typedef typename boost::remove_const<G>::type ncg_type;
+
+    dispatch::clear
+        <
+        typename tag<G>::type,
+        traits::use_std<ncg_type>::value,
+        ncg_type
+        >::apply(geometry);
+}
+
+}  // namespace ggl
+
+#endif // GGL_ALGORITHMS_CLEAR_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/combine.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/combine.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,189 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_COMBINE_HPP
+#define GGL_ALGORITHMS_COMBINE_HPP
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <ggl/arithmetic/arithmetic.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/concepts/box_concept.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/util/assign_box_corner.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+
+/*!
+\defgroup combine combine: add a geometry to a bounding box
+\par Geometries:
+- BOX + BOX -> BOX: the box will be combined with the other box \image html combine_box_box.png
+- BOX + POINT -> BOX: the box will combined with the point  \image html combine_box_point.png
+\note Previously called "grow"
+*/
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace combine {
+
+template
+<
+    typename Box, typename Point,
+    std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_loop
+{
+    typedef typename coordinate_type<Point>::type coordinate_type;
+
+    static inline void apply(Box& box, Point const& source)
+    {
+        coordinate_type const coord = get<Dimension>(source);
+
+        if (coord < get<min_corner, Dimension>(box))
+        {
+            set<min_corner, Dimension>(box, coord );
+        }
+
+        if (coord > get<max_corner, Dimension>(box))
+        {
+            set<max_corner, Dimension>(box, coord);
+        }
+
+        point_loop<Box, Point, Dimension + 1, DimensionCount>::apply(box, source);
+    }
+};
+
+
+template
+<
+    typename Box, typename Point,
+    std::size_t DimensionCount
+>
+struct point_loop<Box, Point, DimensionCount, DimensionCount>
+{
+    static inline void apply(Box&, Point const&) {}
+};
+
+
+template
+<
+    typename BoxIn, typename BoxOut,
+    std::size_t Corner,
+    std::size_t Dimension, std::size_t DimensionCount
+>
+struct box_loop
+{
+    typedef typename select_coordinate_type<BoxIn, BoxOut>::type coordinate_type;
+
+    static inline void apply(BoxIn& box, BoxOut const& source)
+    {
+        coordinate_type const coord = get<Corner, Dimension>(source);
+
+        if (coord < get<min_corner, Dimension>(box))
+        {
+            set<min_corner, Dimension>(box, coord);
+        }
+
+        if (coord > get<max_corner, Dimension>(box))
+        {
+            set<max_corner, Dimension>(box, coord);
+        }
+
+        box_loop
+            <
+                BoxIn, BoxOut, Corner, Dimension + 1, DimensionCount
+            >::apply(box, source);
+    }
+};
+
+
+template
+<
+    typename BoxIn, typename BoxOut,
+    std::size_t Corner, std::size_t DimensionCount
+>
+struct box_loop<BoxIn, BoxOut, Corner, DimensionCount, DimensionCount>
+{
+    static inline void apply(BoxIn&, BoxOut const&) {}
+};
+
+
+// Changes a box b such that it also contains point p
+template<typename Box, typename Point>
+struct combine_box_with_point
+    : point_loop<Box, Point, 0, dimension<Point>::type::value>
+{};
+
+
+// Changes a box such that the other box is also contained by the box
+template<typename BoxOut, typename BoxIn>
+struct combine_box_with_box
+{
+    static inline void apply(BoxOut& b, BoxIn const& other)
+    {
+        box_loop<BoxOut, BoxIn, min_corner, 0,
+                    dimension<BoxIn>::type::value>::apply(b, other);
+        box_loop<BoxOut, BoxIn, max_corner, 0,
+                    dimension<BoxIn>::type::value>::apply(b, other);
+    }
+};
+
+}} // namespace detail::combine
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename BoxOut, typename Geometry>
+struct combine
+{};
+
+
+// Box + point -> new box containing also point
+template <typename BoxOut, typename Point>
+struct combine<point_tag, BoxOut, Point>
+    : detail::combine::combine_box_with_point<BoxOut, Point>
+{};
+
+
+// Box + box -> new box containing two input boxes
+template <typename BoxOut, typename BoxIn>
+struct combine<box_tag, BoxOut, BoxIn>
+    : detail::combine::combine_box_with_box<BoxOut, BoxIn>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Combines a box with another geometry (box, point)
+    \ingroup combine
+    \tparam Box type of the box
+    \tparam Geometry of second geometry, to be combined with the box
+    \param box box to combine another geometry with, might be changed
+    \param geometry other geometry
+ */
+template <typename Box, typename Geometry>
+inline void combine(Box& box, Geometry const& geometry)
+{
+    assert_dimension_equal<Box, Geometry>();
+    dispatch::combine
+        <
+            typename tag<Geometry>::type,
+            Box, Geometry
+        >::apply(box, geometry);
+}
+
+} // namespace ggl
+
+#endif // GGL_COMBINE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/convert.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/convert.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,161 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_CONVERT_HPP
+#define GGL_ALGORITHMS_CONVERT_HPP
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/append.hpp>
+#include <ggl/algorithms/for_each.hpp>
+#include <ggl/core/cs.hpp>
+#include <ggl/geometries/segment.hpp>
+#include <ggl/strategies/strategies.hpp>
+
+/*!
+\defgroup convert convert geometries from one type to another
+\details Convert from one geometry type to another type, for example from BOX to POLYGON
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace convert {
+
+template <typename P, typename B, std::size_t C, std::size_t D, std::size_t N>
+struct point_to_box
+{
+    static inline void apply(P const& point, B& box)
+    {
+        typedef typename coordinate_type<B>::type coordinate_type;
+
+        set<C, D>(box, boost::numeric_cast<coordinate_type>(get<D>(point)));
+        point_to_box<P, B, C, D + 1, N>::apply(point, box);
+    }
+};
+
+template <typename P, typename B, std::size_t C, std::size_t N>
+struct point_to_box<P, B, C, N, N>
+{
+    static inline void apply(P const& point, B& box)
+    {}
+};
+
+}} // namespace detail::convert
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename T1, typename T2, typename G1, typename G2>
+struct convert
+{
+};
+
+template <typename T, typename G1, typename G2>
+struct convert<T, T, G1, G2>
+{
+    // Same geometry type -> copy coordinates from G1 to G2
+};
+
+template <typename T, typename G>
+struct convert<T, T, G, G>
+{
+    // Same geometry -> can be copied
+};
+
+
+// Partial specializations
+template <typename B, typename R>
+struct convert<box_tag, ring_tag, B, R>
+{
+    static inline void apply(B const& box, R& ring)
+    {
+        // go from box to ring -> add coordinates in correct order
+        // only valid for 2D
+        assert_dimension<B, 2>();
+
+        ring.clear();
+        typename point_type<B>::type point;
+
+        ggl::assign(point, get<min_corner, 0>(box), get<min_corner, 1>(box));
+        ggl::append(ring, point);
+
+        ggl::assign(point, get<min_corner, 0>(box), get<max_corner, 1>(box));
+        ggl::append(ring, point);
+
+        ggl::assign(point, get<max_corner, 0>(box), get<max_corner, 1>(box));
+        ggl::append(ring, point);
+
+        ggl::assign(point, get<max_corner, 0>(box), get<min_corner, 1>(box));
+        ggl::append(ring, point);
+
+        ggl::assign(point, get<min_corner, 0>(box), get<min_corner, 1>(box));
+        ggl::append(ring, point);
+    }
+};
+
+template <typename B, typename P>
+struct convert<box_tag, polygon_tag, B, P>
+{
+    static inline void apply(B const& box, P& polygon)
+    {
+        typedef typename ring_type<P>::type ring_type;
+
+        convert<box_tag, ring_tag, B, ring_type>::apply(box, exterior_ring(polygon));
+    }
+};
+
+template <typename P, typename B>
+struct convert<point_tag, box_tag, P, B>
+{
+    static inline void apply(P const& point, B& box)
+    {
+        // go from point to box -> box with volume of zero, 2D or 3D
+        static const std::size_t N = dimension<P>::value;
+
+        detail::convert::point_to_box<P, B, min_corner, 0, N>::apply(point, box);
+        detail::convert::point_to_box<P, B, max_corner, 0, N>::apply(point, box);
+    }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+/*!
+    \brief Converts one geometry to another geometry
+    \details The convert algorithm converts one geometry, e.g. a BOX, to another geometry, e.g. a RING. This only
+    if it is possible and applicable.
+    \ingroup convert
+    \tparam G1 first geometry type
+    \tparam G2 second geometry type
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+ */
+template <typename G1, typename G2>
+inline void convert(G1 const& geometry1, G2& geometry2)
+{
+    dispatch::convert
+        <
+            typename tag<G1>::type,
+            typename tag<G2>::type,
+            G1,
+            G2
+        >::apply(geometry1, geometry2);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_CONVERT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/convex_hull.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/convex_hull.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,127 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_CONVEX_HULL_HPP
+#define GGL_ALGORITHMS_CONVEX_HULL_HPP
+
+
+#include <boost/concept/requires.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/is_multi.hpp>
+
+#include <ggl/core/concepts/point_concept.hpp>
+
+
+#include <ggl/strategies/strategies.hpp>
+#include <ggl/util/as_range.hpp>
+
+
+/*!
+\defgroup convex_hull convex hull calculation
+\par Source descriptions:
+- OGC description: Returns a geometric object that represents the convex hull of this geometric
+object. Convex hulls, being dependent on straight lines, can be accurately represented in linear interpolations
+for any geometry restricted to linear interpolations.
+\see http://en.wikipedia.org/wiki/Convex_hull
+
+\par Performance
+2776 counties of US are "hulled" in 0.52 seconds (other libraries: 2.8 seconds, 2.4 seconds, 3.4 seconds, 1.1 seconds)
+
+\note The convex hull is always a ring, holes are not possible. Therefore it is modelled as an output iterator.
+This gives the most flexibility, the user can decide what to do with it.
+\par Geometries:
+In the images below the convex hull is painted in red.
+- POINT: will not compile
+- POLYGON: will deliver a polygon without holes \image html convexhull_polygon_polygon.png
+*/
+namespace ggl {
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace convex_hull {
+
+template <typename Geometry, typename OutputIterator>
+struct hull
+{
+    static inline OutputIterator apply(Geometry const& geometry,
+            OutputIterator out)
+    {
+        typedef typename point_type<Geometry>::type point_type;
+
+        typedef typename strategy_convex_hull
+            <
+                typename cs_tag<point_type>::type,
+                point_type
+            >::type strategy_type;
+
+        strategy_type s(as_range<typename as_range_type<Geometry>::type>(geometry));
+        s.get(out);
+        return out;
+    }
+};
+
+
+}} // namespace detail::convex_hull
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename GeometryTag,
+    bool IsMulti,
+    typename Geometry,
+    typename OutputIterator
+ >
+struct convex_hull {};
+
+template <typename Linestring, typename OutputIterator>
+struct convex_hull<linestring_tag, false, Linestring, OutputIterator>
+    : detail::convex_hull::hull<Linestring, OutputIterator> 
+{};
+
+template <typename Ring, typename OutputIterator>
+struct convex_hull<ring_tag, false, Ring, OutputIterator>
+    : detail::convex_hull::hull<Ring, OutputIterator> 
+{};
+
+template <typename Polygon, typename OutputIterator>
+struct convex_hull<polygon_tag, false, Polygon, OutputIterator>
+    : detail::convex_hull::hull<Polygon, OutputIterator> 
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+/*!
+    \brief Calculate the convex hull of a geometry
+    \ingroup convex_hull
+    \param geometry the geometry to calculate convex hull from
+    \param out an output iterator outputing points of the convex hull
+    \return the output iterator
+ */
+template<typename Geometry, typename OutputIterator>
+inline OutputIterator convex_hull(Geometry const& geometry, OutputIterator out)
+{
+    typedef typename boost::remove_const<Geometry>::type ncg_type;
+
+    return dispatch::convex_hull
+        <
+            typename tag<ncg_type>::type,
+            is_multi<ncg_type>::type::value,
+            Geometry,
+            OutputIterator
+        >::apply(geometry, out);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_CONVEX_HULL_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/correct.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/correct.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,161 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_CORRECT_HPP
+#define GGL_ALGORITHMS_CORRECT_HPP
+
+#include <algorithm>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+
+#include <ggl/core/concepts/point_concept.hpp>
+
+#include <ggl/algorithms/area.hpp>
+#include <ggl/algorithms/disjoint.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace correct {
+
+// correct an box: make min/max are correct
+template <typename B>
+inline void correct_box(B& b)
+{
+    // Currently only for Cartesian coordinates
+    // TODO: adapt using strategies
+    // TODO: adapt using traits
+    typedef typename coordinate_type<B>::type coordinate_type;
+
+    if (get<min_corner, 0>(b) > get<max_corner, 0>(b))
+    {
+        coordinate_type max_value = get<min_corner, 0>(b);
+        coordinate_type min_value = get<max_corner, 0>(b);
+        set<min_corner, 0>(b, min_value);
+        set<max_corner, 0>(b, max_value);
+    }
+
+    if (get<min_corner, 1>(b) > get<max_corner, 1>(b))
+    {
+        coordinate_type max_value = get<min_corner, 1>(b);
+        coordinate_type min_value = get<max_corner, 1>(b);
+        set<min_corner, 1>(b, min_value);
+        set<max_corner, 1>(b, max_value);
+    }
+}
+
+// close a linear_ring, if not closed
+template <typename R>
+inline void ensure_closed_ring(R& r)
+{
+    if (boost::size(r) > 2)
+    {
+        // check if closed, if not, close it
+        if (ggl::disjoint(r.front(), r.back()))
+        {
+            r.push_back(r.front());
+        }
+    }
+}
+
+// correct a polygon: normalizes all rings, sets outer linear_ring clockwise, sets all
+// inner rings counter clockwise
+template <typename Y>
+inline void correct_polygon(Y& poly)
+{
+    typename ring_type<Y>::type& outer = exterior_ring(poly);
+    ensure_closed_ring(outer);
+
+    typedef typename point_type<Y>::type point_type;
+    typedef typename ring_type<Y>::type ring_type;
+    typedef typename strategy_area
+        <
+            typename cs_tag<point_type>::type,
+            point_type
+        >::type strategy_type;
+
+    strategy_type strategy;
+
+    if (detail::area::ring_area<ring_type, strategy_type>::apply(outer, strategy) < 0)
+    {
+        std::reverse(boost::begin(outer), boost::end(outer));
+    }
+
+    typedef typename boost::range_iterator
+        <
+            typename interior_type<Y>::type
+        >::type iterator_type;
+
+    for (iterator_type it = boost::begin(interior_rings(poly));
+         it != boost::end(interior_rings(poly)); ++it)
+    {
+        ensure_closed_ring(*it);
+        if (detail::area::ring_area<ring_type, strategy_type>::apply(*it, strategy) > 0)
+        {
+            std::reverse(boost::begin(*it), boost::end(*it));
+        }
+    }
+}
+
+}} // namespace detail::correct
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename G>
+struct correct {};
+
+template <typename B>
+struct correct<box_tag, B>
+{
+    static inline void apply(B& box)
+    {
+        detail::correct::correct_box(box);
+    }
+};
+
+template <typename R>
+struct correct<ring_tag, R>
+{
+    static inline void apply(R& ring)
+    {
+        detail::correct::ensure_closed_ring(ring);
+    }
+};
+
+template <typename P>
+struct correct<polygon_tag, P>
+{
+    static inline void apply(P& poly)
+    {
+        detail::correct::correct_polygon(poly);
+    }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+template <typename G>
+inline void correct(G& geometry)
+{
+    dispatch::correct<typename tag<G>::type, G>::apply(geometry);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_CORRECT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/detail/calculate_null.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/detail/calculate_null.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,33 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_DETAIL_CALCULATE_NULL_HPP
+#define GGL_ALGORITHMS_DETAIL_CALCULATE_NULL_HPP
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template<typename ReturnValue, typename Geometry, typename Strategy>
+struct calculate_null
+{
+    static inline ReturnValue apply(Geometry const& , Strategy const&)
+    {
+        return ReturnValue();
+    }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_DETAIL_CALCULATE_NULL_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/detail/not.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/detail/not.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,45 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_DETAIL_NOT_HPP
+#define GGL_ALGORITHMS_DETAIL_NOT_HPP
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+
+/*!
+    \brief Structure negating the result of specified policy
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \tparam Policy
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \return Negation of the result of the policy
+ */
+template <typename Geometry1, typename Geometry2, typename Policy>
+struct not_
+{
+    static inline bool apply(Geometry1 const &geometry1, Geometry2 const& geometry2)
+    {
+        return ! Policy::apply(geometry1, geometry2);
+    }
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_DETAIL_NOT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/disjoint.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/disjoint.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,221 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_DISJOINT_HPP
+#define GGL_ALGORITHMS_DISJOINT_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/static_assert.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/is_multi.hpp>
+#include <ggl/core/reverse_dispatch.hpp>
+#include <ggl/util/math.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace disjoint {
+
+template <typename P1, typename P2, std::size_t D, std::size_t N>
+struct point_point
+{
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+    static inline bool apply(P1 const& p1, P2 const& p2)
+    {
+        if (! math::equals(get<D>(p1), get<D>(p2)))
+        {
+            return true;
+        }
+        return point_point<P1, P2, D + 1, N>::apply(p1, p2);
+    }
+};
+
+template <typename P1, typename P2, std::size_t N>
+struct point_point<P1, P2, N, N>
+{
+    static inline bool apply(P1 const& , P2 const& )
+    {
+        return false;
+    }
+};
+
+
+template <typename P, typename B, std::size_t D, std::size_t N>
+struct point_box
+{
+    static inline bool apply(P const& point, B const& box)
+    {
+        if (get<D>(point) < get<min_corner, D>(box)
+            || get<D>(point) > get<max_corner, D>(box))
+        {
+            return true;
+        }
+        return point_box<P, B, D + 1, N>::apply(point, box);
+    }
+};
+
+template <typename P, typename B, std::size_t N>
+struct point_box<P, B, N, N>
+{
+    static inline bool apply(P const& , B const& )
+    {
+        return false;
+    }
+};
+
+
+template <typename B1, typename B2, std::size_t D, std::size_t N>
+struct box_box
+{
+    static inline bool apply(B1 const& box1, B2 const& box2)
+    {
+        if (get<max_corner, D>(box1) < get<min_corner, D>(box2))
+        {
+            return true;
+        }
+        if (get<min_corner, D>(box1) > get<max_corner, D>(box2))
+        {
+            return true;
+        }
+        return box_box<B1, B2, D + 1, N>::apply(box1, box2);
+    }
+};
+
+template <typename B1, typename B2, std::size_t N>
+struct box_box<B1, B2, N, N>
+{
+    static inline bool apply(B1 const& , B2 const& )
+    {
+        return false;
+    }
+};
+
+
+
+}} // namespace detail::disjoint
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename GeometryTag1, typename GeometryTag2,
+    typename G1, typename G2,
+    bool IsMulti1, bool IsMulti2,
+    std::size_t DimensionCount
+>
+struct disjoint
+{
+};
+
+template <typename P1, typename P2, std::size_t DimensionCount>
+struct disjoint<point_tag, point_tag, P1, P2, false, false, DimensionCount>
+    : detail::disjoint::point_point<P1, P2, 0, DimensionCount>
+{
+};
+
+template <typename B1, typename B2, std::size_t DimensionCount>
+struct disjoint<box_tag, box_tag, B1, B2, false, false, DimensionCount>
+    : detail::disjoint::box_box<B1, B2, 0, DimensionCount>
+{
+};
+
+template <typename P, typename B, std::size_t DimensionCount>
+struct disjoint<point_tag, box_tag, P, B, false, false, DimensionCount>
+    : detail::disjoint::point_box<P, B, 0, DimensionCount>
+{
+};
+
+
+template
+<
+    typename GeometryTag1, typename GeometryTag2,
+    typename G1, typename G2,
+    bool IsMulti1, bool IsMulti2,
+    std::size_t DimensionCount
+>
+struct disjoint_reversed
+{
+    static inline bool apply(G1 const& g1, G2 const& g2)
+    {
+        return disjoint
+            <
+                GeometryTag2, GeometryTag1,
+                G2, G1,
+                IsMulti2, IsMulti1,
+                DimensionCount
+            >::apply(g2, g1);
+    }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+/*!
+    \brief Calculate if two geometries are disjoint
+    \ingroup boolean_relations
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \return true if disjoint, else false
+ */
+template <typename Geometry1, typename Geometry2>
+inline bool disjoint(const Geometry1& geometry1,
+            const Geometry2& geometry2)
+{
+    assert_dimension_equal<Geometry1, Geometry2>();
+
+    typedef typename boost::remove_const<Geometry1>::type ncg1_type;
+    typedef typename boost::remove_const<Geometry2>::type ncg2_type;
+
+    return boost::mpl::if_c
+        <
+            reverse_dispatch<Geometry1, Geometry2>::type::value,
+            dispatch::disjoint_reversed
+            <
+                typename tag<ncg1_type>::type,
+                typename tag<ncg2_type>::type,
+                ncg1_type,
+                ncg2_type,
+                is_multi<ncg1_type>::type::value,
+                is_multi<ncg2_type>::type::value,
+                dimension<ncg1_type>::type::value
+            >,
+            dispatch::disjoint
+            <
+                typename tag<ncg1_type>::type,
+                typename tag<ncg2_type>::type,
+                ncg1_type,
+                ncg2_type,
+                is_multi<ncg1_type>::type::value,
+                is_multi<ncg2_type>::type::value,
+                dimension<ncg1_type>::type::value
+            >
+        >::type::apply(geometry1, geometry2);
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_DISJOINT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/distance.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/distance.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,360 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_DISTANCE_HPP
+#define GGL_ALGORITHMS_DISTANCE_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/static_assert.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/is_multi.hpp>
+#include <ggl/core/reverse_dispatch.hpp>
+#include <ggl/geometries/segment.hpp>
+#include <ggl/strategies/distance_result.hpp>
+#include <ggl/strategies/strategies.hpp>
+
+/*!
+\defgroup distance distance calculation
+The distance algorithm returns the distance between two geometries.
+\par Coordinate systems and strategies:
+With help of strategies the distance function returns the appropriate distance.
+If the input is in cartesian coordinates, the Euclidian distance (Pythagoras) is calculated.
+If the input is in spherical coordinates (either degree or radian), the distance over the sphere is returned.
+If the input is in geographic coordinates, distance is calculated over the globe and returned in meters.
+
+\par Distance result:
+Depending on calculation type the distance result is either a structure, convertable
+to a double, or a double value. In case of Pythagoras it makes sense to not draw the square root in the
+strategy itself. Taking a square root is relative expensive and is not necessary when comparing distances.
+
+\par Geometries:
+Currently implemented, for both cartesian and spherical/geographic:
+- POINT - POINT
+- POINT - SEGMENT and v.v.
+- POINT - LINESTRING and v.v.
+
+Not yet implemented:
+- POINT - RING etc, note that it will return a zero if the point is anywhere within the ring
+
+\par Example:
+Example showing distance calculation of two points, in xy and in latlong coordinates
+\dontinclude doxygen_examples.cpp
+\skip example_distance_point_point
+\line {
+\until }
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace distance {
+
+template <typename P1, typename P2, typename Strategy>
+struct point_to_point
+{
+    static inline typename Strategy::return_type apply(P1 const& p1,
+                P2 const& p2, Strategy const& strategy)
+    {
+        return strategy(p1, p2);
+    }
+};
+
+
+template<typename Point, typename Segment, typename Strategy>
+struct point_to_segment
+{
+    static inline typename Strategy::return_type apply(Point const& point,
+                Segment const& segment, Strategy const& strategy)
+    {
+        typename strategy_distance_segment
+            <
+            typename cs_tag<Point>::type,
+            typename cs_tag<Segment>::type,
+            Point,
+            Segment
+            >::type segment_strategy;
+
+        return segment_strategy(point, segment);
+    }
+};
+
+
+template<typename P, typename L, typename PPStrategy, typename PSStrategy>
+struct point_to_linestring
+{
+    typedef typename PPStrategy::return_type return_type;
+
+    static inline return_type apply(P const& point, L const& linestring,
+            PPStrategy const& pp_strategy, PSStrategy const& ps_strategy)
+    {
+        typedef segment<const typename point_type<L>::type> segment_type;
+
+        if (boost::begin(linestring) == boost::end(linestring))
+        {
+            return return_type(0);
+        }
+
+        // line of one point: return point square_distance
+        typedef typename boost::range_const_iterator<L>::type iterator_type;
+        iterator_type it = boost::begin(linestring);
+        iterator_type prev = it++;
+        if (it == boost::end(linestring))
+        {
+            return pp_strategy(point, *boost::begin(linestring));
+        }
+
+
+        // start with first segment distance
+        return_type d = ps_strategy(point, segment_type(*prev, *it));
+
+        // check if other segments are closer
+        prev = it++;
+        while(it != boost::end(linestring))
+        {
+            return_type ds = ps_strategy(point, segment_type(*prev, *it));
+            if (ggl::close_to_zero(ds))
+            {
+                return return_type(0);
+            }
+            else if (ds < d)
+            {
+                d = ds;
+            }
+            prev = it++;
+        }
+
+        return d;
+    }
+};
+
+
+
+}} // namespace detail::distance
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename GeometryTag1, typename GeometryTag2,
+    typename G1, typename G2,
+    typename StrategyTag, typename Strategy,
+    bool IsMulti1, bool IsMulti2
+>
+struct distance
+{};
+
+
+template <typename P1, typename P2, typename Strategy>
+struct distance
+<
+    point_tag, point_tag,
+    P1, P2,
+    strategy_tag_distance_point_point, Strategy,
+    false, false
+> : detail::distance::point_to_point<P1, P2, Strategy>
+{};
+
+/// Point-line version 1, where point-point strategy is specified
+template <typename Point, typename Linestring, typename Strategy>
+struct distance
+<
+    point_tag, linestring_tag,
+    Point, Linestring,
+    strategy_tag_distance_point_point, Strategy,
+    false, false
+>
+{
+
+    static inline typename Strategy::return_type apply(Point const& point,
+            Linestring const& linestring,
+            Strategy const& strategy)
+    {
+        typedef segment<const typename point_type<Linestring>::type> segment_type;
+        typedef typename ggl::strategy_distance_segment
+                    <
+                            typename cs_tag<Point>::type,
+                            typename cs_tag<segment_type>::type,
+                            Point,
+                            segment_type
+                    >::type ps_strategy_type;
+
+        return detail::distance::point_to_linestring
+            <
+                Point, Linestring, Strategy, ps_strategy_type
+            >::apply(point, linestring, strategy, ps_strategy_type());
+    }
+};
+
+
+/// Point-line version 2, where point-segment strategy is specified
+template <typename Point, typename Linestring, typename Strategy>
+struct distance
+<
+    point_tag, linestring_tag,
+    Point, Linestring,
+    strategy_tag_distance_point_segment, Strategy,
+    false, false
+>
+{
+    static inline typename Strategy::return_type apply(Point const& point,
+            Linestring const& linestring,
+            Strategy const& strategy)
+    {
+        typedef typename Strategy::point_strategy_type pp_strategy_type;
+        return detail::distance::point_to_linestring
+            <
+                Point, Linestring, pp_strategy_type, Strategy
+            >::apply(point, linestring, pp_strategy_type(), strategy);
+    }
+};
+
+
+template <typename Point, typename Segment, typename Strategy>
+struct distance
+<
+    point_tag, segment_tag,
+    Point, Segment,
+    strategy_tag_distance_point_point, Strategy,
+    false, false
+> : detail::distance::point_to_segment<Point, Segment, Strategy>
+{};
+
+
+// Strictly spoken this might be in namespace <impl> again
+template
+<
+    typename GeometryTag1, typename GeometryTag2,
+    typename G1, typename G2,
+    typename StrategyTag, typename Strategy,
+    bool IsMulti1, bool IsMulti2
+>
+struct distance_reversed
+{
+    static inline typename Strategy::return_type apply(G1 const& g1,
+                G2 const& g2, Strategy const& strategy)
+    {
+        return distance
+            <
+                GeometryTag2, GeometryTag1,
+                G2, G1,
+                StrategyTag, Strategy,
+                IsMulti2, IsMulti1
+            >::apply(g2, g1, strategy);
+    }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+/*!
+    \brief Calculate distance between two geometries with a specified strategy
+    \ingroup distance
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \tparam S point-point-distance strategy type
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \param strategy strategy to calculate distance between two points
+    \return the distance (either a double or a distance_result, (convertable to double))
+    \note The strategy can be a point-point strategy. In case of distance point-line/point-polygon
+        it may also be a point-segment strategy.
+    \par Example:
+    Example showing distance calculation of two lat long points, using the accurate Vincenty approximation
+    \dontinclude doxygen_examples.cpp
+    \skip example_distance_point_point_strategy
+    \line {
+    \until }
+ */
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline typename Strategy::return_type distance(Geometry1 const& geometry1,
+            Geometry2 const& geometry2, Strategy const& strategy)
+{
+    typedef typename boost::remove_const<Geometry1>::type ncg1_type;
+    typedef typename boost::remove_const<Geometry2>::type ncg2_type;
+
+    return boost::mpl::if_c
+        <
+            ggl::reverse_dispatch<Geometry1, Geometry2>::type::value,
+            dispatch::distance_reversed
+                <
+                    typename tag<ncg1_type>::type,
+                    typename tag<ncg2_type>::type,
+                    ncg1_type,
+                    ncg2_type,
+                    typename strategy_tag<Strategy>::type,
+                    Strategy,
+                    is_multi<ncg1_type>::value,
+                    is_multi<ncg2_type>::value
+                >,
+                dispatch::distance
+                <
+                    typename tag<ncg1_type>::type,
+                    typename tag<ncg2_type>::type,
+                    ncg1_type,
+                    ncg2_type,
+                    typename strategy_tag<Strategy>::type,
+                    Strategy,
+                    is_multi<ncg1_type>::value,
+                    is_multi<ncg2_type>::value
+                >
+        >::type::apply(geometry1, geometry2, strategy);
+}
+
+
+/*!
+    \brief Calculate distance between two geometries
+    \ingroup distance
+    \details The default strategy is used, belonging to the corresponding coordinate system of the geometries
+    \tparam G1 first geometry type
+    \tparam G2 second geometry type
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \return the distance (either a double or a distance result, convertable to double)
+ */
+template <typename Geometry1, typename Geometry2>
+inline typename distance_result<Geometry1, Geometry2>::type distance(
+                Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+    typedef typename point_type<Geometry1>::type point1_type;
+    typedef typename point_type<Geometry2>::type point2_type;
+
+    // Define a point-point-distance-strategy
+    // for either the normal case, either the reversed case
+    typedef typename boost::mpl::if_c
+        <
+            ggl::reverse_dispatch<Geometry1, Geometry2>::type::value,
+            typename strategy_distance
+                <
+                    typename cs_tag<point2_type>::type,
+                    typename cs_tag<point1_type>::type,
+                    point2_type,
+                    point1_type
+                >::type,
+            typename strategy_distance
+                <
+                    typename cs_tag<point1_type>::type,
+                    typename cs_tag<point2_type>::type,
+                    point1_type,
+                    point2_type
+                >::type
+        >::type strategy;
+
+    return distance(geometry1, geometry2, strategy());
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_DISTANCE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/envelope.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/envelope.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,329 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_ENVELOPE_HPP
+#define GGL_ALGORITHMS_ENVELOPE_HPP
+
+#include <boost/concept/requires.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <ggl/algorithms/combine.hpp>
+#include <ggl/algorithms/convert.hpp>
+#include <ggl/core/cs.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/concepts/box_concept.hpp>
+#include <ggl/core/concepts/linestring_concept.hpp>
+#include <ggl/core/concepts/nsphere_concept.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/core/concepts/polygon_concept.hpp>
+#include <ggl/core/concepts/ring_concept.hpp>
+#include <ggl/strategies/strategies.hpp>
+
+/*!
+\defgroup envelope envelope calculation
+\par Source descriptions:
+- OGC: Envelope (): Geometry - The minimum bounding rectangle (MBR) for this Geometry,
+returned as a Geometry. The polygon is defined by the corner points of the bounding
+box [(MINX, MINY), (MAXX, MINY), (MAXX, MAXY), (MINX, MAXY), (MINX, MINY)].
+
+\note Implemented in the Generic Geometry Library: The minimum bounding box, always as a box, having min <= max
+
+The envelope algorithm calculates the bounding box, or envelope, of a geometry. There are two versions:
+- envelope, taking a reference to a box as second parameter
+- make_envelope, returning a newly constructed box (type as a template parameter in the function call)
+- either of them has an optional strategy
+
+\par Geometries:
+- POINT: a box with zero area, the maximum and the minimum point of the box are
+set to the point itself.
+- LINESTRING, RING or RANGE is the smallest box that contains all points of the specified
+point sequence.
+If the linestring is empty, the envelope is the inverse infinite box, that is, the minimum point is very
+large (max infinite) and the maximum point is very small (min infinite).
+- POLYGON, the envelope of the outer ring
+\image html envelope_polygon.png
+
+\par Example:
+Example showing envelope calculation
+\dontinclude doxygen_examples.cpp
+\skip example_envelope_linestring
+\line {
+\until }
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope {
+
+/// Calculate envelope of an n-sphere, circle or sphere (currently only for Cartesian 2D points)
+template<typename B, typename S, typename Strategy>
+struct envelope_nsphere
+{
+    static inline void apply(S const& s, B& mbr, Strategy const&)
+    {
+        assert_dimension<S, 2>();
+        assert_dimension<B, 2>();
+
+        typename radius_type<S>::type r = get_radius<0>(s);
+        set<min_corner, 0>(mbr, get<0>(s) - r);
+        set<min_corner, 1>(mbr, get<1>(s) - r);
+        set<max_corner, 0>(mbr, get<0>(s) + r);
+        set<max_corner, 1>(mbr, get<1>(s) + r);
+    }
+};
+
+
+/// Calculate envelope of an 2D or 3D point
+template<typename P, typename B, typename Strategy>
+struct envelope_point
+{
+    static inline void apply(P const& p, B& mbr, Strategy const&)
+    {
+        // Envelope of a point is an empty box, a box with zero volume, located at the point.
+        // We just use the convert algorithm here
+        ggl::convert(p, mbr);
+    }
+};
+
+
+/// Calculate envelope of an 2D or 3D segment
+template<typename S, typename B, typename Strategy>
+struct envelope_segment
+{
+    static inline void apply(S const& s, B& mbr, Strategy const&)
+    {
+        ggl::assign_inverse(mbr);
+        ggl::combine(mbr, s.first);
+        ggl::combine(mbr, s.second);
+    }
+};
+
+
+/// Version with state iterating through range (also used in multi*)
+template<typename R, typename Strategy>
+inline void envelope_range_state(R const& range, Strategy const& strategy, typename Strategy::state_type& state)
+{
+    typedef typename boost::range_const_iterator<R>::type iterator_type;
+
+    for (iterator_type it = boost::begin(range); it != boost::end(range); it++)
+    {
+        strategy(*it, state);
+    }
+}
+
+
+
+/// Generic range dispatching struct
+template <typename R, typename B, typename Strategy>
+struct envelope_range
+{
+    /// Calculate envelope of range using a strategy
+    static inline void apply(R const& range, B& mbr, Strategy const& strategy)
+    {
+        typename Strategy::state_type state(mbr);
+        envelope_range_state(range, strategy, state);
+    }
+};
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename Tag1, typename Tag2,
+    typename Geometry, typename Box,
+    typename Strategy
+>
+struct envelope {};
+
+
+template <typename P, typename B, typename Strategy>
+struct envelope<point_tag, box_tag, P, B, Strategy>
+    : detail::envelope::envelope_point<P, B, Strategy>
+{
+private:
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P>) );
+    BOOST_CONCEPT_ASSERT( (concept::Box<B>) );
+};
+
+
+template <typename B, typename Strategy>
+struct envelope<box_tag, box_tag, B, B, Strategy>
+{
+    /*!
+        \brief Calculate envelope of a box
+        \details The envelope of a box is itself, provided for consistency
+        for consistency, on itself it is not useful.
+     */
+    static inline void apply(B const& b, B& mbr, Strategy const&)
+    {
+        mbr = b;
+    }
+
+private:
+    BOOST_CONCEPT_ASSERT( (concept::Box<B>) );
+};
+
+
+template <typename S, typename B, typename Strategy>
+struct envelope<segment_tag, box_tag, S, B, Strategy>
+    : detail::envelope::envelope_segment<S, B, Strategy>
+{};
+
+
+template <typename S, typename B, typename Strategy>
+struct envelope<nsphere_tag, box_tag, S, B, Strategy>
+    : detail::envelope::envelope_nsphere<S, B, Strategy>
+{
+private:
+    BOOST_CONCEPT_ASSERT( (concept::ConstNsphere<S>) );
+    BOOST_CONCEPT_ASSERT( (concept::Box<B>) );
+};
+
+template <typename L, typename B, typename Strategy>
+struct envelope<linestring_tag, box_tag, L, B, Strategy>
+    : detail::envelope::envelope_range<L, B, Strategy>
+{
+private:
+    BOOST_CONCEPT_ASSERT( (concept::ConstLinestring<L>) );
+    BOOST_CONCEPT_ASSERT( (concept::Box<B>) );
+};
+
+
+template <typename R, typename B, typename Strategy>
+struct envelope<ring_tag, box_tag, R, B, Strategy>
+    : detail::envelope::envelope_range<R, B, Strategy>
+{
+private:
+    BOOST_CONCEPT_ASSERT( (concept::ConstRing<R>) );
+    BOOST_CONCEPT_ASSERT( (concept::Box<B>) );
+};
+
+
+template <typename P, typename B, typename Strategy>
+struct envelope<polygon_tag, box_tag, P, B, Strategy>
+{
+    static inline void apply(P const& poly, B& mbr, Strategy const& strategy)
+    {
+        // For polygon inspecting outer linear_ring is sufficient
+
+        detail::envelope::envelope_range
+            <
+                typename ring_type<P>::type,
+                B,
+                Strategy
+            >::apply(exterior_ring(poly), mbr, strategy);
+    }
+
+private:
+    BOOST_CONCEPT_ASSERT( (concept::ConstPolygon<P>) );
+    BOOST_CONCEPT_ASSERT( (concept::Box<B>) );
+};
+
+
+} // namespace dispatch
+#endif
+
+
+/*!
+\brief Calculate envelope of a geometry, using a specified strategy
+\ingroup envelope
+\param geometry the geometry
+\param mbr the box receiving the envelope
+\param strategy strategy to be used
+*/
+template<typename G, typename B, typename S>
+inline void envelope(G const& geometry, B& mbr, S const& strategy)
+{
+    dispatch::envelope
+        <
+            typename tag<G>::type, typename tag<B>::type,
+            G, B, S
+        >::apply(geometry, mbr, strategy);
+}
+
+
+
+
+/*!
+\brief Calculate envelope of a geometry
+\ingroup envelope
+\param geometry the geometry
+\param mbr the box receiving the envelope
+\par Example:
+Example showing envelope calculation, using point_ll latlong points
+\dontinclude doxygen_examples.cpp
+\skip example_envelope_polygon
+\line {
+\until }
+*/
+template<typename G, typename B>
+inline void envelope(G const& geometry, B& mbr)
+{
+    typename strategy_envelope
+        <
+        typename cs_tag<typename point_type<G>::type>::type,
+        typename cs_tag<typename point_type<B>::type>::type,
+        typename point_type<G>::type,
+        B
+        >::type strategy;
+
+    envelope(geometry, mbr, strategy);
+}
+
+
+/*!
+\brief Calculate and return envelope of a geometry
+\ingroup envelope
+\param geometry the geometry
+\param strategy the strategy to be used
+*/
+template<typename B, typename G, typename S>
+inline B make_envelope(G const& geometry, S const& strategy)
+{
+    B box;
+    dispatch::envelope
+        <
+            typename tag<G>::type, typename tag<B>::type,
+            G, B, S
+        >::apply(geometry, box, strategy);
+
+    return box;
+}
+
+
+/*!
+\brief Calculate and return envelope of a geometry
+\ingroup envelope
+\param geometry the geometry
+*/
+template<typename B, typename G>
+inline B make_envelope(G const& geometry)
+{
+    typename strategy_envelope
+        <
+        typename cs_tag<typename point_type<G>::type>::type,
+        typename cs_tag<typename point_type<B>::type>::type,
+        typename point_type<G>::type,
+        B
+        >::type strategy;
+    return make_envelope<B>(geometry, strategy);
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_ENVELOPE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/equals.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/equals.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,134 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_EQUALS_HPP
+#define GGL_ALGORITHMS_EQUALS_HPP
+
+#include <cstddef>
+
+#include <boost/static_assert.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/is_multi.hpp>
+#include <ggl/algorithms/disjoint.hpp>
+#include <ggl/algorithms/detail/not.hpp>
+#include <ggl/util/math.hpp>
+
+/*!
+
+\defgroup boolean_relations boolean relationships (equals, disjoint, overlaps, etc)
+
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace equals {
+
+template <typename B1, typename B2, std::size_t D, std::size_t N>
+struct box_box
+{
+    static inline bool apply(B1 const& box1, B2 const& box2)
+    {
+        if (!math::equals(get<min_corner, D>(box1), get<min_corner, D>(box2))
+            || !math::equals(get<max_corner, D>(box1), get<max_corner, D>(box2)))
+        {
+            return false;
+        }
+        return box_box<B1, B2, D + 1, N>::apply(box1, box2);
+    }
+};
+
+template <typename B1, typename B2, std::size_t N>
+struct box_box<B1, B2, N, N>
+{
+    static inline bool apply(B1 const& , B2 const& )
+    {
+        return true;
+    }
+};
+
+}} // namespace detail::equals
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename GeometryTag,
+    bool IsMulti,
+    typename G1,
+    typename G2,
+    std::size_t DimensionCount
+>
+struct equals
+{
+};
+
+template <typename P1, typename P2, std::size_t DimensionCount>
+struct equals<point_tag, false, P1, P2, DimensionCount>
+    : ggl::detail::not_
+        <
+            P1,
+            P2,
+            detail::disjoint::point_point<P1, P2, 0, DimensionCount>
+        >
+{
+};
+
+template <typename B1, typename B2, std::size_t DimensionCount>
+struct equals<box_tag, false, B1, B2, DimensionCount>
+    : detail::equals::box_box<B1, B2, 0, DimensionCount>
+{
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Calculate if two geometries are equals
+    \ingroup boolean_relations
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \return true if equals, else false
+ */
+template <typename Geometry1, typename Geometry2>
+inline bool equals(Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+    assert_dimension_equal<Geometry1, Geometry2>();
+
+// TODO: assert types equal:
+// typename tag<ncg1_type>::type, typename tag<ncg2_type>::type,
+// (LATER): NO! a linestring can be spatially equal to a multi_linestring
+
+    typedef typename boost::remove_const<Geometry1>::type ncg1_type;
+    typedef typename boost::remove_const<Geometry2>::type ncg2_type;
+
+    return dispatch::equals
+            <
+                typename tag<ncg1_type>::type,
+                is_multi<ncg1_type>::type::value,
+                ncg1_type,
+                ncg2_type,
+                dimension<ncg1_type>::type::value
+            >::apply(geometry1, geometry2);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_EQUALS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/for_each.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/for_each.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,268 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_FOR_EACH_HPP
+#define GGL_ALGORITHMS_FOR_EACH_HPP
+
+/*!
+\defgroup loop loops and for-each functionality
+There are several algorithms provided which walk through the points or segments
+of linestrings and polygons. They are called for_each_point, for_each_segment, after
+the standard library, and \b loop which is more adapted and of which the functor
+could break out if necessary.
+Of the for_each algorithms there is a \b const and a non-const version provided.
+*/
+
+#include <algorithm>
+
+#include <boost/concept/requires.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/geometries/segment.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace for_each {
+
+template <typename P, typename F>
+struct fe_point
+{
+    static inline F for_each_const_point(P const& p, F f)
+    {
+        f(p);
+        return (f);
+    }
+
+    static inline F for_each_point(P& p, F f)
+    {
+        f(p);
+        return (f);
+    }
+};
+
+template <typename R, typename F>
+struct fe_range
+{
+    static inline F for_each_const_point(R const& range, F f)
+    {
+        return (std::for_each(boost::begin(range), boost::end(range), f));
+    }
+
+    static inline F for_each_point(R& range, F f)
+    {
+        return (std::for_each(boost::begin(range), boost::end(range), f));
+    }
+
+    static inline F for_each_const_segment(R const& range, F f)
+    {
+        typedef typename boost::range_const_iterator<R>::type iterator_type;
+
+        iterator_type it = boost::begin(range);
+        iterator_type previous = it++;
+        while(it != boost::end(range))
+        {
+            segment<typename point_type<R>::type> s(*previous, *it);
+            f(s);
+            previous = it++;
+        }
+
+        return (f);
+    }
+
+    static inline F for_each_segment(R& range, F f)
+    {
+        typedef typename boost::range_iterator<R>::type iterator_type;
+
+        iterator_type it = boost::begin(range);
+        iterator_type previous = it++;
+        while(it != boost::end(range))
+        {
+            segment<typename point_type<R>::type> s(*previous, *it);
+            f(s);
+            previous = it++;
+        }
+
+        return (f);
+    }
+};
+
+template <typename P, typename F>
+struct fe_polygon
+{
+    static inline F for_each_const_point(P const& poly, F f)
+    {
+        typedef typename ring_type<P>::type ring_type;
+        typedef typename boost::range_const_iterator
+            <
+            typename interior_type<P>::type
+            >::type iterator_type;
+
+        f = fe_range<ring_type, F>::for_each_const_point(exterior_ring(poly), f);
+
+        for (iterator_type it = boost::begin(interior_rings(poly));
+             it != boost::end(interior_rings(poly)); it++)
+        {
+            f = fe_range<ring_type, F>::for_each_const_point(*it, f);
+        }
+
+        return (f);
+    }
+
+    static inline F for_each_point(P& poly, F f)
+    {
+        typedef typename ring_type<P>::type ring_type;
+        typedef typename boost::range_iterator
+            <
+            typename interior_type<P>::type
+            >::type iterator_type;
+
+        f = fe_range<ring_type, F>::for_each_point(exterior_ring(poly), f);
+
+        for (iterator_type it = boost::begin(interior_rings(poly));
+             it != boost::end(interior_rings(poly)); it++)
+        {
+            f = fe_range<ring_type, F>::for_each_point(*it, f);
+        }
+
+        return (f);
+    }
+
+    static inline F for_each_const_segment(P const& poly, F f)
+    {
+        typedef typename ring_type<P>::type ring_type;
+        typedef typename boost::range_const_iterator
+            <
+            typename interior_type<P>::type
+            >::type iterator_type;
+
+        f = fe_range<ring_type, F>::for_each_const_segment(exterior_ring(poly), f);
+
+        for (iterator_type it = boost::begin(interior_rings(poly));
+             it != boost::end(interior_rings(poly)); it++)
+        {
+            f = fe_range<ring_type, F>::for_each_const_segment(*it, f);
+        }
+
+        return (f);
+    }
+
+    static inline F for_each_segment(P& poly, F f)
+    {
+        typedef typename ring_type<P>::type ring_type;
+        typedef typename boost::range_iterator
+            <
+            typename interior_type<P>::type
+            >::type iterator_type;
+
+        f = fe_range<ring_type, F>::for_each_segment(exterior_ring(poly), f);
+
+        for (iterator_type it = boost::begin(interior_rings(poly));
+             it != boost::end(interior_rings(poly)); it++)
+        {
+            f = fe_range<ring_type, F>::for_each_segment(*it, f);
+        }
+
+        return (f);
+    }
+};
+
+}} // namespace detail::for_each
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename T, typename G, typename F>
+struct for_each {};
+
+template <typename P, typename F>
+struct for_each<point_tag, P, F> : detail::for_each::fe_point<P, F> {};
+
+template <typename L, typename F>
+struct for_each<linestring_tag, L, F> : detail::for_each::fe_range<L, F> {};
+
+template <typename R, typename F>
+struct for_each<ring_tag, R, F> : detail::for_each::fe_range<R, F> {};
+
+template <typename P, typename F>
+struct for_each<polygon_tag, P, F> : detail::for_each::fe_polygon<P, F> {};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+/*!
+    \brief Calls functor for geometry
+    \ingroup loop
+    \param geometry geometry to loop through
+    \param f functor to use
+    \details Calls the functor the specified \b const geometry
+*/
+template<typename G, typename F>
+inline F for_each_point(G const& geometry, F f)
+{
+    typedef typename dispatch::for_each
+        <
+        typename tag<G>::type,
+        G,
+        F
+        >::for_each_const_point for_each_type;
+
+    return for_each_type(geometry, f);
+}
+
+/*!
+    \brief Calls functor for geometry
+    \ingroup loop
+    \param geometry geometry to loop through
+    \param f functor to use
+    \details Calls the functor for the specified geometry
+*/
+template<typename G, typename F>
+inline F for_each_point(G& geometry, F f)
+{
+    return (dispatch::for_each<typename tag<G>::type, G, F>::for_each_point(geometry, f));
+}
+
+/*!
+    \brief Calls functor for segments on linestrings, rings, polygons, ...
+    \ingroup loop
+    \param geometry geometry to loop through
+    \param f functor to use
+    \details Calls the functor all \b const segments of the specified \b const geometry
+*/
+template<typename G, typename F>
+inline F for_each_segment(const G& geometry, F f)
+{
+    return (dispatch::for_each<typename tag<G>::type, G, F>::for_each_const_segment(geometry, f));
+}
+
+
+/*!
+    \brief Calls functor for segments on linestrings, rings, polygons, ...
+    \ingroup loop
+    \param geometry geometry to loop through
+    \param f functor to use
+    \details Calls the functor all segments of the specified geometry
+*/
+template<typename G, typename F>
+inline F for_each_segment(G& geometry, F f)
+{
+    return (dispatch::for_each<typename tag<G>::type, G, F>::for_each_segment(geometry, f));
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_FOR_EACH_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/get_section.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/get_section.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,102 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_GET_SECTION_HPP
+#define GGL_ALGORITHMS_GET_SECTION_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/concept/requires.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+
+#include <ggl/iterators/point_const_iterator.hpp>
+
+#include <ggl/geometries/segment.hpp>
+
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename Geometry, typename Section>
+struct get_section
+{
+    typedef typename ggl::point_const_iterator<Geometry>::type iterator_type;
+    static inline void apply(Geometry const& geometry, Section const& section,
+                iterator_type& begin, iterator_type& end)
+    {
+        begin = boost::begin(geometry) + section.begin_index;
+        end = boost::begin(geometry) + section.end_index + 1;
+    }
+};
+
+template <typename Polygon, typename Section>
+struct get_section<polygon_tag, Polygon, Section>
+{
+    typedef typename ggl::point_const_iterator<Polygon>::type iterator_type;
+    static inline void apply(Polygon const& polygon, Section const& section,
+                iterator_type& begin, iterator_type& end)
+    {
+        typedef typename ggl::ring_type<Polygon>::type ring_type;
+        ring_type const& ring = section.ring_index < 0
+            ? ggl::exterior_ring(polygon)
+            : ggl::interior_rings(polygon)[section.ring_index];
+
+        begin = boost::begin(ring) + section.begin_index;
+        end = boost::begin(ring) + section.end_index + 1;
+    }
+};
+
+} // namespace dispatch
+#endif
+
+
+
+
+/*!
+    \brief Get iterators for a specified section
+    \ingroup sectionalize
+    \tparam Geometry type
+    \tparam Section type of section to get from
+    \param geometry geometry which might be located in the neighborhood
+    \param section structure with section
+    \param begin begin-iterator (const iterator over points of section)
+    \param end end-iterator (const iterator over points of section)
+    \todo Create non-const version as well
+
+ */
+template <typename Geometry, typename Section>
+inline void get_section(Geometry const& geometry, Section const& section,
+    typename point_const_iterator<Geometry>::type& begin,
+    typename point_const_iterator<Geometry>::type& end)
+{
+    dispatch::get_section
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            Section
+        >::apply(geometry, section, begin, end);
+}
+
+
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_GET_SECTION_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/intermediate.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/intermediate.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,126 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_INTERMEDIATE_HPP
+#define GGL_ALGORITHMS_INTERMEDIATE_HPP
+
+#include <cstddef>
+#include <iterator>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/strategies/strategies.hpp>
+
+/*!
+\defgroup intermediate intermediate calculation
+The intermediate algorithm calculate points IN BETWEEN of other points
+\par Purpose:
+- Remove corners in rectangular lines / polygons. Calling them several times will result in smooth lines
+- Creating 3D models
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intermediate {
+
+template <typename Src, typename Dst, std::size_t Dimension, std::size_t DimensionCount>
+struct calculate_coordinate
+{
+    static inline void apply(Src const& p1, Src const& p2, Dst& p)
+    {
+        ggl::set<Dimension>(p,
+                    (ggl::get<Dimension>(p1) + ggl::get<Dimension>(p2)) / 2.0);
+        calculate_coordinate<Src, Dst, Dimension + 1, DimensionCount>::apply(p1, p2, p);
+    }
+};
+
+template <typename Src, typename Dst, std::size_t DimensionCount>
+struct calculate_coordinate<Src, Dst, DimensionCount, DimensionCount>
+{
+    static inline void apply(Src const&, Src const&, Dst&)
+    {
+    }
+};
+
+template<typename R, typename Iterator>
+struct range_intermediate
+{
+    static inline void apply(R const& range, bool start_and_end, Iterator out)
+    {
+        typedef typename point_type<R>::type point_type;
+        typedef typename boost::range_const_iterator<R>::type iterator_type;
+
+        iterator_type it = boost::begin(range);
+
+        if (start_and_end)
+        {
+            (*out++) = *it;
+        }
+
+        iterator_type prev = it++;
+        for (; it != boost::end(range); prev = it++)
+        {
+            point_type p;
+            calculate_coordinate
+                <
+                    point_type,
+                    point_type,
+                    0,
+                    dimension<point_type>::type::value
+                >::apply(*prev, *it, p);
+            *(out++) = p;
+        }
+
+        if (start_and_end)
+        {
+            (*out++) = *prev;
+        }
+    }
+};
+
+}} // namespace detail::intermediate
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename GeometryTag, typename G, typename Iterator>
+struct intermediate  {};
+
+template <typename G, typename Iterator>
+struct intermediate<ring_tag, G, Iterator>
+        : detail::intermediate::range_intermediate<G, Iterator> {};
+
+template <typename G, typename Iterator>
+struct intermediate<linestring_tag, G, Iterator>
+        : detail::intermediate::range_intermediate<G, Iterator> {};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Calculate intermediate of a geometry
+    \ingroup intermediate
+ */
+template<typename G, typename Iterator>
+inline void intermediate(const G& geometry, bool start_and_end, Iterator out)
+{
+    dispatch::intermediate<typename tag<G>::type, G, Iterator>::apply(geometry, start_and_end, out);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_INTERMEDIATE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersection.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersection.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,455 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_INTERSECTION_HPP
+#define GGL_ALGORITHMS_INTERSECTION_HPP
+
+#include <deque>
+
+#include <ggl/algorithms/intersection_linestring.hpp>
+
+#include <ggl/algorithms/overlay/get_intersection_points.hpp>
+#include <ggl/algorithms/overlay/merge_intersection_points.hpp>
+#include <ggl/algorithms/overlay/adapt_turns.hpp>
+#include <ggl/algorithms/overlay/enrich_intersection_points.hpp>
+#include <ggl/algorithms/overlay/traverse.hpp>
+
+#include <ggl/algorithms/assign.hpp>
+#include <ggl/algorithms/convert.hpp>
+#include <ggl/algorithms/within.hpp>
+
+
+
+/*!
+\defgroup overlay overlay operations (intersection, union, clipping)
+\details The intersection of two geometries A and B is the geometry containing all points of A also belonging to B,
+but no other elements. The so-called clip is an intersection of a geometry with a box.
+\par Source description:
+- OGC: Returns a geometric object that represents the Point set intersection of this geometric object with another Geometry.
+\see http://en.wikipedia.org/wiki/Intersection_(set_theory)
+\note Any intersection can result in no geometry at all
+
+\note Used strategies still have to be modelled. Working only for cartesian
+\par Geometries:
+The intersection result is painted with a red outline.
+- clip: POLYGON + BOX -> output iterator of polygons
+\image html clip_polygon.png
+- clip: LINESTRING + BOX -> output iterator of linestrings
+\image html clip_linestring.png
+\note There are some difficulties to model an intersection in the template world. The intersection of two segments can
+result into nothing, into a point, into another segment. At compiletime the result type is not known. An output iterator
+iterating points is appropriate here.
+\image html clip_segment_segment.png
+An intersection of two linestrings can result into nothing, one or more points, one or more segments or one or more
+linestrings. So an output iterator will NOT do here.
+So the output might be changed into a unified algorithm where the output is a multi-geometry.
+For the current clip-only operations the output iterator will do.
+
+\par Example:
+Example showing clipping of linestring with box
+\dontinclude doxygen_examples.cpp
+\skip example_intersection_linestring1
+\line {
+\until }
+\par Example:
+Example showing clipping of vector, outputting vectors, with box
+\dontinclude doxygen_examples.cpp
+\skip example_intersection_linestring2
+\line {
+\until }
+\par Example:
+Example showing clipping of polygon with box
+\dontinclude doxygen_examples.cpp
+\skip example_intersection_polygon1
+\line {
+\until }
+*/
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection {
+
+
+template
+<
+    typename Polygon1, typename Polygon2,
+    typename OutputIterator, typename GeometryOut
+>
+struct intersection_polygon_polygon
+{
+    static inline OutputIterator apply(Polygon1 const& polygon1,
+                Polygon2 const& polygon2, OutputIterator out)
+    {
+        typedef detail::intersection::intersection_point
+            <
+                typename ggl::point_type<GeometryOut>::type
+            > ip_type;
+        typedef std::deque<ip_type> ips_container;
+
+        typedef typename ggl::ring_type<GeometryOut>::type ring_type;
+
+        ips_container ips;
+
+        bool trivial = ggl::get_intersection_points(polygon1, polygon2, ips);
+
+        if (ips.size() <= 0)
+        {
+            // If there are no IP-s, check if one point is in other polygon
+            // assume both polygons having points
+            if (ggl::within(ggl::exterior_ring(polygon1).front(), polygon2))
+            {
+                // Assume same type (output = input)
+                // TODO: solve this (we go to specialize again...)
+                *out = polygon1;
+                out++;
+            }
+            else if (ggl::within(ggl::exterior_ring(polygon2).front(), polygon1))
+            {
+                *out = polygon2;
+                out++;
+            }
+        }
+        else
+        {
+            if (! trivial)
+            {
+                ggl::merge_intersection_points(ips);
+                ggl::adapt_turns(ips);
+
+            }
+
+            ggl::enrich_intersection_points(ips, trivial);
+
+
+            std::vector<ring_type> v;
+            ggl::traverse<ring_type>
+                (
+                    polygon1,
+                    polygon2,
+                    -1,
+                    ips,
+                    trivial,
+                    std::back_inserter(v)
+                );
+
+
+            // TODO:
+            // assemble rings / inner rings / to polygons
+            for (typename std::vector<ring_type>::const_iterator it = v.begin();
+                it != v.end(); ++it)
+            {
+                // How can we avoid the double copy here! It is really bad!
+                // We have to create a polygon, then copy it to the output iterator.
+                // Having an output-vector would have been better: append it to the vector!
+                // So output iterators are not that good.
+                GeometryOut poly;
+                poly.outer() = *it;
+                *out = poly;
+                out++;
+            }
+        }
+
+
+        return out;
+    }
+};
+
+
+
+
+template
+<
+    typename Polygon, typename Box,
+    typename OutputIterator, typename GeometryOut
+>
+struct intersection_polygon_box
+{
+    static inline OutputIterator apply(Polygon const& polygon,
+                Box const& box, OutputIterator out)
+    {
+        typedef typename ggl::point_type<GeometryOut>::type point_type;
+        typedef detail::intersection::intersection_point<point_type> ip_type;
+        typedef std::deque<ip_type> ips_container;
+
+        typedef typename ggl::ring_type<GeometryOut>::type ring_type;
+
+        ips_container ips;
+
+        bool trivial = ggl::get_intersection_points(polygon, box, ips);
+
+        // TODO: share this all with polygon_polygon using an "assemble" function!
+        // It is only different in the 'within' calls, can be sorted out with specialization
+
+
+        if (ips.size() <= 0)
+        {
+            // If there are no IP-s, check if one point is in other polygon
+            // assume both polygons having points
+            if (ggl::within(ggl::exterior_ring(polygon).front(), box))
+            {
+                // Assume same type (output = input)
+                // TODO: solve this (we go to specialize again...)
+                *out = polygon;
+                out++;
+            }
+            else
+            {
+                typename ggl::point_type<Box>::type p;
+                ggl::set<0>(p, ggl::get<min_corner, 0>(box));
+                ggl::set<1>(p, ggl::get<min_corner, 1>(box));
+                if (ggl::within(p, polygon))
+                {
+                    GeometryOut boxpoly;
+                    ggl::convert(box, boxpoly);
+                    *out = boxpoly;
+                    out++;
+                }
+            }
+        }
+        else
+        {
+            if (trivial)
+            {
+                ggl::merge_intersection_points(ips);
+            }
+
+            ggl::enrich_intersection_points(ips, trivial);
+
+            std::vector<ring_type> v;
+            ggl::traverse<ring_type>
+                (
+                    polygon,
+                    box,
+                    -1,
+                    ips,
+                    trivial,
+                    std::back_inserter(v)
+                );
+
+            // TODO:
+            // assemble rings / inner rings / to polygons
+            for (typename std::vector<ring_type>::const_iterator it = v.begin();
+                it != v.end(); ++it)
+            {
+                // How can we avoid the double copy here! It is really bad!
+                // We have to create a polygon, then copy it to the output iterator.
+                // Having an output-vector would have been better: append it to the vector!
+                // So output iterators are not that good.
+                GeometryOut poly;
+                poly.outer() = *it;
+                *out = poly;
+                out++;
+            }
+        }
+
+
+        return out;
+    }
+};
+
+
+}} // namespace detail::intersection
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename Tag1, typename Tag2, typename Tag3,
+    typename G1, typename G2,
+    typename OutputIterator,
+    typename GeometryOut
+>
+struct intersection {};
+
+
+template
+<
+    typename Segment1, typename Segment2,
+    typename OutputIterator, typename GeometryOut
+>
+struct intersection
+    <
+        segment_tag, segment_tag, point_tag,
+        Segment1, Segment2,
+        OutputIterator, GeometryOut
+    >
+{
+    static inline OutputIterator apply(Segment1 const& segment1,
+            Segment2 const& segment2, OutputIterator out)
+    {
+        typedef typename point_type<GeometryOut>::type point_type;
+
+        // Get the intersection point (or two points)
+        segment_intersection_points<point_type> is
+            = strategy::intersection::relate_cartesian_segments
+            <
+                policies::relate::segments_intersection_points
+                    <
+                        Segment1,
+                        Segment2,
+                        segment_intersection_points<point_type>
+                    >
+            >::relate(segment1, segment2);
+        for (int i = 0; i < is.count; i++)
+        {
+            GeometryOut p;
+            ggl::copy_coordinates(is.intersections[i], p);
+            *out = p;
+            out++;
+        }
+        return out;
+    }
+};
+
+
+template
+<
+    typename Linestring, typename Box,
+    typename OutputIterator, typename GeometryOut
+>
+struct intersection
+    <
+        linestring_tag, box_tag, linestring_tag,
+        Linestring, Box,
+        OutputIterator, GeometryOut
+    >
+{
+    static inline OutputIterator apply(Linestring const& linestring,
+            Box const& box, OutputIterator out)
+    {
+        typedef typename point_type<GeometryOut>::type point_type;
+        strategy::intersection::liang_barsky<Box, point_type> strategy;
+        return detail::intersection::clip_linestring_with_box<GeometryOut>(box, linestring, out, strategy);
+    }
+};
+
+
+template
+<
+    typename Polygon1, typename Polygon2,
+    typename OutputIterator, typename GeometryOut
+>
+struct intersection
+    <
+        polygon_tag, polygon_tag, polygon_tag,
+        Polygon1, Polygon2,
+        OutputIterator, GeometryOut
+    >
+    : detail::intersection::intersection_polygon_polygon
+        <Polygon1, Polygon2, OutputIterator, GeometryOut>
+{};
+
+
+
+template
+<
+    typename Polygon, typename Box,
+    typename OutputIterator, typename GeometryOut
+>
+struct intersection
+<
+    polygon_tag, box_tag, polygon_tag,
+    Polygon, Box,
+    OutputIterator, GeometryOut
+>
+    : detail::intersection::intersection_polygon_box
+        <Polygon, Box, OutputIterator, GeometryOut>
+{};
+
+
+
+template
+<
+    typename GeometryTag1, typename GeometryTag2, typename GeometryTag3,
+    typename G1, typename G2,
+    typename OutputIterator, typename GeometryOut
+>
+struct intersection_reversed
+{
+    static inline OutputIterator apply(G1 const& g1, G2 const& g2, OutputIterator out)
+    {
+        return intersection
+            <
+                GeometryTag2, GeometryTag1, GeometryTag3,
+                G2, G1,
+                OutputIterator, GeometryOut
+            >::apply(g2, g1, out);
+    }
+};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+/*!
+    \brief Intersects two geometries which each other
+    \ingroup overlay
+    \details A sequence of points is intersected (clipped) by the specified box
+    and the resulting linestring, or pieces of linestrings, are sent to the specified output operator.
+    \tparam GeometryOut output geometry type, must be specified
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \tparam OutputIterator output iterator
+    \param geometry1 first geometry (currently only a BOX)
+    \param geometry2 second geometry (range, linestring, polygon)
+    \param out the output iterator, outputting linestrings or polygons
+    \return the output iterator
+    \note For linestrings: the default clipping strategy, Liang-Barsky, is used. The algorithm is currently only
+    implemented for 2D xy points. It could be generic for most ll cases, but not across the 180
+    meridian so that issue is still on the todo-list.
+*/
+template
+<
+    typename GeometryOut,
+    typename Geometry1,
+    typename Geometry2,
+    typename OutputIterator
+>
+inline OutputIterator intersection(Geometry1 const& geometry1,
+            Geometry2 const& geometry2,
+            OutputIterator out)
+{
+
+    return boost::mpl::if_c
+        <
+            reverse_dispatch<Geometry1, Geometry2>::type::value,
+            dispatch::intersection_reversed
+            <
+                typename tag<Geometry1>::type,
+                typename tag<Geometry2>::type,
+                typename tag<GeometryOut>::type,
+                Geometry1,
+                Geometry2,
+                OutputIterator, GeometryOut
+            >,
+            dispatch::intersection
+            <
+                typename tag<Geometry1>::type,
+                typename tag<Geometry2>::type,
+                typename tag<GeometryOut>::type,
+                Geometry1,
+                Geometry2,
+                OutputIterator, GeometryOut
+            >
+        >::type::apply(geometry1, geometry2, out);
+}
+
+} // ggl
+
+#endif //GGL_ALGORITHMS_INTERSECTION_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersection_linestring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersection_linestring.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,236 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_INTERSECTION_LINESTRING_HPP
+#define GGL_ALGORITHMS_INTERSECTION_LINESTRING_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/append.hpp>
+#include <ggl/algorithms/clear.hpp>
+#include <ggl/util/copy.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+#include <ggl/geometries/segment.hpp>
+
+namespace ggl
+{
+
+namespace strategy { namespace intersection {
+
+/*!
+    \brief Strategy: line clipping algorithm after Liang Barsky
+    \ingroup overlay
+    \details The Liang-Barsky line clipping algorithm clips a line with a clipping box.
+    It is slightly adapted in the sense that it returns which points are clipped
+    \tparam B input box type of clipping box
+    \tparam P input/output point-type of segments to be clipped
+    \note The algorithm is currently only implemented for 2D Cartesian points
+    \author Barend Gehrels, and the following recourses
+    - A tutorial: http://www.skytopia.com/project/articles/compsci/clipping.html
+    - a German applet (link broken): http://ls7-www.cs.uni-dortmund.de/students/projectgroups/acit/lineclip.shtml
+*/
+template<typename B, typename P>
+class liang_barsky
+{
+private:
+    typedef ggl::segment<P> segment_type;
+
+    inline bool check_edge(double const& p, double const& q, double& t1, double& t2) const
+    {
+        bool visible = true;
+
+        if(p < 0)
+        {
+            // TODO: Move r definition one scope level up to reuse --mloskot
+            double const r = q / p;
+            if (r > t2)
+                visible = false;
+            else if (r > t1)
+                t1 = r;
+        }
+        else if(p > 0)
+        {
+            double const r = q / p;
+            if (r < t1)
+                visible = false;
+            else if (r < t2)
+                t2 = r;
+        }
+        else
+        {
+            if (q < 0)
+                visible = false;
+        }
+
+        return visible;
+    }
+
+public:
+
+    bool clip_segment(B const& b, segment_type& s, bool& sp1_clipped, bool& sp2_clipped) const
+    {
+        typedef typename select_coordinate_type<B, P>::type coordinate_type;
+
+        double t1 = 0;
+        double t2 = 1;
+
+        coordinate_type const dx = get<1, 0>(s) - get<0, 0>(s);
+        coordinate_type const dy = get<1, 1>(s) - get<0, 1>(s);
+
+        coordinate_type const p1 = -dx;
+        coordinate_type const p2 = dx;
+        coordinate_type const p3 = -dy;
+        coordinate_type const p4 = dy;
+
+        coordinate_type const q1 = get<0, 0>(s) - get<min_corner, 0>(b);
+        coordinate_type const q2 = get<max_corner, 0>(b) - get<0, 0>(s);
+        coordinate_type const q3 = get<0, 1>(s) - get<min_corner, 1>(b);
+        coordinate_type const q4 = get<max_corner, 1>(b) - get<0, 1>(s);
+
+        if (check_edge(p1, q1, t1, t2)      // left
+            && check_edge(p2, q2, t1, t2)   // right
+            && check_edge(p3, q3, t1, t2)   // bottom
+            && check_edge(p4, q4, t1, t2))   // top
+        {
+            sp1_clipped = t1 > 0;
+            sp2_clipped = t2 < 1;
+
+            // TODO: maybe round coordinates in case of integer? define some round_traits<> or so?
+            // Take boost-round of Fernando
+            if (sp2_clipped)
+            {
+                set<1, 0>(s, get<0, 0>(s) + t2 * dx);
+                set<1, 1>(s, get<0, 1>(s) + t2 * dy);
+            }
+
+            if(sp1_clipped)
+            {
+                set<0, 0>(s, get<0, 0>(s) + t1 * dx);
+                set<0, 1>(s, get<0, 1>(s) + t1 * dy);
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    template<typename L, typename OutputIterator>
+    inline void add(L& line_out, OutputIterator out) const
+    {
+        if (!boost::empty(line_out))
+        {
+            *out = line_out;
+            ++out;
+            ggl::clear(line_out);
+        }
+    }
+};
+}} // namespace strategy::intersection
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection {
+
+/*!
+    \brief Clips a linestring with a box
+    \details A linestring is intersected (clipped) by the specified box
+    and the resulting linestring, or pieces of linestrings, are sent to the specified output operator.
+    \tparam OutputLinestring type of the output linestrings
+    \tparam OutputIterator an output iterator which outputs linestrings
+    \tparam Linestring linestring-type, for example a vector of points, matching the output-iterator type,
+         the points should also match the input-iterator type
+    \tparam Box box type
+    \tparam Strategy strategy, a clipping strategy which should implement the methods "clip_segment" and "add"
+*/
+template
+<
+    typename OutputLinestring,
+    typename OutputIterator,
+    typename Linestring,
+    typename Box,
+    typename Strategy
+>
+OutputIterator clip_linestring_with_box(Box const& b, Linestring const& linestring,
+            OutputIterator out, Strategy const& strategy)
+{
+    if (boost::begin(linestring) == boost::end(linestring))
+    {
+        return out;
+    }
+
+    typedef typename point_type<OutputLinestring>::type point_type;
+
+    OutputLinestring line_out;
+
+    typedef typename boost::range_const_iterator<Linestring>::type iterator_type;
+    iterator_type vertex = boost::begin(linestring);
+    for(iterator_type previous = vertex++;
+            vertex != boost::end(linestring);
+            previous = vertex++)
+    {
+        point_type p1, p2;
+        copy_coordinates(*previous, p1);
+        copy_coordinates(*vertex, p2);
+
+        // Clip the segment. Five situations:
+        // 1. Segment is invisible, finish line if any (shouldn't occur)
+        // 2. Segment is completely visible. Add (p1)-p2 to line
+        // 3. Point 1 is invisible (clipped), point 2 is visible. Start new line from p1-p2...
+        // 4. Point 1 is visible, point 2 is invisible (clipped). End the line with ...p2
+        // 5. Point 1 and point 2 are both invisible (clipped). Start/finish an independant line p1-p2
+        //
+        // This results in:
+        // a. if p1 is clipped, start new line
+        // b. if segment is partly or completely visible, add the segment
+        // c. if p2 is clipped, end the line
+
+        bool c1 = false;
+        bool c2 = false;
+        segment<point_type> s(p1, p2);
+
+        if (!strategy.clip_segment(b, s, c1, c2))
+        {
+            strategy.add(line_out, out);
+        }
+        else
+        {
+            // a. If necessary, finish the line and add a start a new one
+            if (c1)
+            {
+                strategy.add(line_out, out);
+            }
+
+            // b. Add p1 only if it is the first point, then add p2
+            if (boost::empty(line_out))
+            {
+                ggl::append(line_out, p1);
+            }
+            ggl::append(line_out, p2);
+
+            // c. If c2 is clipped, finish the line
+            if (c2)
+            {
+                strategy.add(line_out, out);
+            }
+        }
+
+    }
+
+    // Add last part
+    strategy.add(line_out, out);
+    return out;
+}
+
+}} // namespace detail::intersection
+#endif // DOXYGEN_NO_DETAIL
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_INTERSECTION_LINESTRING_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersects.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/intersects.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,61 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_INTERSECTS_HPP
+#define GGL_ALGORITHMS_INTERSECTS_HPP
+
+#include <ggl/algorithms/intersection_linestring.hpp>
+
+#include <ggl/algorithms/overlay/get_intersection_points.hpp>
+#include <ggl/algorithms/overlay/self_intersection_points.hpp>
+#include <ggl/algorithms/overlay/adapt_turns.hpp>
+#include <ggl/algorithms/overlay/enrich_intersection_points.hpp>
+#include <ggl/algorithms/overlay/traverse.hpp>
+
+#include <ggl/algorithms/assign.hpp>
+#include <ggl/algorithms/convert.hpp>
+#include <ggl/algorithms/within.hpp>
+
+
+
+namespace ggl
+{
+
+/*!
+    \brief Determine if there is at least one intersection
+        (crossing or self-tangency)
+    \note This function can be called for one geometry (self-intersection) and
+        also for two geometries (intersection)
+    \ingroup overlay
+    \tparam Geometry geometry type
+    \param geometry geometry
+    \return TRUE if there are intersections, else FALSE
+ */
+template <typename Geometry>
+inline bool intersects(Geometry const& geometry)
+{
+    typedef typename boost::remove_const<Geometry>::type ncg_type;
+
+    typedef std::vector<ggl::detail::intersection::intersection_point
+        <typename ggl::point_type<Geometry>::type> > ip_vector;
+
+    ip_vector ips;
+
+    dispatch::self_intersection_points
+            <
+                typename tag<ncg_type>::type,
+                is_multi<ncg_type>::type::value,
+                ncg_type,
+                ip_vector
+            >::apply(geometry, true, ips);
+    return ips.size() > 0;
+}
+
+} // ggl
+
+#endif //GGL_ALGORITHMS_INTERSECTS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/length.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/length.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,181 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_LENGTH_HPP
+#define GGL_ALGORITHMS_LENGTH_HPP
+
+#include <iterator>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+
+#include <ggl/algorithms/detail/calculate_null.hpp>
+#include <ggl/core/cs.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/strategies/strategies.hpp>
+
+/*!
+\defgroup length length calculation
+The length algorithm is implemented for the linestring and the multi_linestring geometry and results
+in the length of the linestring. If the points of a linestring have coordinates expressed in kilometers,
+the length of the line is expressed in kilometers as well.
+\par Example:
+Example showing length calculation
+\dontinclude doxygen_examples.cpp
+\skip example_length_linestring_iterators1
+\line {
+\until }
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace length {
+
+
+template<typename Segment, typename Strategy>
+struct segment_length
+{
+    static inline double apply(Segment const& segment, Strategy const& strategy)
+    {
+        // BSG 10 APR 2009
+        // TODO: the segment concept has to be such that it is easy to return a point from it.
+        // Now it only accesses per coordinate
+        return strategy(segment.first, segment.second);
+    }
+};
+
+/*!
+\brief Internal, calculates length of a linestring using iterator pairs and specified strategy
+\note for_each could be used here, now that point_type is changed by boost range iterator
+*/
+template<typename Range, typename Strategy>
+struct range_length
+{
+    static inline double apply(Range const& range, Strategy const& strategy)
+    {
+        typedef typename ggl::coordinate_type<Range>::type coordinate_type;
+
+        // Because result is square-rooted, for integer, the cast should
+        // go to double and NOT to T
+        typedef typename
+            boost::mpl::if_c
+            <
+                boost::is_integral<coordinate_type>::type::value,
+                double,
+                coordinate_type
+            >::type calculation_type;
+
+        calculation_type sum = 0.0;
+
+        typedef typename boost::range_const_iterator<Range>::type iterator_type;
+        iterator_type it = boost::begin(range);
+        if (it != boost::end(range))
+        {
+            iterator_type previous = it++;
+            while(it != boost::end(range))
+            {
+                // Add point-point distance using the return type belonging to strategy
+                sum += strategy(*previous, *it);
+                previous = it++;
+            }
+        }
+
+        return sum;
+    }
+};
+
+}} // namespace detail::length
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Tag, typename G, typename S>
+struct length : detail::calculate_null<double, G, S>
+{};
+
+
+template <typename G, typename S>
+struct length<linestring_tag, G, S>
+    : detail::length::range_length<G, S>
+{};
+
+
+// RING: length is currently 0.0 but it might be argued that it is the "perimeter"
+template <typename G, typename S>
+struct length<segment_tag, G, S> : detail::length::segment_length<G, S>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+/*!
+    \brief Calculate length of a geometry
+    \ingroup length
+    \details The function length returns the length of a geometry, using the default distance-calculation-strategy
+    \param geometry the geometry, being a ggl::linestring, vector, iterator pair, or any other boost compatible range
+    \return the length
+    Example showing length calculation on a vector
+    \dontinclude doxygen_examples.cpp
+    \skip example_length_linestring_iterators2
+    \line {
+    \until }
+ */
+template<typename G>
+inline double length(const G& geometry)
+{
+    typedef typename point_type<G>::type point_type;
+    typedef typename cs_tag<point_type>::type cs_tag;
+    typedef typename strategy_distance
+        <
+            cs_tag,
+            cs_tag,
+            point_type,
+            point_type
+        >::type strategy_type;
+
+    return dispatch::length
+        <
+            typename tag<G>::type,
+            G,
+            strategy_type
+        >::apply(geometry, strategy_type());
+}
+
+/*!
+    \brief Calculate length of a geometry
+    \ingroup length
+    \details The function length returns the length of a geometry, using specified strategy
+    \param geometry the geometry, being a ggl::linestring, vector, iterator pair, or any other boost compatible range
+    \param strategy strategy to be used for distance calculations.
+    \return the length
+    \par Example:
+    Example showing length calculation using iterators and the Vincenty strategy
+    \dontinclude doxygen_examples.cpp
+    \skip example_length_linestring_iterators3
+    \line {
+    \until }
+ */
+template<typename G, typename S>
+inline double length(G const& geometry, S const& strategy)
+{
+    return dispatch::length<typename tag<G>::type, G, S>::apply(geometry, strategy);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_LENGTH_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/make.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/make.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,123 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_MAKE_HPP
+#define GGL_ALGORITHMS_MAKE_HPP
+
+#include <ggl/algorithms/assign.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief Make a geometry
+    \ingroup access
+    \details the Generic Geometry Library uses concepts for all its geometries. Therefore it does not rely
+    on constructors. The "make" functions are object generators creating geometries. There are overloads
+    with two, three, four or six values, which are implemented depending on the geometry specified.
+    \tparam G the geometry type
+    \tparam T the coordinate type
+    \return the geometry
+ */
+template <typename G, typename T>
+inline G make(T const& c1, T const& c2)
+{
+    G geometry;
+    dispatch::assign
+        <
+            typename tag<G>::type,
+            G,
+            ggl::dimension<G>::type::value
+        >::apply(geometry, c1, c2);
+    return geometry;
+}
+
+/*!
+    \brief Make a geometry
+    \ingroup access
+    \return a 3D point, a circle
+ */
+template <typename G, typename T>
+inline G make(T const& c1, T const& c2, T const& c3)
+{
+    G geometry;
+    dispatch::assign
+        <
+            typename tag<G>::type,
+            G,
+            ggl::dimension<G>::type::value
+        >::apply(geometry, c1, c2, c3);
+    return geometry;
+}
+
+template <typename G, typename T>
+inline G make(T const& c1, T const& c2, T const& c3, T const& c4)
+{
+    G geometry;
+    dispatch::assign
+        <
+            typename tag<G>::type,
+            G,
+            ggl::dimension<G>::type::value
+        >::apply(geometry, c1, c2, c3, c4);
+    return geometry;
+}
+
+
+
+template <typename G, typename R>
+inline G make(R const& range)
+{
+    G geometry;
+    append(geometry, range);
+    return geometry;
+}
+
+
+/*!
+    \brief Create a box with inverse infinite coordinates
+    \ingroup access
+    \details The make_inverse function initialize a 2D or 3D box with large coordinates, the
+    min corner is very large, the max corner is very small
+    \tparam G the geometry type
+    \return the box
+ */
+template <typename G>
+inline G make_inverse()
+{
+    G geometry;
+    dispatch::assign_inverse
+        <
+            typename tag<G>::type,
+            G
+        >::apply(geometry);
+    return geometry;
+}
+
+/*!
+    \brief Create a geometry with "zero" coordinates
+    \ingroup access
+    \details The make_zero function initializes a 2D or 3D point or box with coordinates of zero
+    \tparam G the geometry type
+    \return the geometry
+ */
+template <typename G>
+inline G make_zero()
+{
+    G geometry;
+    dispatch::assign_zero
+        <
+            typename tag<G>::type,
+            G
+        >::apply(geometry);
+    return geometry;
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_MAKE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/num_points.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/num_points.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,147 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_NUM_POINTS_HPP
+#define GGL_ALGORITHMS_NUM_POINTS_HPP
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/is_linear.hpp>
+#include <ggl/core/interior_rings.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace num_points {
+
+
+template <typename Range>
+struct range_count
+{
+    static inline std::size_t apply(Range const& range)
+    {
+        return boost::size(range);
+    }
+};
+
+template <typename Geometry, std::size_t D>
+struct other_count
+{
+    static inline std::size_t apply(Geometry const& geometry)
+    {
+        return D;
+    }
+};
+
+template <typename Polygon>
+struct polygon_count
+{
+    static inline std::size_t apply(Polygon const& poly)
+    {
+        std::size_t n = boost::size(exterior_ring(poly));
+        typedef typename boost::range_const_iterator
+            <
+                typename interior_type<Polygon>::type
+            >::type iterator;
+
+        for (iterator it = boost::begin(interior_rings(poly));
+             it != boost::end(interior_rings(poly));
+             ++it)
+        {
+            n += boost::size(*it);
+        }
+
+        return n;
+    }
+};
+
+}} // namespace detail::num_points
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename GeometryTag, bool Linear, typename Geometry>
+struct num_points
+{
+};
+
+template <typename GeometryTag, typename Geometry>
+struct num_points<GeometryTag, true, Geometry>
+        : detail::num_points::range_count<Geometry>
+{
+};
+
+template <typename Geometry>
+struct num_points<point_tag, false, Geometry>
+        : detail::num_points::other_count<Geometry, 1>
+{
+};
+
+template <typename Geometry>
+struct num_points<box_tag, false, Geometry>
+        : detail::num_points::other_count<Geometry, 4>
+{
+};
+
+template <typename Geometry>
+struct num_points<segment_tag, false, Geometry>
+        : detail::num_points::other_count<Geometry, 2>
+{
+};
+
+template <typename Geometry>
+struct num_points<nsphere_tag, false, Geometry>
+        : detail::num_points::other_count<Geometry, 1>
+{
+};
+
+template <typename Geometry>
+struct num_points<polygon_tag, false, Geometry>
+        : detail::num_points::polygon_count<Geometry>
+{
+};
+
+} // namespace dispatch
+#endif
+
+
+/*!
+    \brief get number of points
+    \ingroup access
+    \tparam Geometry geometry type
+    \param geometry the geometry to get number of points from
+    \return number of points
+    \note For linestrings/rings also boost::size or .size() could be used, however,
+        for polygons this is less obvious. So this function is provided. Besides that
+        it is described by OGC (numPoints)
+*/
+template <typename Geometry>
+inline std::size_t num_points(Geometry const& geometry)
+{
+    typedef typename boost::remove_const<Geometry>::type ncg_type;
+
+    return dispatch::num_points
+        <
+            typename tag<Geometry>::type,
+            is_linear<ncg_type>::value,
+            ncg_type
+        >::apply(geometry);
+}
+
+}
+
+
+#endif // GGL_ALGORITHMS_NUM_POINTS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlaps.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlaps.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,49 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_OVERLAPS_HPP
+#define GGL_ALGORITHMS_OVERLAPS_HPP
+
+#include <ggl/core/access.hpp>
+
+
+namespace ggl
+{
+
+/*!
+    \brief Determines overlap between two geometries
+    \details parameters are now boxes but in the future will be geometries
+    \ingroup boolean_relations
+    \return true if there is overlap
+
+
+    \par Source descriptions:
+    - Egenhofer: Two objects overlap if they have common interior faces and the bounding faces have common parts
+    with the opposite interior faces.
+
+    \note Implemented in scratch the Generic Geometry library. Will be reworked internally to support more geometries
+    but function call will stay as it is now.
+    \see http://docs.codehaus.org/display/GEOTDOC/02+Geometry+Relationships#02GeometryRelationships-Overlaps
+    where is stated that "inside" is not an "overlap", this is probably true and should then be implemented as such.
+
+ */
+template <typename B>
+inline bool overlaps(const B& b1, const B& b2)
+{
+    return !(
+            get<max_corner, 0>(b1) <= get<min_corner, 0>(b2) ||
+            get<min_corner, 0>(b1) >= get<max_corner, 0>(b2) ||
+            get<max_corner, 1>(b1) <= get<min_corner, 1>(b2) ||
+            get<min_corner, 1>(b1) >= get<max_corner, 1>(b2)
+            );
+
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_OVERLAPS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/adapt_turns.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/adapt_turns.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,556 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ADAPT_TURNS_HPP
+#define GGL_ADAPT_TURNS_HPP
+
+#include <algorithm>
+
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+#include <ggl/core/coordinate_type.hpp>
+
+#include <ggl/algorithms/equals.hpp>
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection {
+
+
+
+// TEMP: another COPY of side
+// TODO: solve this inside SIDE!!!
+template <typename P1, typename P2, typename P>
+inline int the_side(P1 const& p1, P2 const& p2, P const& p)
+{
+    typedef typename select_coordinate_type<P, P1>::type T;
+
+    T dx = get<0>(p2) - get<0>(p1);
+    T dy = get<1>(p2) - get<1>(p1);
+    T dpx = get<0>(p) - get<0>(p1);
+    T dpy = get<1>(p) - get<1>(p1);
+    T product =  dx * dpy - dy * dpx;
+    return product > 0 ? 1 : product < 0 ? -1 : 0;
+}
+
+template <typename T>
+inline void join_adapt(T& info, int direction)
+{
+    info.first->direction = direction;
+    info.second->direction = direction;
+}
+
+
+
+template <typename T>
+inline void both_same(T const& pi, T & pk, T const& qu, T& qw, int dir_p, int dir_q, int direction)
+{
+    // Comments are for "both Left"
+    if (dir_q == direction) // If (Qw left-of Qu)
+    {
+        if (dir_p == -direction) // if (Pk right-of Pi)
+        {
+            // make Pk Right, Qw Left
+            join_adapt(pk, -direction);
+            join_adapt(qw, direction);
+        }
+        else if (pk.first->direction == -direction) // else if (Pk right-of Qu)
+        {
+            // make both Right
+            join_adapt(pk, -direction);
+            join_adapt(qw, -direction);
+        }
+    }
+    else
+    {
+        if (dir_p == -direction // if (Pk right-of Pi
+            || pk.first->direction == direction) // || Pk left-of Qu)
+        {
+            //  make both Left
+            join_adapt(pk, direction);
+            join_adapt(qw, direction);
+        }
+    }
+}
+
+template <typename T>
+inline void crossing(T const& pi, T & pk, T const& qu, T& qw, int dir_p, int dir_q, int direction)
+{
+    if (dir_p == direction) // If (Pk left-of Pi)
+    {
+        if (pk.first->direction == -direction) // if (Pk right-of Qu)
+        {
+            // make both Right
+            join_adapt(pk, -direction);
+            join_adapt(qw, -direction);
+        }
+        else
+        {
+            // make Pk Left, Qw Right
+            join_adapt(pk, direction);
+            join_adapt(qw, -direction);
+        }
+    }
+}
+
+
+
+template <typename T>
+inline void collinear(T const& pi, T & pk, T const& qu, T& qw, int dir_p, int dir_q, int direction)
+{
+    if (dir_p == direction // If (Pk left-of Pi
+        && dir_q == direction // && Qw left-of Qu
+        && pk.first->direction == -direction) // && Pk right-of Qu
+    {
+        // make both Right
+        join_adapt(pk, -direction);
+        join_adapt(qw, -direction);
+    }
+    else if (dir_p == -direction // If (Pk right-of Pi
+        && dir_q == -direction) // && Qw right-of Qu
+    {
+        // make both Left
+        join_adapt(pk, direction);
+        join_adapt(qw, direction);
+    }
+
+}
+
+template <typename T, typename P>
+inline void assign_pq(T const& info, P& p, P& q)
+{
+    if (info.seg_id.source_index == 0)
+    {
+        if (info.arrival == 1)
+        {
+            p.first = info.other_point;
+        }
+        else if (info.arrival == -1)
+        {
+            p.second = info.other_point;
+        }
+    }
+    else
+    {
+        if (info.arrival == 1)
+        {
+            q.first = info.other_point;
+        }
+        else if (info.arrival == -1)
+        {
+            q.second = info.other_point;
+        }
+    }
+}
+
+template <typename Info, typename Point>
+inline void touch_in_the_middle(Info& info, Point const& point)
+{
+    typedef typename boost::range_iterator<Info>::type iterator;
+
+    // Determine which is Q, and assign points
+    iterator qu, qw, p;
+    int count = 0;
+
+    // Find out which one is arriving/departing from the middle
+    for (iterator it = boost::begin(info);
+        it != boost::end(info);
+        ++it)
+    {
+        // One arrives AND departs in the middle of the other.
+        if(it->how == 'm' && it->arrival == 1)
+        {
+            qu = it;
+            count |= 1;
+        }
+        else if(it->how == 's' && it->arrival == -1)
+        {
+            qw = it;
+            count |= 2;
+        }
+        else if (it->how == 's') //  or m, does not really matter
+        {
+            p = it;
+            count |= 4;
+        }
+
+    }
+    // Adapt it
+    if (count == 7
+        && qu->direction == qw->direction
+        && qu->seg_id.source_index == qw->seg_id.source_index)
+    {
+        int dir_q = the_side(qu->other_point, point, qw->other_point);
+
+#ifdef GGL_DEBUG_INTERSECTION
+        std::cout << "Both "
+            << (qu->direction == 1 ? "Left" : "Right")
+            << ", Turn " << (dir_q == 1 ? "Left" : dir_q == -1 ? "Right" : "?")
+            << std::endl;
+#endif
+
+        // Let P also be starting
+        p->arrival = -1;
+
+        // This is also symmetric. See slides:
+        // Qu left-of P && Qw left-of P
+        if (qu->direction == 1 && dir_q == -1)
+        {
+            // make both Left
+            p->direction = 1;
+            qw->direction = 1;
+        }
+        // else, symmetric version
+        else if (qu->direction == -1 && dir_q == 1)
+        {
+            p->direction = -1;
+            qw->direction = -1;
+        }
+    }
+}
+
+
+
+
+template <typename Info>
+inline void arrive_in_the_middle(Info& info)
+{
+    typedef typename boost::range_iterator<Info>::type iterator;
+
+    // Find out which one is NOT arriving in the middle,
+    // and the direction of the one arriving in the middle
+    int departing = -1;
+    int direction = 0;
+    for (iterator it = boost::begin(info);
+        it != boost::end(info);
+        ++it)
+    {
+        if(it->how == 'm')
+        {
+            switch(it->arrival)
+            {
+                case 1 : direction = it->direction; break;
+                default : departing = it->seg_id.source_index;
+            }
+        }
+    }
+
+    // Make this the departing one, following collinear in opposite segment,
+    // same direction as established above
+    for (iterator it = boost::begin(info);
+        it != boost::end(info);
+        ++it)
+    {
+        if (it->how == 'c' && it->seg_id.source_index == departing)
+        {
+            it->arrival = -1;
+            it->direction = direction;
+        }
+    }
+}
+
+template <typename Info>
+inline void start_in_the_middle(Info& info, bool opposite)
+{
+    typedef typename boost::range_iterator<Info>::type iterator;
+
+    for (iterator it = boost::begin(info);
+        it != boost::end(info);
+        ++it)
+    {
+        if(it->how == 's')
+        {
+            if (! opposite)
+            {
+                // Not opposite, all "start" traversals can also be made "departing"
+                it->arrival = -1;
+            }
+            else if (opposite && it->arrival == 0)
+            {
+                // Prevent the collinear the "start" from "departing",
+                // if it is in opposite direction
+                it->arrival = 1;
+                it->direction = 0;
+                it->flagged = true; // might be deleted
+            }
+        }
+    }
+}
+
+
+template <typename V>
+inline void adapt_turns(V& intersection_points)
+{
+    typedef typename boost::range_iterator<V>::type iterator_type;
+    typedef typename boost::range_value<V>::type ip_type;
+    typedef typename ip_type::traversal_type info_type;
+
+    typedef typename boost::range_value<V>::type::traversal_vector vector_type;
+    typedef typename boost::range_iterator<vector_type>::type tvit_type;
+
+    for (iterator_type it = boost::begin(intersection_points);
+         it != boost::end(intersection_points);
+         ++it)
+    {
+        if (! it->trivial)
+        {
+            if (boost::size(it->info) == 4)
+            {
+                /*
+                    can be ARRIVE/START from the middle (#11)
+                        src 0 seg 1 (// 1.0) how m[A R] p // qu
+                        src 0 seg 1 (// 1.1) how s[D L] p // qw
+                        src 1 seg 0 (// 0.1) how m[A R] qu / p
+                        src 1 seg 1 (// 0.1) how s[D R] qw / p
+
+                    or can be ARRIVE at COLLINEARITY (#8, #13)
+                        src 0 seg 1 (// 1.1) how m[A L] p // qu
+                        src 0 seg 1 (// 1.2) how c[- -] p // qw
+                        src 1 seg 1 (// 0.1) how m[A L] qu // p
+                        src 1 seg 2 (// 0.1) how c[- -] qw // p
+
+                    or can be START from COLLINEARITY (#8, #13)
+                        src 0 seg 1 (// 1.2) how c[- -] p // qu
+                        src 0 seg 1 (// 1.0) how s[D R] p // qw
+                        src 1 seg 2 (// 0.1) how c[- -] qu // p
+                        src 1 seg 0 (// 0.1) how s[D L] qw // p
+                */
+
+                 // First detect the case and if it is opposite
+                int count_m = 0, count_s = 0, count_c = 0;
+
+                bool opposite = false;
+                for (tvit_type tvit = boost::begin(it->info);
+                    tvit != boost::end(it->info);
+                    ++tvit)
+                {
+                    switch(tvit->how)
+                    {
+                        case 'm' : count_m++; break;
+                        case 's' : count_s++; break;
+                        case 'c' : count_c++; break;
+                    }
+                    if (tvit->opposite)
+                    {
+                        opposite = true;
+                    }
+                }
+
+
+                if (count_m == 2 && count_s == 2)
+                {
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "Touching the middle " << std::endl;
+#endif
+
+                    touch_in_the_middle(it->info, it->point);
+                }
+                else if (count_m == 2 && count_c == 2 && opposite)
+                {
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "Arriving the middle/collinearity, opposite" << std::endl;
+#endif
+
+                    arrive_in_the_middle(it->info);
+                }
+                else if (count_s == 2 && count_c == 2)
+                {
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "Starting from middle/collinearity"
+                        << (opposite ? " , opposite"  : "")
+                        << std::endl;
+#endif
+
+                    start_in_the_middle(it->info, opposite);
+                }
+            }
+
+            if (boost::size(it->info) == 8)
+            {
+                /*
+                  src 0 seg 1 (// 1.0) how t[A R]   pi // qu   pi.first
+                  src 0 seg 1 (// 1.1) how a[A R]   pi // qw   pi.second
+                  src 0 seg 2 (// 1.0) how a[D R]   pk // qu   pk.first
+                  src 0 seg 2 (// 1.1) how f[D L]   pk // qw   pk.second
+
+                  src 1 seg 0 (// 0.1) how t[A L]   qu // pi
+                  src 1 seg 0 (// 0.2) how a[A R]   qu // pk
+                  src 1 seg 1 (// 0.1) how a[D R]   qw // pi
+                  src 1 seg 1 (// 0.2) how f[D R]   qw // pk
+                */
+
+                std::pair<tvit_type, tvit_type> pi, pk, qu, qw;
+                std::pair<typename info_type::point_type, typename info_type::point_type> p, q;
+
+
+                // Find out which is which
+                for (tvit_type tvit = boost::begin(it->info);
+                    tvit != boost::end(it->info);
+                    ++tvit)
+                {
+                    assign_pq(*tvit, p, q);
+                    if (tvit->seg_id.source_index == 0)
+                    {
+                        if (tvit->arrival == 1)
+                        {
+                            if(tvit->how != 'a')
+                            {
+                                pi.first = tvit;
+                            }
+                            else
+                            {
+                                pi.second = tvit;
+                            }
+
+                        }
+                        else if (tvit->arrival == -1)
+                        {
+                            if (tvit->how == 'a')
+                            {
+                                pk.first = tvit;
+                            }
+                            else
+                            {
+                                pk.second = tvit;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        if (tvit->arrival == 1)
+                        {
+                            if(tvit->how != 'a')
+                            {
+                                qu.first = tvit;
+                            }
+                            else
+                            {
+                                qu.second = tvit;
+                            }
+                        }
+                        else if (tvit->arrival == -1)
+                        {
+                            if (tvit->how == 'a')
+                            {
+                                qw.first = tvit;
+                            }
+                            else
+                            {
+                                qw.second = tvit;
+                            }
+                        }
+                    }
+                }
+
+                int dir_p = the_side(p.first, it->point, p.second);
+                int dir_q = the_side(q.first, it->point, q.second);
+
+#ifdef GGL_DEBUG_INTERSECTION
+                std::cout << "Pi//Qu : " << *pi.first << std::endl;
+                std::cout << "Pi//Qw : " << *pi.second << std::endl;
+                std::cout << "Pk//Qu : " << *pk.first << std::endl;
+                std::cout << "Pk//Qw : " << *pk.second << std::endl;
+                std::cout << "Qu//Pi : " << *qu.first << std::endl;
+                std::cout << "Qu//Pk : " << *qu.second << std::endl;
+                std::cout << "Qw//Pi : " << *qw.first << std::endl;
+                std::cout << "Qw//Pk : " << *qw.second << std::endl;
+                if (dir_p == 1) std::cout << "P turns left" << std::endl;
+                if (dir_p == -1) std::cout << "P turns right" << std::endl;
+                if (dir_q == 1) std::cout << "Q turns left" << std::endl;
+                if (dir_q == -1) std::cout << "Q turns right" << std::endl;
+#endif
+
+                if (qu.first->direction == qw.first->direction)
+                {
+                    // Both Right or Both Left
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "Both "
+                        << (qu.first->direction == 1 ? "Left" : "Right")
+                        << std::endl;
+#endif
+
+                    both_same(pi, pk, qu, qw, dir_p, dir_q, qu.first->direction);
+                }
+                else if (qu.first->direction == -qw.first->direction)
+                {
+                    // From Left to Right, or from Right to Left
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "Left to/from Right" << std::endl;
+#endif
+                    crossing(pi, pk, qu, qw, dir_p, dir_q, qu.first->direction);
+                }
+                else if (qw.first->direction == 1 || qu.first->direction == 1)
+                {
+                    // Collinear left
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "Collinear left" << std::endl;
+#endif
+                    collinear(pi, pk, qu, qw, dir_p, dir_q, 1);
+                }
+                else if (qw.first->direction == -1 || qu.first->direction == -1)
+                {
+                    // Collinear right
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "Collinear right" << std::endl;
+#endif
+                    collinear(pi, pk, qu, qw, dir_p, dir_q, -1);
+                }
+
+
+                for (tvit_type tvit = boost::begin(it->info);
+                    tvit != boost::end(it->info);
+                    ++tvit)
+                {
+                    if (tvit->how == 'a')
+                    {
+                        tvit->direction = 0;
+                    }
+                }
+
+
+             }
+        }
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Adapted turns: " << std::endl;
+    report_ip(intersection_points);
+#endif
+}
+
+
+
+}} // namespace detail::intersection
+#endif //DOXYGEN_NO_DETAIL
+
+
+
+template <typename V>
+inline void adapt_turns(V& intersection_points)
+{
+    // If there are merges, there might be merged IP's which have right turns
+    detail::intersection::adapt_turns(intersection_points);
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Merged (2): " << std::endl;
+    report_ip(intersection_points);
+#endif
+
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ADAPT_TURNS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/copy_segments.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/copy_segments.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,211 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_OVERLAY_COPY_SEGMENTS_HPP
+#define GGL_ALGORITHMS_OVERLAY_COPY_SEGMENTS_HPP
+
+
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+
+#include <ggl/algorithms/overlay/intersection_point.hpp>
+
+#include <ggl/iterators/ever_circling_iterator.hpp>
+#include <ggl/iterators/point_const_iterator.hpp>
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace copy_segments {
+
+
+template <typename Ring, typename SegmentIdentifier, typename RangeOut>
+struct copy_segments_ring
+{
+    static inline void apply(Ring const& ring,
+            SegmentIdentifier const& seg_id, int to_index,
+            RangeOut& current_output)
+    {
+
+        typedef typename ggl::point_const_iterator<Ring>::type iterator;
+        typedef ggl::ever_circling_iterator<iterator> ec_iterator;
+
+        // The problem: sometimes we want to from "3" to "2" -> end = "3" -> end == begin
+        // This is not convenient with iterators.
+
+        // So we use the ever-circling iterator and determine when to step out
+
+        int from_index = seg_id.segment_index + 1;
+
+        // Sanity check
+        BOOST_ASSERT(from_index < boost::size(ring));
+
+        ec_iterator it(boost::begin(ring), boost::end(ring),
+                    boost::begin(ring) + from_index);
+
+        // [2..4] -> 4 - 2 + 1 = 3 -> {2,3,4} -> OK
+        // [4..2],size=6 -> 6 - 4 + 2 + 1 = 5 -> {4,5,0,1,2} -> OK
+        // [1..1], travel the whole ring round
+        int count = from_index <= to_index
+            ? to_index - from_index + 1
+            : boost::size(ring) - from_index + to_index + 1;
+
+        for (int i = 0; i < count; ++i, ++it)
+        {
+            // TODO: use 'copy coordinates' to handle different point types
+#ifdef GGL_DEBUG_INTERSECTION
+            std::cout << "  add: (" 
+                << ggl::get<0>(*it) << ", " << ggl::get<1>(*it) << ")" 
+                << std::endl;
+#endif
+            current_output.push_back(*it);
+        }
+    }
+};
+
+
+template <typename Polygon, typename SegmentIdentifier, typename RangeOut>
+struct copy_segments_polygon
+{
+    static inline void apply(Polygon const& polygon,
+            SegmentIdentifier const& seg_id, int to_index,
+            RangeOut& current_output)
+    {
+        // Call ring-version with the right ring
+        copy_segments_ring
+            <
+                typename ggl::ring_type<Polygon>::type,
+                SegmentIdentifier,
+                RangeOut
+            >::apply
+                (
+                    seg_id.ring_index < 0
+                    ? ggl::exterior_ring(polygon)
+                    : ggl::interior_rings(polygon)[seg_id.ring_index],
+                    seg_id, to_index, 
+                    current_output
+                );
+    }
+};
+
+
+template <typename Box, typename SegmentIdentifier, typename RangeOut>
+struct copy_segments_box
+{
+    static inline void apply(Box const& box,
+            SegmentIdentifier const& seg_id, int to_index,
+            RangeOut& current_output)
+    {
+        // Convert again...
+        // TODO: avoid that...
+
+        typedef typename point_type<Box>::type point_type;
+
+        point_type ll, lr, ul, ur;
+        assign_box_corners(box, ll, lr, ul, ur);
+
+        std::vector<point_type> points;
+        points.push_back(ll);
+        points.push_back(ul);
+        points.push_back(ur);
+        points.push_back(lr);
+        points.push_back(ll);
+
+        copy_segments_ring
+            <
+                std::vector<point_type>,
+                SegmentIdentifier,
+                RangeOut
+            >
+            ::apply(points, seg_id, to_index, current_output);
+    }
+};
+
+
+
+
+}} // namespace detail::copy_segments
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+
+template
+<
+    typename Tag,
+    typename GeometryIn,
+    typename SegmentIdentifier,
+    typename RangeOut
+>
+struct copy_segments
+{
+};
+
+
+template <typename Ring, typename SegmentIdentifier, typename RangeOut>
+struct copy_segments<ring_tag, Ring, SegmentIdentifier, RangeOut>
+    : detail::copy_segments::copy_segments_ring
+        <
+            Ring, SegmentIdentifier, RangeOut
+        >
+{};
+
+template <typename Polygon, typename SegmentIdentifier, typename RangeOut>
+struct copy_segments<polygon_tag, Polygon, SegmentIdentifier, RangeOut>
+    : detail::copy_segments::copy_segments_polygon
+        <
+            Polygon, SegmentIdentifier, RangeOut
+        >
+{};
+
+
+template <typename Box, typename SegmentIdentifier, typename RangeOut>
+struct copy_segments<box_tag, Box, SegmentIdentifier, RangeOut>
+    : detail::copy_segments::copy_segments_box
+        <
+            Box, SegmentIdentifier, RangeOut
+        >
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+
+
+/*!
+    \brief Traverses through intersection points / geometries
+    \ingroup overlay
+ */
+template<typename Geometry, typename SegmentIdentifier, typename RangeOut>
+inline void copy_segments(Geometry const& geometry,
+            SegmentIdentifier const& seg_id, int to_index,
+            RangeOut& range_out)
+{
+    dispatch::copy_segments
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            SegmentIdentifier,
+            RangeOut
+        >::apply(geometry, seg_id, to_index, range_out);
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_OVERLAY_COPY_SEGMENTS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/enrich_intersection_points.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/enrich_intersection_points.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,501 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_ENRICH_INTERSECTION_POINTS_HPP
+#define GGL_ALGORITHMS_ENRICH_INTERSECTION_POINTS_HPP
+
+#include <cstddef>
+#include <algorithm>
+#include <map>
+#include <vector>
+#ifdef GGL_DEBUG_INTERSECTION
+#include <iostream>
+#endif
+
+#include <boost/concept_check.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection {
+
+#ifdef GGL_DEBUG_INTERSECTION
+
+template <typename M>
+inline void report_map(M const& map)
+{
+    std::cout << "Map [source,segment(,ring,multi)] -> [count]:" << std::endl;
+    for (typename M::const_iterator it = map.begin(); it != map.end(); it++)
+    {
+        std::cout << "(" << it->first << ")"
+            << " -> " << "(" << it->second << ")" << std::endl;
+    }
+}
+
+
+template <typename V>
+inline void report_indexed(V const& index)
+{
+    typedef typename boost::range_const_iterator<V>::type iterator_type;
+
+    for (iterator_type it = boost::begin(index); it != boost::end(index); ++it)
+    {
+        std::cout << it->index << ": " << it->subject;
+    }
+}
+
+#endif // GGL_DEBUG_INTERSECTION
+
+
+template <typename T>
+struct indexed_source_segment
+{
+    std::size_t index;
+    T subject;
+
+    inline indexed_source_segment() {}
+
+    inline indexed_source_segment(std::size_t i, T const& s, segment_identifier const& seg_id)
+        : index(i)
+    {
+        s.clone_except_info(subject);
+
+        typedef typename T::traversal_vector vector_type;
+        for (typename boost::range_const_iterator<vector_type>::type it = s.info.begin();
+             it != s.info.end(); ++it)
+        {
+            // Copy info-record if belonging to source and to segment
+            if (it->seg_id == seg_id)
+            {
+                subject.info.push_back(*it);
+            }
+        }
+    }
+};
+
+
+template <typename T>
+struct indexed_source
+{
+    T subject;
+    std::size_t index;
+
+    inline indexed_source() {}
+
+    inline indexed_source(std::size_t i, T const& s,
+            int source_index, int multi_index, int ring_index)
+        : index(i)
+    {
+        s.clone_except_info(subject);
+
+        typedef typename T::traversal_vector vector_type;
+        for (typename boost::range_const_iterator<vector_type>::type it = s.info.begin();
+             it != s.info.end(); ++it)
+        {
+            // Copy info-record if belonging to source
+            if (it->seg_id.source_index == source_index
+                && it->seg_id.multi_index == multi_index
+                && it->seg_id.ring_index == ring_index)
+            {
+                subject.info.push_back(*it);
+            }
+        }
+    }
+};
+
+
+template <typename Indexed>
+struct sort_on_distance
+{
+    inline bool operator()(Indexed const& left, Indexed const& right) const
+    {
+        // Sanity check, there should be info-records because only those are copied
+        BOOST_ASSERT (left.subject.info.size() > 0 && right.subject.info.size() > 0);
+
+        return left.subject.info.front().distance < right.subject.info.front().distance;
+    }
+};
+
+// Sorts on segment + ring_index + multi_index
+template <typename Indexed>
+struct sort_on_segment_identifier
+{
+    inline bool operator()(Indexed const& left, Indexed const& right) const
+    {
+        // Sanity check
+        BOOST_ASSERT (left.subject.info.size() > 0 && right.subject.info.size() > 0);
+
+        segment_identifier const& sl = left.subject.info.front().seg_id;
+        segment_identifier const& sr = right.subject.info.front().seg_id;
+
+        return sl == sr
+            ? left.subject.info.front().distance < right.subject.info.front().distance
+            : sl < sr;
+    }
+};
+
+
+template <typename Info>
+struct on_source_segment_dir
+{
+    inline bool operator()(Info const& left, Info const& right) const
+    {
+        int ldir = left.direction;
+        int rdir = right.direction;
+        if (ldir == -1) ldir = 2;
+        if (rdir == -1) rdir = 2;
+
+
+        return left.seg_id.source_index == right.seg_id.source_index
+            ? (left.seg_id.segment_index == right.seg_id.segment_index
+                ? ldir < rdir
+                : left.seg_id.segment_index < right.seg_id.segment_index
+               )
+
+            : left.seg_id.source_index < right.seg_id.source_index;
+    }
+};
+
+
+
+
+
+// Assigns IP[index] . info[source/multi/ring/segment] . next_ip_index
+template <typename V>
+static inline void assign_next_ip_index(V& intersection_points, int index,
+            segment_identifier const& seg_id,
+            int next_ip_index)
+{
+    typedef typename boost::range_value<V>::type ip_type;
+    typedef typename ip_type::traversal_vector vector_type;
+    typedef typename boost::range_iterator<vector_type>::type iterator_type;
+
+    ip_type& ip = intersection_points[index];
+
+    for (iterator_type it = boost::begin(ip.info);
+            it != boost::end(ip.info);
+            ++it)
+    {
+        if (it->seg_id == seg_id)
+        {
+            it->next_ip_index = next_ip_index;
+            // Note: there can be MORE than one here. So do NOT return
+        }
+    }
+}
+
+
+// Assigns IP[index] . info[source_index] . travels_to_[vertex,ip]_index
+template <typename V>
+static inline void assign_last_vertex(V& intersection_points, int index,
+            int source_index,
+            int travels_to_vertex_index, int travels_to_ip_index)
+{
+    typedef typename boost::range_value<V>::type ip_type;
+    typedef typename ip_type::traversal_vector vector_type;
+    typedef typename boost::range_iterator<vector_type>::type iterator_type;
+
+    ip_type& ip = intersection_points[index];
+
+    for (iterator_type it = boost::begin(ip.info); it != boost::end(ip.info); ++it)
+    {
+        if (it->seg_id.source_index == source_index)
+        {
+            it->travels_to_vertex_index = travels_to_vertex_index;
+            it->travels_to_ip_index = travels_to_ip_index;
+            // do not return here, there can be more than one
+        }
+    }
+}
+
+
+// Creates selection of IP-s of only this unique source/segment,
+// then sorts on distance,
+// then assigns for each IP which is the next IP on this segment.
+// This is only applicable (but essential) for segments having
+// more than one IP on it. It is not the usual situation, so not
+// computational intensive.
+template <typename V>
+static inline bool assign_next_points(V& intersection_points,
+            segment_identifier const& seg_id)
+{
+    typedef typename boost::range_value<V>::type ip_type;
+    typedef typename boost::range_const_iterator<V>::type iterator_type;
+    typedef indexed_source_segment<ip_type> indexed_type;
+    typedef typename ip_type::traversal_vector vector_type;
+    typedef typename boost::range_const_iterator<vector_type>::type tvit_type;
+
+    // Create a copy of all IP's on this segment from this source
+
+    std::vector<indexed_type> copy;
+    copy.reserve(intersection_points.size());
+    std::size_t index = 0;
+    for (iterator_type it = boost::begin(intersection_points);
+         it != boost::end(intersection_points);
+         ++it, ++index)
+    {
+        bool to_be_copied = false;
+        for (tvit_type tvit = boost::begin(it->info);
+             !to_be_copied && tvit != boost::end(it->info);
+             ++tvit)
+        {
+            if (tvit->seg_id == seg_id)
+            {
+                to_be_copied = true;
+            }
+        }
+
+        if (to_be_copied)
+        {
+            // Copy this row, plus ONLY the related information
+            copy.push_back(indexed_type(index, *it, seg_id));
+        }
+    }
+
+    // Normally there are more elements in "copy".
+    // But in case of merges there could be only one.
+    if (boost::size(copy) <= 1)
+    {
+        return false;
+    }
+
+    std::sort(copy.begin(), copy.end(), sort_on_distance<indexed_type>());
+
+
+    // Now that it is sorted, do the main purpose: assign the next points
+    typedef typename boost::range_iterator
+        <
+            std::vector<indexed_type>
+        >::type indexed_iterator_type;
+
+    indexed_iterator_type it = boost::begin(copy);
+    for (indexed_iterator_type prev = it++; it != boost::end(copy); prev = it++)
+    {
+        for (
+#ifdef GGL_DEBUG_INTERSECTION
+        typename boost::range_iterator<vector_type>::type
+#else
+        tvit_type
+#endif
+            tvit = boost::begin(it->subject.info);
+             tvit != boost::end(it->subject.info);
+             ++tvit)
+        {
+            if (tvit->seg_id == seg_id)
+            {
+                assign_next_ip_index(intersection_points, prev->index, seg_id, it->index);
+
+#ifdef GGL_DEBUG_INTERSECTION
+                tvit->next_ip_index = it->index;
+#endif
+
+            }
+        }
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Enrichment - sorted (on distance, " << seg_id << "): " << std::endl;
+    report_indexed(copy);
+#endif
+
+    return true;
+}
+
+
+// If a segment has more than one IP, we determine what is the next IP
+// on that segment
+template <typename M, typename V>
+static inline bool assign_next_points(M& map, V& intersection_points)
+{
+    bool assigned = false;
+    for (typename M::iterator mit = map.begin(); mit != map.end(); ++mit)
+    {
+        // IF there are more IP's on this segment
+        if (mit->second > 1)
+        {
+            if (assign_next_points(intersection_points, mit->first))
+            {
+                assigned = true;
+            }
+        }
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Enrichment - assigned next points on same segment: " << std::endl;
+    report_ip(intersection_points);
+#endif
+
+    return assigned;
+}
+
+
+template <typename V>
+static inline bool assign_order(V& intersection_points,
+            int source_index, int multi_index, int ring_index)
+{
+    typedef typename boost::range_value<V>::type ip_type;
+    typedef typename boost::range_const_iterator<V>::type iterator_type;
+    typedef indexed_source<ip_type> indexed_type;
+    typedef typename ip_type::traversal_vector vector_type;
+    typedef typename boost::range_const_iterator<vector_type>::type tvit_type;
+
+    // Create a copy of all IP's from this source
+    std::vector<indexed_type> copy;
+    copy.reserve(intersection_points.size());
+    std::size_t index = 0;
+    for (iterator_type it = boost::begin(intersection_points);
+         it != boost::end(intersection_points);
+         ++it, ++index)
+    {
+        bool to_be_copied = false;
+        for (tvit_type tvit = boost::begin(it->info);
+             !to_be_copied && tvit != boost::end(it->info);
+             ++tvit)
+        {
+            if (tvit->seg_id.source_index == source_index
+                && tvit->seg_id.multi_index == multi_index
+                && tvit->seg_id.ring_index == ring_index)
+            {
+                to_be_copied = true;
+            }
+        }
+
+        if (to_be_copied)
+        {
+            // Copy this row, plus ONLY the related information
+            copy.push_back(indexed_type(index, *it, source_index, multi_index, ring_index));
+        }
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Enrichment - ordered/copy (on segment "
+        << " src: " << source_index
+        << "): " << std::endl;
+    report_indexed(copy);
+#endif
+
+    std::sort(copy.begin(), copy.end(), sort_on_segment_identifier<indexed_type>());
+
+    typedef typename boost::range_const_iterator<std::vector<indexed_type> >::type iit_type;
+
+    // Now that it is sorted, do the main purpose:
+    // assign travel-to-vertex/ip index for each IP
+    // Because IP's are circular, PREV starts at the very last one,
+    // being assigned from the first one.
+    iit_type it = boost::begin(copy);
+    for (iit_type prev = it + (boost::size(copy) - 1);
+         it != boost::end(copy);
+         prev = it++)
+    {
+        for (tvit_type tvit = boost::begin(it->subject.info);
+             tvit != boost::end(it->subject.info);
+             ++tvit)
+        {
+            if (tvit->seg_id.source_index == source_index
+                && tvit->seg_id.multi_index == multi_index
+                && tvit->seg_id.ring_index == ring_index)
+            {
+                assign_last_vertex(intersection_points, prev->index, source_index,
+                    tvit->seg_id.segment_index, it->index);
+            }
+        }
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Enrichment - ordered  on segment (src: "
+        << source_index << "): " << std::endl;
+    report_ip(intersection_points);
+#endif
+
+    return true;
+}
+
+template <typename M, typename V>
+static inline void assign_order(M const& map, V& intersection_points)
+{
+    typename M::const_iterator prev;
+    bool first = true;
+    for (typename M::const_iterator mit = map.begin(); mit != map.end(); ++mit)
+    {
+        if (first
+            || prev->first.source_index != mit->first.source_index
+            || prev->first.ring_index != mit->first.ring_index
+            || prev->first.multi_index != mit->first.multi_index)
+        {
+            assign_order(intersection_points, mit->first.source_index,
+                         mit->first.multi_index, mit->first.ring_index);
+            first = false;
+        }
+        prev = mit;
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Enrichment - assigned order: " << std::endl;
+    report_ip(intersection_points);
+#endif
+
+}
+
+
+
+
+}} // namespace detail::intersection
+#endif //DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief All intersection points are enriched with successor information
+    \ingroup overlay
+    \tparam IntersectionPoints type of intersection container (e.g. vector of "intersection_point"'s)
+    \param intersection_points container containing intersectionpoints
+    \param trivial Boolean flag to indicate that it is trivial, only intersections,
+        no touch, collinearities, etc.
+ */
+template <typename IntersectionPoints>
+inline void enrich_intersection_points(IntersectionPoints& intersection_points, bool trivial)
+{
+
+    // Create a map of segment<source_index,segment_index,ring_index,multi_index>
+    // to <number of IP's on this segment>
+    // Purpose: count IP's per source/segment, sort them lateron
+    std::map<segment_identifier, int> map;
+
+    typedef typename boost::range_const_iterator<IntersectionPoints>::type iterator_type;
+    for (iterator_type it = boost::begin(intersection_points);
+         it != boost::end(intersection_points);
+         ++it)
+    {
+        typedef typename boost::range_value
+            <
+                IntersectionPoints
+            >::type::traversal_vector vector_type;
+        typedef typename boost::range_const_iterator<vector_type>::type tvit_type;
+        for (tvit_type tvit = boost::begin(it->info);
+            tvit != boost::end(it->info);
+            ++tvit)
+        {
+            map[tvit->seg_id]++;
+        }
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    detail::intersection::report_map(map);
+#endif
+
+    detail::intersection::assign_next_points(map, intersection_points);
+
+    detail::intersection::assign_order(map, intersection_points);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_ENRICH_INTERSECTION_POINTS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/get_intersection_points.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/get_intersection_points.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,722 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_GET_INTERSECTION_POINTS_HPP
+#define GGL_ALGORITHMS_GET_INTERSECTION_POINTS_HPP
+
+#include <cstddef>
+
+#include <boost/mpl/if.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/is_multi.hpp>
+#include <ggl/core/reverse_dispatch.hpp>
+
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/ring_type.hpp>
+
+#include <ggl/util/math.hpp>
+
+#include <ggl/geometries/box.hpp>
+
+#include <ggl/strategies/cartesian/cart_intersect.hpp>
+#include <ggl/strategies/intersection_result.hpp>
+
+#include <ggl/policies/relate/intersection_points.hpp>
+#include <ggl/policies/relate/direction.hpp>
+#include <ggl/policies/relate/tupled.hpp>
+
+#include <ggl/algorithms/overlay/intersection_point.hpp>
+
+#include <ggl/algorithms/distance.hpp>
+#include <ggl/algorithms/disjoint.hpp>
+#include <ggl/algorithms/sectionalize.hpp>
+#include <ggl/algorithms/get_section.hpp>
+#include <ggl/algorithms/within.hpp>
+
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace get_intersection_points {
+
+
+template <typename Segment1, typename Segment2, typename IntersectionPoints>
+struct relate
+{
+    static inline bool apply(Segment1 const& s1, Segment2 const& s2,
+                segment_identifier const& seg_id1,
+                segment_identifier const& seg_id2,
+                IntersectionPoints& out, bool& trivial)
+    {
+
+        typedef typename boost::range_value
+            <
+                IntersectionPoints
+            >::type intersection_point;
+        typedef segment_intersection_points<intersection_point> ip_type;
+
+        typedef boost::tuple
+            <
+                ip_type,
+                policies::relate::direction_type
+            > result_type;
+
+        result_type result = strategy::intersection::relate_cartesian_segments
+            <
+                policies::relate::segments_tupled
+                    <
+                        policies::relate::segments_intersection_points
+                            <
+                                Segment1,
+                                Segment2,
+                                ip_type
+                            > ,
+                        policies::relate::segments_direction
+                            <
+                                Segment1,
+                                Segment2
+                            >
+                    >
+            >::relate(s1, s2);
+
+        ip_type& is = result.get<0>();
+        policies::relate::direction_type & dir = result.get<1>();
+
+        for (int i = 0; i < is.count; i++)
+        {
+            typedef typename point_type<Segment1>::type point1_type;
+            typedef typename cs_tag<point1_type>::type tag;
+
+            typename intersection_point::traversal_type info;
+
+            info.how = dir.how;
+            info.opposite = dir.opposite;
+
+            // First info-record, containing info about segment 1
+            info.seg_id = seg_id1;
+            info.other_id = seg_id2;
+            info.other_point = dir.how_a == 1 ? s1.first : s1.second;
+
+            info.distance = ggl::distance(is.intersections[i], s1.first);
+
+            //info.distance = dir.ra; // NOTE: not possible for collinear intersections!
+            info.arrival = dir.how_a;
+            info.direction = dir.dir_a;
+            is.intersections[i].info.push_back(info);
+
+
+            // Second info-record, containing info about segment 2
+            info.seg_id = seg_id2;
+            info.other_id = seg_id1;
+            info.other_point = dir.how_b == 1 ? s2.first : s2.second;
+
+            info.distance = ggl::distance(is.intersections[i], s2.first);
+            //info.distance = dir.rb;
+
+            info.arrival = dir.how_b;
+            info.direction = dir.dir_b;
+            is.intersections[i].info.push_back(info);
+
+            if (dir.how != 'i')
+            {
+                trivial = false;
+                is.intersections[i].trivial = false;
+            }
+
+            // Robustness: due to IEEE floating point errors, also in double, it might be
+            // that the IP is at the same location as s1.first/s1.second, and still
+            // being classified as an 'i' (normal intersection). Then handle it as non-trivial,
+            // such that the IP's will be merged lateron.
+
+            double eps = 1.0e-10;
+            if (dir.how == 'i'
+                && (dir.ra < eps
+                    || dir.rb < eps
+                    || 1.0 - dir.ra < eps
+                    || 1.0 - dir.rb <  eps
+                    )
+                )
+            {
+                // Handle them as non-trivial. This will case a "merge" lateron,
+                // which could be done anyway (because of other intersections)
+                // So it is never harmful to do this with a larger epsilon.
+                // However, it has to be handled (more) carefully lateron, in
+                // 'merge' or 'adapt_turns'
+                trivial = false;
+                is.intersections[i].trivial = false;
+
+
+#ifdef GGL_DEBUG_INTERSECTION
+                std::cout << "INTERSECTION suspicious: " << std::setprecision(20)
+                    << " ra: " << dir.ra
+                    << " rb: " << dir.rb
+                    << std::endl
+                    << " dist1: " << ggl::distance(is.intersections[i], s1.first)
+                    << " dist2: " << ggl::distance(is.intersections[i], s1.second)
+                    << std::endl;
+#endif
+            }
+
+            out.push_back(is.intersections[i]);
+        }
+        return is.count > 0;
+    }
+};
+
+template
+<
+    typename Geometry1, typename Geometry2,
+    typename Section1, typename Section2,
+    typename IntersectionPoints
+>
+class get_ips_in_sections
+{
+public :
+    static inline void apply(
+            std::size_t source_id1, Geometry1 const& geometry1,
+                Section1 const& sec1,
+            std::size_t source_id2, Geometry2 const& geometry2,
+                Section2 const& sec2,
+            bool return_if_found,
+            IntersectionPoints& intersection_points,
+            bool& trivial)
+    {
+
+        typedef typename ggl::point_const_iterator
+            <
+                Geometry1
+            >::type range1_iterator;
+        typedef typename ggl::point_const_iterator
+            <
+                Geometry2
+            >::type range2_iterator;
+
+        int const dir1 = sec1.directions[0];
+        int const dir2 = sec2.directions[0];
+        int index1 = sec1.begin_index;
+        int ndi1 = sec1.non_duplicate_index;
+
+        bool const same_source =
+            source_id1 == source_id2
+                    && sec1.multi_index == sec2.multi_index
+                    && sec1.ring_index == sec2.ring_index;
+
+        // Note that it is NOT possible to have section-iterators here
+        // because of the logistics of "index" (the section-iterator automatically
+        // skips to the begin-point, we loose the index or have to recalculate it)
+        // So we mimic it here
+        range1_iterator it1, end1;
+        get_section(geometry1, sec1, it1, end1);
+
+        // Mimic 1: Skip to point such that section interects other box
+        range1_iterator prev1 = it1++;
+        for(; it1 != end1 && preceding<0>(dir1, *it1, sec2.bounding_box);
+            prev1 = it1++, index1++, ndi1++)
+        {
+        }
+        // Go back one step because we want to start completely preceding
+        it1 = prev1;
+
+        // Walk through section and stop if we exceed the other box
+        for (prev1 = it1++;
+            it1 != end1 && ! exceeding<0>(dir1, *prev1, sec2.bounding_box);
+            prev1 = it1++, index1++, ndi1++)
+        {
+            segment1_type s1(*prev1, *it1);
+
+            int index2 = sec2.begin_index;
+            int ndi2 = sec2.non_duplicate_index;
+
+            range2_iterator it2, end2;
+            get_section(geometry2, sec2, it2, end2);
+
+            range2_iterator prev2 = it2++;
+
+            // Mimic 2:
+            for(; it2 != end2 && preceding<0>(dir2, *it2, sec1.bounding_box);
+                prev2 = it2++, index2++, ndi2++)
+            {
+            }
+            it2 = prev2;
+
+            for (prev2 = it2++;
+                it2 != end2 && ! exceeding<0>(dir2, *prev2, sec1.bounding_box);
+                prev2 = it2++, index2++, ndi2++)
+            {
+                bool skip = same_source;
+                if (skip)
+                {
+                    // If sources are the same (possibly self-intersecting):
+                    // check if it is a neighbouring sement.
+                    // (including first-last segment
+                    //  and two segments with one or more degenerate/duplicate
+                    //  (zero-length) segments in between)
+
+                    // Also skip if index1 < index2 to avoid getting all
+                    // intersections twice (only do this on same source!)
+
+                    // About n-2:
+                    //   (square: range_count=5, indices 0,1,2,3
+                    //    -> 0-3 are adjacent)
+                    skip = index2 >= index1
+                        || ndi1 == ndi2 + 1
+                        || (index2 == 0 && index1 >= int(sec1.range_count) - 2)
+                        ;
+                }
+
+                if (! skip)
+                {
+                    if (relate<segment1_type, segment2_type, IntersectionPoints>
+                        ::apply(s1, segment2_type(*prev2, *it2),
+                            segment_identifier(source_id1,
+                                        sec1.multi_index, sec1.ring_index, index1),
+                            segment_identifier(source_id2,
+                                        sec2.multi_index, sec2.ring_index, index2),
+                            intersection_points, trivial)
+                        && return_if_found)
+                    {
+                        return;
+                    }
+                }
+            }
+        }
+    }
+
+
+private :
+    typedef typename ggl::point_type<Geometry1>::type point1_type;
+    typedef typename ggl::point_type<Geometry2>::type point2_type;
+    typedef typename ggl::segment<const point1_type> segment1_type;
+    typedef typename ggl::segment<const point2_type> segment2_type;
+
+
+    template <size_t Dim, typename Point, typename Box>
+    static inline bool preceding(int dir, Point const& point, Box const& box)
+    {
+        return (dir == 1  && get<Dim>(point) < get<min_corner, Dim>(box))
+            || (dir == -1 && get<Dim>(point) > get<max_corner, Dim>(box));
+    }
+
+    template <size_t Dim, typename Point, typename Box>
+    static inline bool exceeding(int dir, Point const& point, Box const& box)
+    {
+        return (dir == 1  && get<Dim>(point) > get<max_corner, Dim>(box))
+            || (dir == -1 && get<Dim>(point) < get<min_corner, Dim>(box));
+    }
+
+
+};
+
+
+template
+<
+    typename Ring, typename Box,
+    typename Section1, typename Section2,
+    typename IntersectionPoints
+>
+class get_ips_range_box
+{
+public :
+    static inline void apply(
+            std::size_t source_id1, Ring const& ring,
+            std::size_t source_id2, Box const& box,
+            Section1 const& sec1, Section2 const& sec2,
+            IntersectionPoints& intersection_points, bool& trivial)
+    {
+        get_ips_in_sections<Ring, Box, Section1, Section2, IntersectionPoints>
+            ::apply(
+                source_id1, ring, sec1,
+                source_id2, box, sec2,
+                false,
+                intersection_points, trivial);
+    }
+};
+
+
+
+
+template<typename Geometry1, typename Geometry2, typename IntersectionPoints>
+struct get_ips_generic
+{
+    static inline bool apply(
+            std::size_t source_id1, Geometry1 const& geometry1,
+            std::size_t source_id2, Geometry2 const& geometry2,
+            IntersectionPoints& intersection_points)
+    {
+        // Create monotonic sections in ONE direction
+        // - in most cases ONE direction is faster (e.g. ~1% faster for the NLP4 testset)
+        // - the sections now have a limit (default 10) so will not be too large
+        typedef typename ggl::sections
+            <
+                ggl::box < typename ggl::point_type<Geometry1>::type >, 1
+            > sections1_type;
+        typedef typename ggl::sections
+            <
+                ggl::box < typename ggl::point_type<Geometry2>::type >, 1
+            > sections2_type;
+
+        sections1_type sec1;
+        sections2_type sec2;
+
+        ggl::sectionalize(geometry1, sec1);
+        ggl::sectionalize(geometry2, sec2);
+
+        bool trivial = true;
+        for (typename boost::range_const_iterator<sections1_type>::type
+                    it1 = sec1.begin();
+            it1 != sec1.end();
+            ++it1)
+        {
+            for (typename boost::range_const_iterator<sections2_type>::type
+                        it2 = sec2.begin();
+                it2 != sec2.end();
+                ++it2)
+            {
+                if (! ggl::disjoint(it1->bounding_box, it2->bounding_box))
+                {
+                    get_ips_in_sections
+                    <
+                        Geometry1,
+                        Geometry2,
+                        typename boost::range_value<sections1_type>::type,
+                        typename boost::range_value<sections2_type>::type,
+                        IntersectionPoints
+                    >::apply(
+                            source_id1, geometry1, *it1,
+                            source_id2, geometry2, *it2,
+                            false,
+                            intersection_points, trivial);
+                }
+            }
+        }
+        return trivial;
+    }
+};
+
+
+
+template<typename Range, typename Box, typename IntersectionPoints>
+struct get_ips_cs
+{
+    static inline void apply(std::size_t source_id1, Range const& range,
+            int multi_index, int ring_index,
+            std::size_t source_id2, Box const& box,
+            IntersectionPoints& intersection_points,
+            bool& trivial)
+    {
+        if (boost::size(range) <= 1)
+        {
+            return;
+        }
+
+
+        typedef typename ggl::point_type<Box>::type box_point_type;
+        typedef typename ggl::point_type<Range>::type point_type;
+
+        typedef segment<const box_point_type> box_segment_type;
+        typedef segment<const point_type> segment_type;
+
+        point_type lower_left, upper_left, lower_right, upper_right;
+        assign_box_corners(box, lower_left, lower_right, upper_left, upper_right);
+
+        box_segment_type left(lower_left, upper_left);
+        box_segment_type top(upper_left, upper_right);
+        box_segment_type right(upper_right, lower_right);
+        box_segment_type bottom(lower_right, lower_left);
+
+
+        typedef typename boost::range_const_iterator<Range>::type iterator_type;
+        iterator_type it = boost::begin(range);
+
+        bool first = true;
+
+        char previous_side[2] = {0, 0};
+
+        int index = 0;
+
+        for (iterator_type prev = it++;
+            it != boost::end(range);
+            prev = it++, index++)
+        {
+            segment_type segment(*prev, *it);
+
+            if (first)
+            {
+                previous_side[0] = get_side<0>(box, *prev);
+                previous_side[1] = get_side<1>(box, *prev);
+            }
+
+            char current_side[2];
+            current_side[0] = get_side<0>(box, *it);
+            current_side[1] = get_side<1>(box, *it);
+
+            // There can NOT be intersections if
+            // 1) EITHER the two points are lying on one side of the box (! 0 && the same)
+            // 2) OR same in Y-direction
+            // 3) OR all points are inside the box (0)
+            if (! (
+                (current_side[0] != 0 && current_side[0] == previous_side[0])
+                || (current_side[1] != 0 && current_side[1] == previous_side[1])
+                || (current_side[0] == 0
+                        && current_side[1] == 0
+                        && previous_side[0] == 0
+                        && previous_side[1] == 0)
+                  )
+                )
+            {
+                segment_identifier seg_id(source_id1,
+                            multi_index, ring_index, index);
+
+                typedef relate
+                    <
+                        segment_type, box_segment_type, IntersectionPoints
+                    > relater;
+
+                // Todo: depending on code some relations can be left out
+                relater::apply(segment, left, seg_id,
+                        segment_identifier(source_id2, -1, -1, 0),
+                        intersection_points, trivial);
+                relater::apply(segment, top, seg_id,
+                        segment_identifier(source_id2, -1, -1, 1),
+                        intersection_points, trivial);
+                relater::apply(segment, right, seg_id,
+                        segment_identifier(source_id2, -1, -1, 2),
+                        intersection_points, trivial);
+                relater::apply(segment, bottom, seg_id,
+                        segment_identifier(source_id2, -1, -1, 3),
+                        intersection_points, trivial);
+
+            }
+        }
+    }
+
+
+    template<std::size_t Index, typename Point>
+    static inline int get_side(Box const& box, Point const& point)
+    {
+        // Note: border has to be included because of boundary cases
+
+        if (get<Index>(point) <= get<min_corner, Index>(box)) return -1;
+        else if (get<Index>(point) >= get<max_corner, Index>(box)) return 1;
+        else return 0;
+    }
+
+
+};
+
+
+}} // namespace detail::get_intersection_points
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename GeometryTag1, typename GeometryTag2,
+    bool IsMulti1, bool IsMulti2,
+    typename Geometry1, typename Geometry2,
+    typename IntersectionPoints
+
+>
+struct get_intersection_points
+{
+};
+
+
+template<typename Polygon, typename Box, typename IntersectionPoints>
+struct get_intersection_points
+    <
+        polygon_tag, box_tag, false, false,
+        Polygon, Box,
+        IntersectionPoints
+    >
+{
+
+    static inline bool apply(
+            std::size_t source_id1, Polygon const& polygon,
+            std::size_t source_id2, Box const& box,
+            IntersectionPoints& intersection_points)
+    {
+        typedef typename ggl::ring_type<Polygon>::type ring_type;
+
+        typedef typename boost::range_const_iterator
+            <
+                typename interior_type<Polygon>::type
+            >::type iterator_type;
+
+
+        typedef detail::get_intersection_points::get_ips_cs
+            <ring_type, Box, IntersectionPoints> intersector_type;
+
+        bool trivial = true;
+        intersector_type::apply(
+                source_id1, ggl::exterior_ring(polygon), -1, -1,
+                source_id2, box,
+                intersection_points, trivial);
+
+        int i = 0;
+        for (iterator_type it = boost::begin(interior_rings(polygon));
+             it != boost::end(interior_rings(polygon));
+             ++it, ++i)
+        {
+            intersector_type::apply(
+                    source_id1, *it, -1, i,
+                    source_id2, box, intersection_points, trivial);
+        }
+
+        return trivial;
+    }
+};
+
+template<typename Ring1, typename Ring2, typename IntersectionPoints>
+struct get_intersection_points
+    <
+        ring_tag, ring_tag, false, false,
+        Ring1, Ring2,
+        IntersectionPoints
+    >
+    : detail::get_intersection_points::get_ips_generic
+        <
+            Ring1,
+            Ring2,
+            IntersectionPoints
+        >
+{};
+
+
+template<typename Polygon1, typename Polygon2, typename IntersectionPoints>
+struct get_intersection_points
+    <
+        polygon_tag, polygon_tag, false, false,
+        Polygon1, Polygon2,
+        IntersectionPoints
+    >
+    : detail::get_intersection_points::get_ips_generic
+        <
+            Polygon1,
+            Polygon2,
+            IntersectionPoints
+        >
+{};
+
+template
+<
+    typename LineString1,
+    typename LineString2,
+    typename IntersectionPoints
+>
+struct get_intersection_points
+    <
+        linestring_tag, linestring_tag, false, false,
+        LineString1, LineString2,
+        IntersectionPoints
+    >
+    : detail::get_intersection_points::get_ips_generic
+        <
+            LineString1,
+            LineString2,
+            IntersectionPoints
+        >
+{};
+
+template
+<
+    typename GeometryTag1, typename GeometryTag2,
+    bool IsMulti1, bool IsMulti2,
+    typename Geometry1, typename Geometry2,
+    typename IntersectionPoints
+>
+struct get_intersection_points_reversed
+{
+    static inline bool apply(
+            std::size_t source_id1, Geometry1 const& g1,
+            std::size_t source_id2, Geometry2 const& g2,
+            IntersectionPoints& intersection_points)
+    {
+        return get_intersection_points
+            <
+                GeometryTag2, GeometryTag1,
+                IsMulti2, IsMulti1,
+                Geometry2, Geometry1,
+                IntersectionPoints
+            >::apply(source_id2, g2, source_id1, g1, intersection_points);
+    }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+/*!
+    \brief Calculate intersection points of two geometries
+    \ingroup overlay
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \tparam IntersectionPoints type of intersection container (e.g. vector of "intersection_point"'s)
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \param intersection_points container which will contain intersection points
+    \return TRUE if it is trivial, else FALSE
+ */
+template <typename Geometry1, typename Geometry2, typename IntersectionPoints>
+inline bool get_intersection_points(Geometry1 const& geometry1,
+            Geometry2 const& geometry2, IntersectionPoints& intersection_points)
+{
+    assert_dimension_equal<Geometry1, Geometry2>();
+
+    typedef typename boost::remove_const<Geometry1>::type ncg1_type;
+    typedef typename boost::remove_const<Geometry2>::type ncg2_type;
+
+    return boost::mpl::if_c
+        <
+            reverse_dispatch<Geometry1, Geometry2>::type::value,
+            dispatch::get_intersection_points_reversed
+            <
+                typename tag<ncg1_type>::type,
+                typename tag<ncg2_type>::type,
+                is_multi<ncg1_type>::type::value,
+                is_multi<ncg2_type>::type::value,
+                ncg1_type,
+                ncg2_type,
+                IntersectionPoints
+            >,
+            dispatch::get_intersection_points
+            <
+                typename tag<ncg1_type>::type,
+                typename tag<ncg2_type>::type,
+                is_multi<ncg1_type>::type::value,
+                is_multi<ncg2_type>::type::value,
+                ncg1_type,
+                ncg2_type,
+               IntersectionPoints
+            >
+        >::type::apply(
+            0, geometry1,
+            1, geometry2,
+            intersection_points);
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_GET_INTERSECTION_POINTS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/intersection_point.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/intersection_point.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,255 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_INTERSECTION_POINT_HPP
+#define GGL_ALGORITHMS_INTERSECTION_POINT_HPP
+
+#include <vector>
+
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+
+#include <ggl/strategies/distance_result.hpp>
+#include <ggl/strategies/strategy_traits.hpp>
+
+#include <ggl/algorithms/overlay/segment_identifier.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection {
+
+
+template<typename P>
+struct intersection_info
+{
+    typedef P point_type;
+    typedef typename distance_result<P, P>::type distance_type;
+
+    inline intersection_info()
+        : travels_to_vertex_index(-1)
+        , travels_to_ip_index(-1)
+        , next_ip_index(-1)
+        , distance(ggl::make_distance_result<distance_type>(0))
+        , direction(0)
+        , how('?')
+        , arrival(0)
+        , opposite(false)
+        , visit_code(0)
+        , flagged(false)
+    {}
+
+    // Point to which the segment from IP is directing (TO-point)
+    // If they intersect on their "arrival" points, it is the FROM-point.
+    P other_point;
+
+    // Identifier of this segment (source,segment,ring,multi)
+    segment_identifier seg_id;
+
+    // Identify the segment where it was intersected with to form this IP
+    segment_identifier other_id;
+
+
+    // vertex to which is free travel after this IP,
+    // so from "segment_index+1" to "travels_to_vertex_index", without IP-s,
+    // can be -1
+    int travels_to_vertex_index;
+
+    // same but now IP index, so "next IP index" but not on THIS segment
+    int travels_to_ip_index;
+
+    // index of next IP on this segment, -1 if there is no one
+    int next_ip_index;
+
+    distance_type distance; // distance-measurement from segment.first to IP
+
+    // 1: left, -1: right, 0: collinear
+    int direction;
+
+    // Information about how intersection is done
+    char how;
+
+    // 1: arrived at IP, -1: departs from IP, 0: crosses IP
+    int arrival;
+
+    bool opposite;
+
+    int visit_code;
+
+    bool flagged; // flagged for deletion
+
+#ifdef GGL_DEBUG_INTERSECTION
+        static inline std::string dir(int d)
+        {
+            return d == 0 ? "-" : (d == 1 ? "L" : d == -1 ? "R" : "#");
+        }
+        static inline std::string how_str(int h)
+        {
+            return h == 0 ? "-" : (h == 1 ? "A" : "D");
+        }
+
+        friend std::ostream& operator<<(std::ostream &os, intersection_info<P> const& info)
+        {
+            os  << "\t"
+                << " src " << info.seg_id.source_index
+                << " seg " << info.seg_id.segment_index
+                << " (// " << info.other_id.source_index
+                    << "." << info.other_id.segment_index << ")"
+                << " how " << info.how
+                    << "[" << how_str(info.arrival)
+                    << " " << dir(info.direction)
+                    << (info.opposite ? " o" : "")
+                    << "]"
+                << " nxt seg " << info.travels_to_vertex_index
+                << " , ip " << info.travels_to_ip_index
+                << " , or " << info.next_ip_index
+                << " dst " << std::setprecision(12) << double(info.distance);
+            if (info.visit_code != 0)
+            {
+                os << " VIS: " << int(info.visit_code);
+            }
+            return os;
+        }
+#endif
+};
+
+
+template<typename P>
+struct intersection_point
+{
+    public :
+        inline intersection_point()
+            : visit_code(0) // VISIT_NONE
+            , trivial(true)
+            , shared(false)
+            , flagged(false)
+        {
+        }
+
+
+#ifdef GGL_DEBUG_INTERSECTION
+        friend std::ostream& operator<<(std::ostream &os, intersection_point<P> const& p)
+        {
+            os << "IP (" << ggl::get<0>(p.point) << "," << ggl::get<1>(p.point) << ")"
+                << " visited: " << int(p.visit_code)
+                << (p.shared ? " SHARED" : "")
+                << (p.flagged ? " FLAGGED" : "")
+                << std::endl;
+
+            for (unsigned int i = 0; i < p.info.size(); i++)
+            {
+                os << p.info[i] << std::endl;
+            }
+            return os;
+        }
+#endif
+        typedef intersection_info<P> traversal_type;
+        typedef std::vector<traversal_type> traversal_vector;
+
+        P point;
+
+        int visit_code;
+        bool trivial; // FALSE if there is an collinearity, touch or so.
+        bool shared; // shared with more IP's
+        bool flagged; // flagged for deletion afterwards
+
+        // info about the two intersecting segments
+        // usually two, but often more if IP's are merged
+        traversal_vector info;
+
+        inline void clone_except_info(intersection_point& other) const
+        {
+            other.point = point;
+            other.visit_code = visit_code;
+            other.trivial = trivial;
+            other.shared = shared;
+            other.flagged = flagged;
+        }
+};
+
+
+
+
+}} // namespace detail::intersection
+#endif //DOXYGEN_NO_DETAIL
+
+
+// Register the intersection point as being a point fulfilling the ggl Point Concept
+namespace traits
+{
+
+    template <typename P>
+    struct coordinate_type<ggl::detail::intersection::intersection_point<P> >
+    {
+        typedef typename ggl::coordinate_type<P>::type type;
+    };
+
+    template <typename P>
+    struct coordinate_system<ggl::detail::intersection::intersection_point<P> >
+    {
+        typedef typename ggl::coordinate_system<P>::type type;
+    };
+
+    template <typename P>
+    struct dimension<ggl::detail::intersection::intersection_point<P> >
+        : ggl::dimension<P>
+    {};
+
+    template <typename P>
+    struct tag<ggl::detail::intersection::intersection_point<P> >
+    {
+        typedef point_tag type;
+    };
+
+    template <typename P>
+    struct access<ggl::detail::intersection::intersection_point<P> >
+    {
+        template <int Index>
+        static inline typename coordinate_type<P>::type get(
+                ggl::detail::intersection::intersection_point<P> const& p)
+        {
+            return ggl::get<Index>(p.point);
+        }
+
+        template <int Index>
+        static inline void set(ggl::detail::intersection::intersection_point<P>& p,
+                typename coordinate_type<P>::type const& value)
+        {
+            ggl::set<Index>(p.point, value);
+        }
+    };
+
+}
+
+
+#ifdef GGL_DEBUG_INTERSECTION
+
+template <typename V>
+inline void report_ip(V const& intersection_points)
+{
+    typedef typename V::const_iterator iterator_type;
+
+    for (iterator_type it = intersection_points.begin();
+         it != intersection_points.end();
+         ++it)
+    {
+        if (! it->flagged)
+        {
+            std::cout << *it;
+        }
+    }
+}
+#endif // GGL_DEBUG_INTERSECTION
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_INTERSECTION_POINT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/merge_intersection_points.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/merge_intersection_points.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,254 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_MERGE_INTERSECTION_POINTS_HPP
+#define GGL_ALGORITHMS_MERGE_INTERSECTION_POINTS_HPP
+
+#include <algorithm>
+
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+#include <ggl/core/coordinate_type.hpp>
+
+#include <ggl/algorithms/equals.hpp>
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection {
+
+template <typename PointType>
+struct on_increasing_dimension
+{
+    typedef typename ggl::coordinate_type<PointType>::type coordinate_type;
+
+    inline bool operator()(PointType const& lhs, PointType const& rhs) const
+    {
+        coordinate_type const& left0 = ggl::get<0>(lhs);
+        coordinate_type const& right0 = ggl::get<0>(rhs);
+
+        return math::equals(left0, right0)
+            ? ggl::get<1>(lhs) < ggl::get<1>(rhs)
+            : left0 < right0;
+    }
+};
+
+
+
+// T can be an intersection_point or intersection_info record
+template <typename T>
+struct is_flagged
+{
+    inline bool operator()(T const& object) const
+    {
+        return object.flagged;
+    }
+};
+
+
+
+template <typename V>
+inline void remove_collinearities(V& intersection_points)
+{
+    typedef typename boost::range_iterator<V>::type iterator_type;
+    typedef typename boost::range_value<V>::type ip_type;
+    typedef typename ip_type::traversal_type info_type;
+
+
+    for (iterator_type it = boost::begin(intersection_points);
+         it != boost::end(intersection_points);
+         ++it)
+    {
+        if (! it->trivial && ! it->flagged)
+        {
+            // Remove anything having to do with collinearity
+            typedef typename boost::range_value<V>::type::traversal_vector vector_type;
+            typedef typename boost::range_iterator<vector_type>::type tvit_type;
+
+            bool has_flag = false;
+
+            // Note, this is done n*m, in case of collinearity, but it is only done if not trivial
+            // or if there
+            bool middle = false;
+            for (tvit_type tvit = boost::begin(it->info);
+                ! middle && tvit != boost::end(it->info);
+                ++tvit)
+            {
+                if (tvit->how == 'e' || tvit->how == 'c')
+                {
+                    tvit->flagged = true;
+                    has_flag = true;
+
+                    for (tvit_type tvit2 = boost::begin(it->info);
+                        tvit2 != boost::end(it->info); ++tvit2)
+                    {
+                        // Do NOT remove anything starting from collinear, or ending on, in the middle.
+                        if (tvit2->how != 'm' && tvit2->how != 's')
+                        {
+                            if (tvit->seg_id == tvit2->seg_id
+                                || tvit->seg_id == tvit2->other_id
+                                || tvit->other_id == tvit2->seg_id
+                                || tvit->other_id == tvit2->other_id
+                                )
+                            {
+                                tvit2->flagged = true;
+                            }
+                        }
+                        else
+                        {
+                            tvit->flagged = false;
+                            has_flag = false;
+                            middle = true;
+                        }
+                    }
+                }
+            }
+
+            if (has_flag)
+            {
+                it->info.erase(
+                    std::remove_if(
+                            boost::begin(it->info),
+                            boost::end(it->info),
+                            is_flagged<info_type>()),
+                    boost::end(it->info));
+
+                // Mark for deletion afterwards if there are no info-records left
+                if (boost::size(it->info) == 0)
+                {
+                    it->flagged = true;
+                }
+
+                // Cases, previously forming an 'angle' (test #19)
+                // will be normal (neutral) case now,
+                // so to continue traversal:
+                if (it->info.size() == 2
+                    && it->info.front().how == 'a'
+                    && it->info.back().how == 'a')
+                {
+                    it->info.front().direction = 1;
+                    it->info.back().direction = 1;
+                }
+            }
+        }
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Removed collinearities: " << std::endl;
+    report_ip(intersection_points);
+#endif
+}
+
+
+
+
+
+}} // namespace detail::intersection
+#endif //DOXYGEN_NO_DETAIL
+
+
+
+/*!
+    \brief Merges intersection points such that points at the same location will be merged, having one point
+        and their info-records appended
+    \ingroup overlay
+    \tparam IntersectionPoints type of intersection container (e.g. vector of "intersection_point"'s)
+    \param intersection_points container containing intersectionpoints
+ */
+template <typename IntersectionPoints>
+inline void merge_intersection_points(IntersectionPoints& intersection_points)
+{
+    typedef typename boost::range_value<IntersectionPoints>::type trav_type;
+
+    if (boost::size(intersection_points) <= 1)
+    {
+        return;
+    }
+
+
+    // Sort all IP's from left->right, ymin->ymax such that
+    // all same IP's are consecutive
+    // (and we need this order lateron again)
+    // This order is NOT changed here and should not be after
+    // (otherwise indexes are wrong)
+    std::sort(boost::begin(intersection_points),
+        boost::end(intersection_points),
+        detail::intersection::on_increasing_dimension<trav_type>());
+
+    typedef typename boost::range_iterator<IntersectionPoints>::type iterator;
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Sorted (x then y): " << std::endl;
+    for (iterator it = boost::begin(intersection_points);
+        it != boost::end(intersection_points); ++it)
+    {
+        std::cout << *it;
+    }
+#endif
+    bool has_merge = false;
+
+    // Merge all same IP's, combining there IP/segment-info entries
+    iterator it = boost::begin(intersection_points);
+    for (iterator prev = it++; it != boost::end(intersection_points); ++it)
+    {
+        // IP can be merged if the point is equal
+        if (ggl::equals(prev->point, it->point))
+        {
+            has_merge = true;
+            prev->shared = true;
+            prev->trivial = false;
+            it->flagged = true;
+            std::copy(it->info.begin(), it->info.end(),
+                        std::back_inserter(prev->info));
+        }
+        else
+        {
+            prev = it;
+        }
+    }
+
+
+    if (has_merge)
+    {
+#ifdef GGL_DEBUG_INTERSECTION
+        std::cout << "Merged (1): " << std::endl;
+        report_ip(intersection_points);
+#endif
+
+        // If there merges, there might be  collinearities
+        detail::intersection::remove_collinearities(intersection_points);
+
+        // Remove all IP's which are flagged for deletion
+        intersection_points.erase(
+            std::remove_if(
+                    boost::begin(intersection_points),
+                    boost::end(intersection_points),
+                    detail::intersection::is_flagged<trav_type>()),
+            boost::end(intersection_points));
+
+
+#ifdef GGL_DEBUG_INTERSECTION
+        std::cout << "Merged (2): " << std::endl;
+        report_ip(intersection_points);
+#endif
+
+
+    }
+
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_MERGE_INTERSECTION_POINTS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/segment_identifier.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/segment_identifier.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,86 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_OVERLAY_SEGMENT_IDENTIFIER_HPP
+#define GGL_ALGORITHMS_OVERLAY_SEGMENT_IDENTIFIER_HPP
+
+#include <vector>
+
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+
+#include <ggl/strategies/distance_result.hpp>
+#include <ggl/strategies/strategy_traits.hpp>
+
+namespace ggl
+{
+
+
+// Internal struct to uniquely identify a segment
+// on a linestring,ring
+// or polygon (needs ring_index)
+// or multi-geometry (needs multi_index)
+struct segment_identifier
+{
+    inline segment_identifier()
+        : source_index(-1)
+        , multi_index(-1)
+        , ring_index(-1)
+        , segment_index(-1)
+    {}
+
+    inline segment_identifier(int src, int mul, int rin, int seg)
+        : source_index(src)
+        , multi_index(mul)
+        , ring_index(rin)
+        , segment_index(seg)
+    {}
+
+    inline bool operator<(segment_identifier const& other) const
+    {
+        return source_index != other.source_index ? source_index < other.source_index
+            : multi_index !=other.multi_index ? multi_index < other.multi_index
+            : ring_index != other.ring_index ? ring_index < other.ring_index
+            : segment_index < other.segment_index
+            ;
+    }
+
+    inline bool operator==(segment_identifier const& other) const
+    {
+        return source_index == other.source_index
+            && segment_index == other.segment_index
+            && ring_index == other.ring_index
+            && multi_index == other.multi_index
+            ;
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    friend std::ostream& operator<<(std::ostream &os, segment_identifier const& seg_id)
+    {
+        std::cout
+            << "s:" << seg_id.source_index
+            << ", v:" << seg_id.segment_index // vertex
+            ;
+        if (seg_id.ring_index >= 0) std::cout << ", r:" << seg_id.ring_index;
+        if (seg_id.multi_index >= 0) std::cout << ", m:" << seg_id.multi_index;
+        return os;
+    }
+#endif
+
+    int source_index;
+    int multi_index;
+    int ring_index;
+    int segment_index;
+};
+
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_OVERLAY_SEGMENT_IDENTIFIER_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/self_intersection_points.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/self_intersection_points.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,167 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_SELF_INTERSECTION_POINTS_HPP
+#define GGL_ALGORITHMS_SELF_INTERSECTION_POINTS_HPP
+
+#include <cstddef>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/is_multi.hpp>
+
+#include <ggl/algorithms/overlay/get_intersection_points.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace self_intersection_points {
+
+template
+<
+    typename Geometry,
+    typename IntersectionPoints
+>
+struct check_ips
+{
+    static inline bool apply(
+            Geometry const& geometry,
+            bool return_if_found,
+            IntersectionPoints& intersection_points)
+    {
+        typedef typename ggl::sections
+            <
+                ggl::box < typename ggl::point_type<Geometry>::type >, 1
+            > sections_type;
+
+        sections_type sec;
+        ggl::sectionalize(geometry, sec);
+
+        bool trivial = true;
+        for (typename boost::range_const_iterator<sections_type>::type
+                    it1 = sec.begin();
+            it1 != sec.end();
+            ++it1)
+        {
+            for (typename boost::range_const_iterator<sections_type>::type
+                        it2 = sec.begin();
+                it2 != sec.end();
+                ++it2)
+            {
+                if (! ggl::disjoint(it1->bounding_box, it2->bounding_box)
+                    && ! it1->duplicate
+                    && ! it2->duplicate
+                    )
+                {
+                    ggl::detail::get_intersection_points::get_ips_in_sections
+                    <
+                        Geometry, Geometry,
+                        typename boost::range_value<sections_type>::type,
+                        typename boost::range_value<sections_type>::type,
+                        IntersectionPoints
+                    >::apply(
+                            0, geometry, *it1,
+                            0, geometry, *it2,
+                            return_if_found,
+                            intersection_points, trivial);
+                }
+            }
+        }
+        return trivial;
+    }
+};
+
+
+}} // namespace detail::self_intersection_points
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename GeometryTag,
+    bool IsMulti,
+    typename Geometry,
+    typename IntersectionPoints
+
+>
+struct self_intersection_points
+{
+};
+
+
+template<typename Ring, typename IntersectionPoints>
+struct self_intersection_points
+    <
+        ring_tag, false, Ring,
+        IntersectionPoints
+    >
+    : detail::self_intersection_points::check_ips
+        <
+            Ring,
+            IntersectionPoints
+        >
+{};
+
+
+template<typename Polygon, typename IntersectionPoints>
+struct self_intersection_points
+    <
+        polygon_tag, false, Polygon,
+        IntersectionPoints
+    >
+    : detail::self_intersection_points::check_ips
+        <
+            Polygon,
+            IntersectionPoints
+        >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Calculate self intersections of a geometry
+    \ingroup overlay
+    \tparam Geometry geometry type
+    \tparam IntersectionPoints type of intersection container (e.g. vector of "intersection_point"'s)
+    \param geometry geometry
+    \param intersection_points container which will contain intersection points
+    \return TRUE if it is trivial, else FALSE
+ */
+template <typename Geometry, typename IntersectionPoints>
+inline bool get_intersection_points(Geometry const& geometry,
+            IntersectionPoints& intersection_points)
+{
+    typedef typename boost::remove_const<Geometry>::type ncg_type;
+
+    return dispatch::self_intersection_points
+            <
+                typename tag<ncg_type>::type,
+                is_multi<ncg_type>::type::value,
+                ncg_type,
+               IntersectionPoints
+            >::apply(geometry, false, intersection_points);
+}
+
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_SELF_INTERSECTION_POINTS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/traverse.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/overlay/traverse.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,437 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_OVERLAY_TRAVERSE_HPP
+#define GGL_ALGORITHMS_OVERLAY_TRAVERSE_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+
+#include <ggl/algorithms/overlay/copy_segments.hpp>
+
+#ifdef GGL_DEBUG_INTERSECTION
+#include <ggl/extensions/gis/io/wkt/write_wkt.hpp>
+#endif
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection {
+
+
+const int VISIT_NONE = 0;
+const int VISIT_START = 1;
+const int VISIT_VISITED = 2;
+const int VISIT_FINISH = 3;
+const int VISIT_WITHIN = 4;
+
+
+template
+<
+    typename IntersectionPoint,
+    typename IntersectionInfo
+>
+struct on_direction
+{
+    on_direction(IntersectionPoint const& ip, int direction)
+        : m_ip(ip)
+        , m_direction(direction)
+    {}
+
+    // TEMP: convenient COPY of side
+    template <typename P1, typename P2, typename P>
+    static inline int side(P1 const& p1, P2 const& p2, P const& p)
+    {
+        typedef typename select_coordinate_type<P, P1>::type T;
+
+        T dx = get<0>(p2) - get<0>(p1);
+        T dy = get<1>(p2) - get<1>(p1);
+        T dpx = get<0>(p) - get<0>(p1);
+        T dpy = get<1>(p) - get<1>(p1);
+        T product =  dx * dpy - dy * dpx;
+        return product > 0 ? 1 : product < 0 ? -1 : 0;
+    }
+
+    inline bool operator()(IntersectionInfo const& first, IntersectionInfo const& second) const
+    {
+        int dir = side(m_ip, first->other_point, second->other_point);
+        return m_direction == dir;
+    }
+
+private :
+    IntersectionPoint const& m_ip;
+    int m_direction;
+};
+
+
+template
+<
+    typename GeometryOut,
+    typename G1,
+    typename G2,
+    typename IntersectionPoints,
+    typename IntersectionInfo
+>
+inline bool assign_next_ip(G1 const& g1, G2 const& g2, int direction,
+            IntersectionPoints& intersection_points,
+            typename boost::range_iterator<IntersectionPoints>::type & ip,
+            GeometryOut& current_output,
+            IntersectionInfo & info)
+{
+    info.visit_code = VISIT_VISITED;
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << " take: " << info << std::endl;
+#endif
+
+    // If there is no next IP on this segment
+    if (info.next_ip_index < 0)
+    {
+        if (info.seg_id.source_index == 0)
+        {
+            ggl::copy_segments(g1, info.seg_id,
+                    info.travels_to_vertex_index,
+                    current_output);
+        }
+        else
+        {
+            ggl::copy_segments(g2, info.seg_id,
+                    info.travels_to_vertex_index,
+                    current_output);
+        }
+        ip = boost::begin(intersection_points) + info.travels_to_ip_index;
+    }
+    else
+    {
+        ip = boost::begin(intersection_points) + info.next_ip_index;
+    }
+    current_output.push_back(ip->point);
+
+    return true;
+}
+
+template <typename Info>
+inline bool turning(Info const& info, int direction)
+{
+    // If it is turning in specified direction (RIGHT for intersection,
+    // LEFT for union, and NOT arriving at that point
+    return info.direction == direction
+        && info.arrival != 1
+        //&& (! (info.how == 'a' && info.direction != 0))
+        ;
+}
+
+template
+<
+    typename GeometryOut,
+    typename G1,
+    typename G2,
+    typename IntersectionPoints
+>
+inline bool select_next_ip_trivial(G1 const& g1, G2 const& g2, int direction,
+            IntersectionPoints& intersection_points,
+            typename boost::range_iterator<IntersectionPoints>::type & ip,
+            GeometryOut& current_output)
+{
+    // Check all intersecting segments on this IP:
+    typedef typename boost::range_value<IntersectionPoints>::type ip_type;
+    typedef typename ip_type::traversal_vector tv;
+    typedef typename boost::range_iterator<tv>::type tit_type;
+
+    for (tit_type it = boost::begin(ip->info); it != boost::end(ip->info); ++it)
+    {
+        if (turning(*it, direction))
+        {
+            return assign_next_ip(g1, g2, direction,
+                        intersection_points, ip, current_output, *it);
+        }
+    }
+
+    return false;
+}
+
+
+template
+<
+    typename GeometryOut,
+    typename G1,
+    typename G2,
+    typename IntersectionPoints
+>
+inline bool select_next_ip_with_sorting(G1 const& g1, G2 const& g2,
+            int direction,
+            IntersectionPoints& intersection_points,
+            typename boost::range_iterator<IntersectionPoints>::type & ip,
+            GeometryOut& current_output)
+{
+
+    typedef typename boost::range_value<IntersectionPoints>::type ip_type;
+    typedef typename ip_type::traversal_vector tv;
+    typedef typename boost::range_iterator<tv>::type tit_type;
+    typedef typename ip_type::traversal_type info_type;
+
+    std::vector<info_type*> info;
+    for (tit_type it = boost::begin(ip->info); it != boost::end(ip->info); ++it)
+    {
+        if (turning(*it, direction))
+        {
+            info.push_back(&(*it));
+        }
+    }
+
+    // If there are no intersection points, fall-back to collinear cases or
+    // if already in that case, return false.
+    if (boost::size(info) == 0)
+    {
+        return direction == 0
+            ? false
+            : select_next_ip_with_sorting(g1, g2, 0,
+                            intersection_points, ip, current_output);
+    }
+
+    // For one IP, it is easy: take that one.
+    if (boost::size(info) == 1)
+    {
+        return assign_next_ip(g1, g2, direction,
+                    intersection_points, ip, current_output, *info.front());
+    }
+
+    // In case of direction 0, also take first one
+    // TODO: sort this vector somehow, there are more rows, it is too
+    // arbitrary to take first one (though working well)
+    if (direction == 0)
+    {
+        return assign_next_ip(g1, g2, direction,
+                    intersection_points, ip, current_output, *info.front());
+    }
+
+
+    // For more, sort the information on direction, take the most left / right one
+    //std::cout << " " << boost::size(info);
+    std::sort(info.begin(), info.end(), on_direction<ip_type, info_type*>(*ip, direction));
+    return assign_next_ip(g1, g2, direction, intersection_points, ip, current_output, *info.back());
+}
+
+template
+<
+    typename GeometryOut,
+    typename G1,
+    typename G2,
+    typename IntersectionPoints
+>
+inline bool select_next_ip(G1 const& g1, G2 const& g2, int direction,
+            IntersectionPoints& intersection_points,
+            typename boost::range_iterator<IntersectionPoints>::type & ip,
+            GeometryOut& current_output)
+{
+    if (ip->trivial)
+    {
+        return select_next_ip_trivial(g1, g2, direction, intersection_points,
+                ip, current_output);
+    }
+    else
+    {
+        return select_next_ip_with_sorting(g1, g2, direction, intersection_points,
+                ip, current_output);
+    }
+}
+
+
+template<typename IntersectionPoint>
+inline bool is_starting_point(IntersectionPoint const& ip, int direction)
+{
+    for (typename IntersectionPoint::traversal_vector::const_iterator it
+        = boost::begin(ip.info); it != boost::end(ip.info); ++it)
+    {
+        if (it->direction == direction
+            && it->arrival != 1)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+
+template <typename Container>
+inline void stop_gracefully(Container& container, bool& stop,
+            std::string const& reason)
+{
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "STOPPING: " << reason << std::endl;
+#endif
+
+    stop = true;
+    if (container.size() > 0)
+    {
+        container.push_back(container.front());
+    }
+}
+
+}} // namespace detail::intersection
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+
+
+
+/*!
+    \brief Traverses through intersection points / geometries
+    \ingroup overlay
+ */
+template
+<
+    typename GeometryOut,
+    typename Geometry1,
+    typename Geometry2,
+    typename IntersectionPoints,
+    typename OutputIterator
+>
+inline void traverse(Geometry1 const& geometry1,
+            Geometry2 const& geometry2, int direction,
+            IntersectionPoints& intersection_points,
+            bool trivial,
+            OutputIterator out)
+{
+    typedef typename boost::range_iterator
+                <IntersectionPoints>::type ip_iterator;
+
+    typedef typename boost::range_value<IntersectionPoints>::type ip_type;
+    typedef typename ip_type::traversal_vector tv;
+    typedef typename boost::range_iterator<tv>::type tit_type;
+    typedef typename ip_type::traversal_type info_type;
+
+
+
+    GeometryOut current_output;
+
+
+    // Iterate through all unvisited points
+    for (ip_iterator it = boost::begin(intersection_points);
+        it != boost::end(intersection_points);
+        ++it)
+    {
+#ifdef GGL_DEBUG_INTERSECTION
+        std::cout << "TRY traversal: " << *it;
+#endif
+
+        if (it->visit_code == detail::intersection::VISIT_NONE
+            // UNION may operate on non-starting points, but INTERSECTION may not.
+            // TODO: re-evaluate that
+            && (direction == 1
+            || detail::intersection::is_starting_point(*it, direction)
+                )
+            )
+        {
+            for (tit_type iit = boost::begin(it->info);
+                iit != boost::end(it->info);
+                ++iit)
+            {
+                if (iit->arrival == -1
+                    && iit->visit_code == detail::intersection::VISIT_NONE
+                    && iit->direction == direction)
+                {
+                    it->visit_code = detail::intersection::VISIT_START;
+                    iit->visit_code = detail::intersection::VISIT_START;
+
+                    current_output.push_back(it->point);
+
+                    ip_iterator current = it;
+
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "START traversal: " << *current;
+#endif
+
+                    detail::intersection::assign_next_ip(geometry1, geometry2,
+                                direction,
+                                intersection_points,
+                                current, current_output, *iit);
+
+                    std::vector<segment_identifier> segments;
+                    segments.push_back(iit->seg_id);
+
+                    unsigned int i = 0;
+                    bool stop = false;
+
+                    while (current != it && ! stop)
+                    {
+#ifdef GGL_DEBUG_INTERSECTION
+                        std::cout << "traverse: " << *current;
+#endif
+
+                        // We assume clockwise polygons only, non self-intersecting, closed.
+                        // However, the input might be different, and checking validity
+                        // is up to the library user.
+
+                        // Therefore we make here some sanity checks. If the input
+                        // violates the assumptions, the output polygon will not be correct
+                        // but the routine will stop and output the current polygon, and
+                        // will continue with the next one.
+
+                        // Below three reasons to stop.
+                        if (! detail::intersection::select_next_ip(geometry1,
+                                    geometry2, direction,
+                                    intersection_points,
+                                    current, current_output))
+                        {
+                            // Should not occur in valid (non-self-intersecting) polygons
+                            // Should not occur in self-intersecting polygons without spikes
+                            // Might occur in polygons with spikes
+                            detail::intersection::stop_gracefully(
+                                current_output, stop, "Dead end");
+                        }
+
+                        if (current->visit_code == detail::intersection::VISIT_VISITED)
+                        {
+                            // It visits a visited node again, without passing the start node.
+                            // This makes it suspicious for endless loops
+                            // Check if it is really same node
+                            detail::intersection::stop_gracefully(
+                                current_output, stop, "Visit again");
+                        }
+
+
+                        if (i++ > intersection_points.size())
+                        {
+                            // Sanity check: there may be never more loops
+                            // than intersection points.
+                            detail::intersection::stop_gracefully(
+                                current_output, stop, "Endless loop");
+                        }
+
+                        current->visit_code = detail::intersection::VISIT_VISITED;
+                    }
+
+                    iit->visit_code = detail::intersection::VISIT_FINISH;
+
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "finish: " << *current;
+                    std::cout << ggl::wkt(current_output) << std::endl;
+#endif
+
+                    *out = current_output;
+                    ++out;
+                    current_output.clear();
+                }
+            }
+            it->visit_code = detail::intersection::VISIT_FINISH;
+        }
+    }
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_OVERLAY_TRAVERSE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/perimeter.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/perimeter.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,141 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_PERIMETER_HPP
+#define GGL_ALGORITHMS_PERIMETER_HPP
+
+#include <cmath>
+#include <iterator>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/length.hpp>
+#include <ggl/core/cs.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/strategies/strategies.hpp>
+
+/*!
+\defgroup perimeter perimeter calculation
+The perimeter algorithm is implemented for polygon,box,linear_ring,multi_polygon
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace perimeter {
+
+template<typename R, typename S>
+struct range_perimeter : detail::length::range_length<R, S>
+{
+};
+
+// might be merged with "range_area" with policy to sum/subtract interior rings
+template<typename Polygon, typename S>
+struct polygon_perimeter
+{
+    static inline double apply(Polygon const& poly, S const& strategy)
+    {
+        typedef typename ring_type<Polygon>::type ring_type;
+        typedef typename boost::range_const_iterator
+            <
+            typename interior_type<Polygon>::type
+            >::type iterator_type;
+
+        double sum = std::abs(range_perimeter<ring_type, S>::apply(exterior_ring(poly), strategy));
+
+        for (iterator_type it = boost::begin(interior_rings(poly));
+             it != boost::end(interior_rings(poly)); it++)
+        {
+            sum += std::abs(range_perimeter<ring_type, S>::apply(*it, strategy));
+        }
+        return sum;
+    }
+};
+
+}} // namespace detail:;perimeter
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// Default perimeter is 0.0, specializations implement calculated values
+template <typename Tag, typename Geometry, typename Strategy>
+struct perimeter : detail::calculate_null<double, Geometry, Strategy>
+{};
+
+template <typename Geometry, typename Strategy>
+struct perimeter<ring_tag, Geometry, Strategy>
+    : detail::perimeter::range_perimeter<Geometry, Strategy>
+{};
+
+template <typename Geometry, typename Strategy>
+struct perimeter<polygon_tag, Geometry, Strategy>
+    : detail::perimeter::polygon_perimeter<Geometry, Strategy>
+{};
+
+
+// box,n-sphere: to be implemented
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Calculate perimeter of a geometry
+    \ingroup perimeter
+    \details The function perimeter returns the perimeter of a geometry, using the default distance-calculation-strategy
+    \param geometry the geometry, be it a ggl::ring, vector, iterator pair, or any other boost compatible range
+    \return the perimeter
+ */
+template<typename Geometry>
+inline double perimeter(Geometry const& geometry)
+{
+    typedef typename point_type<Geometry>::type point_type;
+    typedef typename cs_tag<point_type>::type cs_tag;
+    typedef typename strategy_distance
+        <
+            cs_tag,
+            cs_tag,
+            point_type,
+            point_type
+        >::type strategy_type;
+
+    return dispatch::perimeter
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            strategy_type
+        >::apply(geometry, strategy_type());
+}
+
+/*!
+    \brief Calculate perimeter of a geometry
+    \ingroup perimeter
+    \details The function perimeter returns the perimeter of a geometry, using specified strategy
+    \param geometry the geometry, be it a ggl::ring, vector, iterator pair, or any other boost compatible range
+    \param strategy strategy to be used for distance calculations.
+    \return the perimeter
+ */
+template<typename Geometry, typename Strategy>
+inline double perimeter(Geometry const& geometry, Strategy const& strategy)
+{
+    return dispatch::perimeter
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            Strategy
+        >::apply(geometry, strategy);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_PERIMETER_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/sectionalize.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/sectionalize.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,579 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_SECTIONALIZE_HPP
+#define GGL_ALGORITHMS_SECTIONALIZE_HPP
+
+#include <cstddef>
+#include <vector>
+
+#include <boost/concept_check.hpp>
+#include <boost/concept/requires.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/assign.hpp>
+#include <ggl/algorithms/combine.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/exterior_ring.hpp>
+
+#include <ggl/iterators/point_const_iterator.hpp>
+
+#include <ggl/util/assign_box_corner.hpp>
+#include <ggl/util/math.hpp>
+#include <ggl/geometries/segment.hpp>
+
+
+/*!
+\defgroup sectionalize sectionalize: split a geometry (polygon, linestring, etc)
+    into monotonic sections
+
+\par Geometries:
+- LINESTRING:
+- RING:
+- POLYGON:
+- BOX
+*/
+
+namespace ggl
+{
+
+
+/*!
+    \brief Structure containing section information
+    \details Section information consists of a bounding box, direction
+        information (if it is increasing or decreasing, per dimension),
+        index information (begin-end, ring, multi) and the number of
+        segments in this section
+
+    \tparam Box box-type
+    \tparam DimensionCount number of dimensions for this section
+    \ingroup sectionalize
+ */
+template <typename Box, std::size_t DimensionCount>
+struct section
+{
+    typedef Box box_type;
+
+    int directions[DimensionCount];
+    int ring_index;
+    int multi_index;
+    Box bounding_box;
+
+    int begin_index;
+    int end_index;
+    std::size_t count;
+    std::size_t range_count;
+    bool duplicate;
+    int non_duplicate_index;
+
+
+    inline section()
+        : ring_index(-99)
+        , multi_index(-99)
+        , begin_index(-1)
+        , end_index(-1)
+        , count(0)
+        , range_count(0)
+        , duplicate(false)
+        , non_duplicate_index(-1)
+    {
+        assign_inverse(bounding_box);
+        for (register std::size_t i = 0; i < DimensionCount; i++)
+        {
+            directions[i] = 0;
+        }
+    }
+};
+
+
+/*!
+    \brief Structure containing a collection of sections
+    \note Derived from a vector, proves to be faster than of deque
+    \note vector might be templated in the future
+    \ingroup sectionalize
+ */
+template <typename Box, std::size_t DimensionCount>
+struct sections : std::vector<section<Box, DimensionCount> >
+{
+    typedef Box box_type;
+    static const std::size_t value = DimensionCount;
+};
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace sectionalize {
+
+template <typename Segment, std::size_t Dimension, std::size_t DimensionCount>
+struct get_direction_loop
+{
+    typedef typename coordinate_type<Segment>::type coordinate_type;
+
+    static inline void apply(Segment const& seg,
+                int directions[DimensionCount])
+    {
+        coordinate_type const diff =
+            ggl::get<1, Dimension>(seg) - ggl::get<0, Dimension>(seg);
+
+        directions[Dimension] = diff > 0 ? 1 : (diff < 0 ? -1 : 0);
+
+        get_direction_loop
+            <
+                Segment, Dimension + 1, DimensionCount
+            >::apply(seg, directions);
+    }
+};
+
+template <typename Segment, std::size_t DimensionCount>
+struct get_direction_loop<Segment, DimensionCount, DimensionCount>
+{
+    static inline void apply(Segment const& seg,
+                int directions[DimensionCount])
+    {
+        boost::ignore_unused_variable_warning(seg);
+        boost::ignore_unused_variable_warning(directions);
+    }
+};
+
+template <typename T, std::size_t Dimension, std::size_t DimensionCount>
+struct copy_loop
+{
+    static inline void apply(const T source[DimensionCount],
+                T target[DimensionCount])
+    {
+        target[Dimension] = source[Dimension];
+        copy_loop<T, Dimension + 1, DimensionCount>::apply(source, target);
+    }
+};
+
+template <typename T, std::size_t DimensionCount>
+struct copy_loop<T, DimensionCount, DimensionCount>
+{
+    static inline void apply(const T source[DimensionCount],
+                T target[DimensionCount])
+    {
+        boost::ignore_unused_variable_warning(source);
+        boost::ignore_unused_variable_warning(target);
+    }
+};
+
+template <typename T, std::size_t Dimension, std::size_t DimensionCount>
+struct compare_loop
+{
+    static inline bool apply(const T source[DimensionCount],
+                const T target[DimensionCount])
+    {
+        bool const not_equal = target[Dimension] != source[Dimension];
+
+        return not_equal
+            ? false
+            : compare_loop
+                <
+                    T, Dimension + 1, DimensionCount
+                >::apply(source, target);
+    }
+};
+
+template <typename T, std::size_t DimensionCount>
+struct compare_loop<T, DimensionCount, DimensionCount>
+{
+    static inline bool apply(const T source[DimensionCount],
+                const T target[DimensionCount])
+    {
+        boost::ignore_unused_variable_warning(source);
+        boost::ignore_unused_variable_warning(target);
+
+        return true;
+    }
+};
+
+
+template <typename Segment, std::size_t Dimension, std::size_t DimensionCount>
+struct check_duplicate_loop
+{
+    typedef typename coordinate_type<Segment>::type coordinate_type;
+
+    static inline bool apply(Segment const& seg)
+    {
+        coordinate_type const diff =
+            ggl::get<1, Dimension>(seg) - ggl::get<0, Dimension>(seg);
+
+        if (! ggl::math::equals(diff, 0))
+        {
+            return false;
+        }
+
+        return check_duplicate_loop
+            <
+                Segment, Dimension + 1, DimensionCount
+            >::apply(seg);
+    }
+};
+
+template <typename Segment, std::size_t DimensionCount>
+struct check_duplicate_loop<Segment, DimensionCount, DimensionCount>
+{
+    static inline bool apply(Segment const&)
+    {
+        return true;
+    }
+};
+
+template <typename T, std::size_t Dimension, std::size_t DimensionCount>
+struct assign_loop
+{
+    static inline void apply(T dims[DimensionCount], int const value)
+    {
+        dims[Dimension] = value;
+        assign_loop<T, Dimension + 1, DimensionCount>::apply(dims, value);
+    }
+};
+
+template <typename T, std::size_t DimensionCount>
+struct assign_loop<T, DimensionCount, DimensionCount>
+{
+    static inline void apply(T dims[DimensionCount], int const)
+    {
+        boost::ignore_unused_variable_warning(dims);
+    }
+};
+
+
+template
+<
+    typename Range,
+    typename Point,
+    typename Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize_range
+{
+    static inline void apply(Range const& range, Sections& sections,
+                int ring_index = -1, int multi_index = -1)
+    {
+        typedef segment<const Point> segment_type;
+
+        std::size_t const n = boost::size(range);
+        if (n == 0)
+        {
+            // Zero points, no section
+            return;
+        }
+
+        if (n == 1)
+        {
+            // Line with one point ==> no sections
+            return;
+        }
+
+        int i = 0;
+        int ndi = 0; // non duplicate index
+
+        typedef typename boost::range_value<Sections>::type sections_range_type;
+        sections_range_type section;
+
+        typedef typename boost::range_const_iterator<Range>::type iterator_type;
+        iterator_type it = boost::begin(range);
+
+        for(iterator_type previous = it++;
+            it != boost::end(range);
+            previous = it++, i++)
+        {
+            segment_type s(*previous, *it);
+
+            int direction_classes[DimensionCount] = {0};
+            get_direction_loop
+                <
+                    segment_type, 0, DimensionCount
+                >::apply(s, direction_classes);
+
+            // if "dir" == 0 for all point-dimensions, it is duplicate.
+            // Those sections might be omitted, if wished, lateron
+            bool check_duplicate = true; //?
+            bool duplicate = false;
+
+            if (check_duplicate && direction_classes[0] == 0)
+            {
+                // Recheck because all dimensions should be checked,
+                // not only first one,
+                // Note that DimensionCount might be < dimension<P>::value
+                if (check_duplicate_loop
+                    <
+                        segment_type, 0, ggl::dimension<Point>::type::value
+                    >::apply(s)
+                    )
+                {
+                    duplicate = true;
+
+                    // Change direction-info to force new section
+                    // Note that wo consecutive duplicate segments will generate
+                    // only one duplicate-section.
+                    // Actual value is not important as long as it is not -1,0,1
+                    assign_loop
+                    <
+                        int, 0, DimensionCount
+                    >::apply(direction_classes, -99);
+                }
+            }
+
+            if (section.count > 0
+                && (!compare_loop
+                        <
+                            int, 0, DimensionCount
+                        >::apply(direction_classes, section.directions)
+                    || section.count > MaxCount
+                    )
+                )
+            {
+                sections.push_back(section);
+                section = sections_range_type();
+            }
+
+            if (section.count == 0)
+            {
+                section.begin_index = i;
+                section.ring_index = ring_index;
+                section.multi_index = multi_index;
+                section.duplicate = duplicate;
+                section.non_duplicate_index = ndi;
+                section.range_count = boost::size(range);
+
+                copy_loop
+                    <
+                        int, 0, DimensionCount
+                    >::apply(direction_classes, section.directions);
+                ggl::combine(section.bounding_box, *previous);
+            }
+
+            ggl::combine(section.bounding_box, *it);
+            section.end_index = i + 1;
+            section.count++;
+            if (! duplicate)
+            {
+                ndi++;
+            }
+        }
+
+        if (section.count > 0)
+        {
+            sections.push_back(section);
+        }
+    }
+};
+
+template
+<
+    typename Polygon,
+    typename Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize_polygon
+{
+    static inline void apply(Polygon const& poly, Sections& sections,
+                int multi_index = -1)
+    {
+        typedef typename point_type<Polygon>::type point_type;
+        typedef typename ring_type<Polygon>::type ring_type;
+        typedef sectionalize_range
+            <
+                ring_type, point_type, Sections, DimensionCount, MaxCount
+            > sectionalizer_type;
+
+        typedef typename boost::range_const_iterator
+            <
+            typename interior_type<Polygon>::type
+            >::type iterator_type;
+
+        sectionalizer_type::apply(exterior_ring(poly), sections, -1, multi_index);
+
+        int i = 0;
+        for (iterator_type it = boost::begin(interior_rings(poly));
+             it != boost::end(interior_rings(poly));
+             ++it, ++i)
+        {
+            sectionalizer_type::apply(*it, sections, i, multi_index);
+        }
+    }
+};
+
+template
+<
+    typename Box,
+    typename Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize_box
+{
+    static inline void apply(Box const& box, Sections& sections)
+    {
+        typedef typename point_type<Box>::type point_type;
+
+        assert_dimension<Box, 2>();
+
+        // Add all four sides of the 2D-box as separate section.
+        // Easiest is to convert it to a polygon.
+        // However, we don't have the polygon type
+        // (or polygon would be a helper-type).
+        // Therefore we mimic a linestring/std::vector of 5 points
+
+        point_type ll, lr, ul, ur;
+        assign_box_corners(box, ll, lr, ul, ur);
+
+        std::vector<point_type> points;
+        points.push_back(ll);
+        points.push_back(ul);
+        points.push_back(ur);
+        points.push_back(lr);
+        points.push_back(ll);
+
+        sectionalize_range
+            <
+                std::vector<point_type>,
+                point_type,
+                Sections,
+                DimensionCount,
+                MaxCount
+            >::apply(points, sections);
+    }
+};
+
+}} // namespace detail::sectionalize
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename Tag,
+    typename Geometry,
+    typename Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize
+{};
+
+template
+<
+    typename Box,
+    typename Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize<box_tag, Box, Sections, DimensionCount, MaxCount>
+    : detail::sectionalize::sectionalize_box
+        <
+            Box,
+            Sections,
+            DimensionCount,
+            MaxCount
+        >
+{};
+
+template
+<
+    typename LineString, typename
+    Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize
+    <
+        linestring_tag,
+        LineString,
+        Sections,
+        DimensionCount,
+        MaxCount
+    >
+    : detail::sectionalize::sectionalize_range
+        <
+            LineString,
+            typename point_type<LineString>::type,
+            Sections,
+            DimensionCount,
+            MaxCount
+        >
+{};
+
+template
+<
+    typename Range,
+    typename Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize<ring_tag, Range, Sections, DimensionCount, MaxCount>
+    : detail::sectionalize::sectionalize_range
+        <
+            Range,
+            typename point_type<Range>::type,
+            Sections,
+            DimensionCount,
+            MaxCount
+        >
+{};
+
+template
+<
+    typename Polygon,
+    typename Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize<polygon_tag, Polygon, Sections, DimensionCount, MaxCount>
+    : detail::sectionalize::sectionalize_polygon
+        <
+            Polygon, Sections, DimensionCount, MaxCount
+        >
+{};
+
+} // namespace dispatch
+#endif
+
+
+/*!
+    \brief Split a geometry into monotonic sections
+    \ingroup sectionalize
+    \tparam Geometry type of geometry to check
+    \tparam Sections type of sections to create
+    \param geometry geometry to create sections from
+    \param sections structure with sections
+
+ */
+template<typename Geometry, typename Sections>
+inline void sectionalize(Geometry const& geometry, Sections& sections)
+{
+    // A maximum of 10 segments per section seems to give the fastest results
+    static const std::size_t max_segments_per_section = 10;
+    typedef dispatch::sectionalize
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            Sections,
+            Sections::value,
+            max_segments_per_section
+        > sectionalizer_type;
+
+    sections.clear();
+    sectionalizer_type::apply(geometry, sections);
+}
+
+
+
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_SECTIONALIZE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/selected.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/selected.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,278 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_SELECTED_HPP
+#define GGL_ALGORITHMS_SELECTED_HPP
+
+#include <cmath>
+#include <cstddef>
+
+#include <boost/concept/requires.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/within.hpp>
+#include <ggl/core/access.hpp>
+#include <ggl/core/topological_dimension.hpp>
+#include <ggl/core/concepts/nsphere_concept.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+
+/*!
+\defgroup selected selection: check if a geometry is "selected" by a point
+
+Checks if one geometry is selected by a point lying within or in the neighborhood of that geometry
+
+\par Geometries:
+- POINT: checks if points are CLOSE TO each other (< search_radius)
+- LINESTRING: checks if selection point is CLOSE TO linestring (< search_radius)
+- RING: checks if selection point is INSIDE the ring, search radius is ignored
+- POLYGON: checks if selection point is INSIDE the polygon, but not inside any of its holes
+
+*/
+
+namespace ggl
+{
+
+/*!
+    \ingroup impl
+ */
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace selected {
+
+/*!
+\details Checks, per dimension, if d[I] not larger than search distance. If true for all
+dimensions then returns true. If larger stops immediately and returns false.
+Calculate during this process the sum, which is only valid if returning true
+*/
+template <typename P1, typename P2, typename T, std::size_t D, std::size_t N>
+struct differences_loop
+{
+    static inline bool apply(P1 const& p1, P2 const& p2, T const& distance, T& sum)
+    {
+        typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+        coordinate_type const c1 = boost::numeric_cast<coordinate_type>(get<D>(p1));
+        coordinate_type const c2 = boost::numeric_cast<coordinate_type>(get<D>(p2));
+
+        T const d = std::abs(c1 - c2);
+        if (d > distance)
+        {
+            return false;
+        }
+        sum += d * d;
+        return differences_loop<P1, P2, T, D + 1, N>::apply(p1, p2, distance, sum);
+    }
+};
+
+template <typename P1, typename P2, typename T, std::size_t N>
+struct differences_loop<P1, P2, T, N, N>
+{
+    static inline bool apply(P1 const&, P2 const&, T const&, T&)
+    {
+        return true;
+    }
+};
+
+
+
+template <typename S, typename P, typename T, std::size_t D, std::size_t N>
+struct outside_loop
+{
+    static inline bool apply(S const& seg, P const& point, T const& distance)
+    {
+        typedef typename select_coordinate_type<S, P>::type coordinate_type;
+
+        coordinate_type const v = boost::numeric_cast<coordinate_type>(get<D>(point));
+        coordinate_type const s1 = get<0, D>(seg);
+        coordinate_type const s2 = get<1, D>(seg);
+
+        // Out of reach if left/bottom or right/top of both points making up the segment
+        // I know and currently accept that these comparisons/calculations are done twice per point
+
+        if ((v < s1 - distance && v < s2 - distance) || (v > s1 + distance && v > s2 + distance))
+        {
+            return true;
+        }
+        return outside_loop<S, P, T, D + 1, N>::apply(seg, point, distance);
+    }
+};
+
+template <typename S, typename P, typename T, std::size_t N>
+struct outside_loop<S, P, T, N, N>
+{
+    static inline bool apply(S const&, P const&, T const&)
+    {
+        return false;
+    }
+};
+
+
+template <typename P1, typename P2, typename T>
+struct close_to_point
+{
+    static inline bool apply(P1 const& point, P1 const& selection_point, T const& search_radius)
+    {
+        assert_dimension_equal<P1, P2>();
+
+        T sum = 0;
+        if (differences_loop
+                <
+                    P1, P2, T, 0, dimension<P1>::type::value
+                >::apply(point, selection_point, search_radius, sum))
+        {
+            return sum <= search_radius * search_radius;
+        }
+
+        return false;
+    }
+};
+
+template <typename S, typename P, typename T>
+struct close_to_segment
+{
+    static inline bool apply(S const& seg, P const& selection_point, T const& search_radius)
+    {
+        assert_dimension_equal<S, P>();
+
+        if (! outside_loop
+                <
+                    S, P, T, 0, dimension<P>::type::value
+                >::apply(seg, selection_point, search_radius))
+        {
+            // Not outside, calculate dot product/square distance to segment.
+            // Call corresponding strategy
+            typedef typename strategy_distance_segment
+                <
+                    typename cs_tag<P>::type,
+                    typename cs_tag<S>::type,
+                    P,
+                    S
+                >::type strategy_type;
+            typedef typename strategy_type::return_type return_type;
+
+            strategy_type strategy;
+            return_type result = strategy(selection_point, seg);
+            return result < search_radius;
+        }
+
+        return false;
+    }
+};
+
+template <typename R, typename P, typename T>
+struct close_to_range
+{
+    static inline bool apply(R const& range, P const& selection_point, T const& search_radius)
+    {
+        assert_dimension_equal<R, P>();
+
+        std::size_t const n = boost::size(range);
+        if (n == 0)
+        {
+            // Line with zero points, never close
+            return false;
+        }
+
+        typedef typename point_type<R>::type point_type;
+        typedef typename boost::range_const_iterator<R>::type iterator_type;
+
+        iterator_type it = boost::begin(range);
+        if (n == 1)
+        {
+            // Line with one point ==> close to point
+            return close_to_point<P, point_type, T>::apply(*it, selection_point, search_radius);
+        }
+
+        iterator_type previous = it++;
+        while(it != boost::end(range))
+        {
+            typedef segment<const point_type> segment_type;
+            segment_type s(*previous, *it);
+            if (close_to_segment<segment_type, P, T>::apply(s, selection_point, search_radius))
+            {
+                return true;
+            }
+            previous = it++;
+        }
+
+        return false;
+    }
+};
+
+template <typename Tag, typename G, typename P, typename T>
+struct use_within
+{
+    static inline bool apply(G const& geometry, P const& selection_point, T const& search_radius)
+    {
+        // Note the reversion, point-in-poly -> first point, then poly
+        // Selected-at-point -> first geometry, then point
+        return dispatch::within<point_tag, Tag, P, G>::apply(selection_point, geometry);
+    }
+};
+
+}} // namespace detail::selected
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+/*!
+    \tparam TD topological dimension
+ */
+template <typename Tag, typename G, std::size_t D, typename P, typename T>
+struct selected
+{
+};
+
+template <typename P1, typename P2, typename T>
+struct selected<point_tag, P1, 0, P2, T> : detail::selected::close_to_point<P1, P2, T> { };
+
+// SEGMENT, TODO HERE (close_to_segment)
+
+template <typename L, typename P, typename T>
+struct selected<linestring_tag, L, 1, P, T> : detail::selected::close_to_range<L, P, T> { };
+
+template <typename Tag, typename G, typename P, typename T>
+struct selected<Tag, G, 2, P, T> : detail::selected::use_within<Tag, G, P, T> { };
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Checks if one geometry is selected by a point lying within or in the neighborhood of that geometry
+    \ingroup selected
+    \tparam G type of geometry to check
+    \tparam P type of point to check
+    \tparam T type of search radius
+    \param geometry geometry which might be located in the neighborhood
+    \param selection_point point to select the geometry
+    \param search_radius for points/linestrings: defines radius of "neighborhood" to find things in
+    \return true if point is within or close to the other geometry
+
+ */
+template<typename G, typename P, typename T>
+inline bool selected(G const& geometry, P const& selection_point, T const& search_radius)
+{
+    typedef dispatch::selected
+        <
+        typename tag<G>::type,
+        G,
+        topological_dimension<G>::value,
+        P,
+        T
+        > selector_type;
+
+    return selector_type::apply(geometry, selection_point, search_radius);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_SELECTED_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/simplify.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/simplify.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,342 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_SIMPLIFY_HPP
+#define GGL_ALGORITHMS_SIMPLIFY_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/distance.hpp>
+#include <ggl/core/cs.hpp>
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/strategies/agnostic/agn_simplify.hpp>
+
+
+/*!
+\defgroup simplify simplification (generalization)
+\par Source description:
+- Wikipedia: given a 'curve' composed of line segments to find a curve not too dissimilar but that has fewer points
+
+\see http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
+
+\par Performance
+Performance is measured on simplification of a collection of rings, such that 10% of the points is kept.
+- 2776 counties of US are simplified in 0.8 seconds (2.5 seconds or 11.5 seconds in 2 other libraries)
+- 3918 zipcode areas of the Netherlands are simplified in 0.03 seconds (0.1 seconds or 0.45 seconds in 2 other libraries)
+
+
+\par Geometries
+- LINESTRING:
+\image html simplify_linestring.png
+- POLYGON: simplifying a valid simple polygon (which never intersects itself) might result in an invalid polygon,
+where the simplified rings intersect themselves or one of the other outer or inner rings.
+Efficient simplification of a ring/polygon is still an "Open Problem"
+(http://maven.smith.edu/~orourke/TOPP/P24.html#Problem.24)
+
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace simplify {
+
+template<typename R, typename OutputIterator, typename S>
+inline void simplify_range_strategy(R const& range, OutputIterator out, double max_distance, S const& strategy)
+{
+    if (boost::begin(range) == boost::end(range) || max_distance < 0)
+    {
+        std::copy(boost::begin(range), boost::end(range), out);
+    }
+    else
+    {
+        typename boost::range_const_iterator<R>::type it = boost::begin(range) + 1;
+        if (it == boost::end(range) || it + 1 == boost::end(range))
+        {
+            std::copy(boost::begin(range), boost::end(range), out);
+        }
+        else
+        {
+            strategy.simplify(range, out, max_distance);
+        }
+    }
+}
+
+template<typename R, typename OutputIterator>
+inline void simplify_range(R const& range, OutputIterator out, double max_distance)
+{
+    // Define default strategy
+    typedef typename point_type<R>::type point_type;
+    typedef typename cs_tag<point_type>::type cs_tag;
+    typedef typename strategy_distance_segment
+        <
+            cs_tag,
+            cs_tag,
+            point_type,
+            segment<const point_type>
+        >::type strategy_type;
+
+    strategy::simplify::douglas_peucker<R, OutputIterator, strategy_type> douglas;
+
+    simplify_range_strategy(range, out, max_distance, douglas);
+}
+
+template<typename R, typename OutputIterator, typename S>
+inline void simplify_ring(R const& r_in, OutputIterator out, double max_distance, S const& strategy)
+{
+    // Call do_container for a ring
+
+    // The first/last point (the closing point of the ring) should maybe be excluded because it
+    // lies on a line with second/one but last. Here it is never excluded.
+
+    // Note also that, especially if max_distance is too large, the output ring might be self intersecting
+    // while the input ring is not, although chances are low in normal polygons
+
+    // Finally the inputring might have 4 points (=correct), the output < 4(=wrong)
+    if (boost::size(r_in) <= 4 || max_distance < 0)
+    {
+        std::copy(boost::begin(r_in), boost::end(r_in), out);
+    }
+    else
+    {
+        simplify_range_strategy(r_in, out, max_distance, strategy);
+    }
+}
+
+template<typename Y, typename S>
+inline void simplify_polygon(Y const& poly_in, Y& poly_out, double max_distance, S const& strategy)
+{
+    typedef typename boost::range_iterator
+        <typename interior_type<Y>::type>::type iterator_type;
+    typedef typename boost::range_const_iterator
+        <typename interior_type<Y>::type>::type const_iterator_type;
+
+    poly_out.clear();
+
+    // Note that if there are inner rings, and distance is too large, they might intersect with the
+    // outer ring in the output, while it didn't in the input.
+    simplify_ring(exterior_ring(poly_in), std::back_inserter(exterior_ring(poly_out)),
+                  max_distance, strategy);
+
+    interior_rings(poly_out).resize(boost::size(interior_rings(poly_in)));
+
+    const_iterator_type it_in = boost::begin(interior_rings(poly_in));
+    iterator_type it_out = boost::begin(interior_rings(poly_out));
+
+    for (; it_in != boost::end(interior_rings(poly_in)); it_in++, it_out++)
+    {
+        simplify_ring(*it_in, std::back_inserter(*it_out), max_distance, strategy);
+    }
+}
+
+template<typename Y>
+inline void simplify_polygon(Y const& poly_in, Y& poly_out, double max_distance)
+{
+    // Define default strategy
+    typedef typename ring_type<Y>::type ring_type;
+    typedef std::back_insert_iterator<ring_type> iterator_type;
+
+    typedef typename point_type<Y>::type point_type;
+    typedef typename cs_tag<point_type>::type cs_tag;
+    typedef typename strategy_distance_segment
+        <
+            cs_tag,
+            cs_tag,
+            point_type,
+            segment<const point_type>
+        >::type strategy_type;
+
+    strategy::simplify::douglas_peucker<ring_type, iterator_type, strategy_type> douglas;
+
+    simplify_polygon(poly_in, poly_out, max_distance, douglas);
+}
+
+}} // namespace detail::simplify
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename G>
+struct simplify
+{
+};
+
+// Partial specializations
+template <typename R>
+struct simplify<linestring_tag, R>
+{
+    template<typename OutputIterator, typename S>
+    static inline void apply(R const& range, OutputIterator out, double max_distance, S const& strategy)
+    {
+        strategy.simplify(range, out, max_distance);
+    }
+
+    template<typename OutputIterator>
+    static inline void apply(R const& range, OutputIterator out, double max_distance)
+    {
+        // Define default strategy
+        typedef typename point_type<R>::type point_type;
+        typedef typename cs_tag<point_type>::type cs_tag;
+        typedef typename strategy_distance_segment
+            <
+                cs_tag,
+                cs_tag,
+                point_type,
+                segment<const point_type>
+           >::type strategy_type;
+
+        strategy::simplify::douglas_peucker<R, OutputIterator, strategy_type> douglas;
+
+        detail::simplify::simplify_range_strategy(range, out, max_distance, douglas);
+    }
+};
+
+template <typename R>
+struct simplify<ring_tag, R>
+{
+    /// Simplify a ring, using a strategy
+    template<typename S>
+    static inline void apply(R const& ring_in, R& ring_out, double max_distance, S const& strategy)
+    {
+        using detail::simplify::simplify_ring;
+        simplify_ring(ring_in, std::back_inserter(ring_out), max_distance, strategy);
+    }
+
+    /// Simplify a ring
+    static inline void apply(R const& ring_in, R& ring_out, double max_distance)
+    {
+        // Define default strategy
+        typedef typename point_type<R>::type point_type;
+        typedef typename cs_tag<point_type>::type cs_tag;
+        typedef typename strategy_distance_segment
+            <
+                cs_tag,
+                cs_tag,
+                point_type,
+                segment<const point_type>
+            >::type strategy_type;
+        typedef std::back_insert_iterator<R> iterator_type;
+
+        strategy::simplify::douglas_peucker<R, iterator_type, strategy_type> douglas;
+
+        detail::simplify::simplify_ring(ring_in, std::back_inserter(ring_out), max_distance, douglas);
+    }
+};
+
+template <typename P>
+struct simplify<polygon_tag, P>
+{
+    /// Simplify a polygon, using a strategy
+    template<typename S>
+    static inline void apply(P const& poly_in, P& poly_out, double max_distance, S const& strategy)
+    {
+        detail::simplify::simplify_polygon(poly_in, poly_out, max_distance, strategy);
+    }
+
+    /// Simplify a polygon
+    static inline void apply(P const& poly_in, P& poly_out, double max_distance)
+    {
+        detail::simplify::simplify_polygon(poly_in, poly_out, max_distance);
+    }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+// Model 1, using output iterator
+
+/*!
+    \brief Simplify a geometry
+    \ingroup simplify
+    \details The simplify algorithm removes points, keeping the shape as much as possible.
+    This version of simplify uses an output iterator
+    \param geometry the geometry to be simplified, being a ggl::linestring, vector, iterator pair, or any other boost compatible range
+    \param out output iterator, outputs all simplified points
+    \param max_distance distance (in units of input coordinates) of a vertex to other segments to be removed
+    \par Example:
+    The simplify algorithm can be used as following:
+    \dontinclude doxygen_examples.cpp
+    \skip example_simplify_linestring1
+    \line {
+    \until }
+ */
+template<typename G, typename O>
+inline void simplify(const G& geometry, O out, double max_distance)
+{
+    typedef dispatch::simplify<typename tag<G>::type, G> simplify_type;
+    simplify_type::apply(geometry, out, max_distance);
+}
+
+/*!
+    \brief Simplify a geometry
+    \ingroup simplify
+    \details The simplify algorithm removes points, keeping the shape as much as possible.
+    This version of simplify uses an output iterator and a simplify strategy
+    \param geometry the geometry to be simplified, being a ggl::linestring, vector, iterator pair, or any other boost compatible range
+    \param out output iterator, outputs all simplified points
+    \param max_distance distance (in units of input coordinates) of a vertex to other segments to be removed
+    \param strategy simplify strategy to be used for simplification, might include point-distance strategy
+    \par Example:
+    The simplify algorithm with strategy can be used as following:
+    \dontinclude doxygen_examples.cpp
+    \skip example_simplify_linestring2
+    \line {
+    \until }
+ */
+template<typename G, typename O, typename S>
+inline void simplify(const G& geometry, O out, double max_distance, S const& strategy)
+{
+    typedef dispatch::simplify<typename tag<G>::type, G> simplify_type;
+    simplify_type::apply(geometry, out, max_distance, strategy);
+}
+
+// Model 2, where output is same type as input
+
+/*!
+    \brief Simplify a geometry
+    \ingroup simplify
+    \details This version of simplify simplifies a geometry using the default strategy (Douglas Peucker),
+    where the output is of the same geometry type as the input.
+    \param geometry input geometry, to be simplified
+    \param out output geometry, simplified version of the input geometry
+    \param max_distance distance (in units of input coordinates) of a vertex to other segments to be removed
+ */
+template<typename G>
+inline void simplify(const G& geometry, G& out, double max_distance)
+{
+    typedef dispatch::simplify<typename tag<G>::type, G> simplify_type;
+    simplify_type::apply(geometry, out, max_distance);
+}
+
+/*!
+    \brief Simplify a geometry
+    \ingroup simplify
+    \details This version of simplify simplifies a geometry using a specified strategy
+    where the output is of the same geometry type as the input.
+    \param geometry input geometry, to be simplified
+    \param out output geometry, simplified version of the input geometry
+    \param max_distance distance (in units of input coordinates) of a vertex to other segments to be removed
+    \param strategy simplify strategy to be used for simplification, might include point-distance strategy
+ */
+template<typename G, typename S>
+inline void simplify(const G& geometry, G& out, double max_distance, S const& strategy)
+{
+    typedef dispatch::simplify<typename tag<G>::type, G> simplify_type;
+    simplify_type::apply(geometry, out, max_distance, strategy);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_SIMPLIFY_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/transform.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/transform.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,289 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_TRANSFORM_HPP
+#define GGL_ALGORITHMS_TRANSFORM_HPP
+
+#include <cmath>
+#include <iterator>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/clear.hpp>
+#include <ggl/core/cs.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/ring_type.hpp>
+#include <ggl/geometries/segment.hpp>
+#include <ggl/strategies/strategies.hpp>
+
+
+/*!
+\defgroup transform transformations
+\brief Transforms from one geometry to another geometry, optionally using a strategy
+\details The transform algorithm automatically transforms from one coordinate system to another coordinate system.
+If the coordinate system of both geometries are the same, the geometry is copied. All point(s of the geometry)
+are transformed.
+
+There is a version without a strategy, transforming automatically, and there is a version with a strategy.
+
+This function has a lot of appliances, for example
+- transform from spherical coordinates to cartesian coordinates, and back
+- transform from geographic coordinates to cartesian coordinates (projections) and back
+- transform from degree to radian, and back
+- transform from and to cartesian coordinates (mapping, translations, etc)
+
+The automatic transformations look to the coordinate system family, and dimensions, of the point type and by this
+apply the strategy (internally bounded by traits classes).
+
+\par Examples:
+The example below shows automatic transformations to go from one coordinate system to another one:
+\dontinclude doxygen_2.cpp
+\skip example_for_transform()
+\skipline XYZ
+\until endl;
+
+The next example takes another approach and transforms from Cartesian to Cartesian:
+\skipline XY
+\until endl;
+
+\note Not every possibility is yet worked out, e.g. polar coordinate system is ignored until now
+\note This "transform" is broader then geodetic datum transformations, those are currently not worked out
+
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace transform {
+
+template <typename P1, typename P2>
+struct transform_point
+{
+    template <typename S>
+    static inline bool apply(P1 const& p1, P2& p2, S const& strategy)
+    {
+        return strategy(p1, p2);
+    }
+};
+
+template <typename B1, typename B2>
+struct transform_box
+{
+    template <typename S>
+    static inline bool apply(B1 const& b1, B2& b2, S const& strategy)
+    {
+        typedef typename point_type<B1>::type point_type1;
+        typedef typename point_type<B2>::type point_type2;
+
+        point_type1 lower_left, upper_right;
+        assign_box_corner<min_corner, min_corner>(b1, lower_left);
+        assign_box_corner<max_corner, max_corner>(b1, upper_right);
+
+        point_type2 p1, p2;
+        if (strategy(lower_left, p1) && strategy(upper_right, p2))
+        {
+            // Create a valid box and therefore swap if necessary
+            typedef typename coordinate_type<point_type2>::type coordinate_type;
+            coordinate_type x1 = ggl::get<0>(p1)
+                    , y1  = ggl::get<1>(p1)
+                    , x2  = ggl::get<0>(p2)
+                    , y2  = ggl::get<1>(p2);
+
+            if (x1 > x2) { std::swap(x1, x2); }
+            if (y1 > y2) { std::swap(y1, y2); }
+
+            set<min_corner, 0>(b2, x1);
+            set<min_corner, 1>(b2, y1);
+            set<max_corner, 0>(b2, x2);
+            set<max_corner, 1>(b2, y2);
+
+            return true;
+        }
+        return false;
+    }
+};
+
+template <typename P, typename OutputIterator, typename R, typename S>
+inline bool transform_range_out(R const& range, OutputIterator out, S const& strategy)
+{
+    P point_out;
+    for(typename boost::range_const_iterator<R>::type it = boost::begin(range);
+        it != boost::end(range); ++it)
+    {
+        if (! transform_point<typename point_type<R>::type, P>::apply(*it, point_out, strategy))
+        {
+            return false;
+        }
+        *out = point_out;
+        ++out;
+    }
+    return true;
+}
+
+template <typename P1, typename P2>
+struct transform_polygon
+{
+    template <typename S>
+    static inline bool apply(const P1& poly1, P2& poly2, S const& strategy)
+    {
+        typedef typename interior_type<P1>::type interior1_type;
+        typedef typename interior_type<P2>::type interior2_type;
+        typedef typename ring_type<P1>::type ring1_type;
+        typedef typename ring_type<P2>::type ring2_type;
+        typedef typename point_type<P2>::type point2_type;
+
+        ggl::clear(poly2);
+
+        if (!transform_range_out<point2_type>(exterior_ring(poly1),
+                    std::back_inserter(exterior_ring(poly2)), strategy))
+        {
+            return false;
+        }
+
+        interior_rings(poly2).resize(boost::size(interior_rings(poly1)));
+
+        typedef typename boost::range_const_iterator<interior1_type>::type iterator1_type;
+        typedef typename boost::range_iterator<interior2_type>::type iterator2_type;
+
+        iterator1_type it1 = boost::begin(interior_rings(poly1));
+        iterator2_type it2 = boost::begin(interior_rings(poly2));
+        for ( ; it1 != boost::end(interior_rings(poly1)); ++it1, ++it2)
+        {
+            if (!transform_range_out<point2_type>(*it1, std::back_inserter(*it2), strategy))
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+};
+
+
+template <typename P1, typename P2>
+struct select_strategy
+{
+    typedef typename strategy_transform
+        <
+        typename cs_tag<P1>::type,
+        typename cs_tag<P2>::type,
+        typename coordinate_system<P1>::type,
+        typename coordinate_system<P2>::type,
+        dimension<P1>::type::value,
+        dimension<P2>::type::value,
+        typename point_type<P1>::type,
+        typename point_type<P2>::type
+        >::type type;
+};
+
+template <typename R1, typename R2>
+struct transform_range
+{
+    template <typename S>
+    static inline bool apply(R1 const& range1, R2& range2, S const& strategy)
+    {
+        typedef typename point_type<R2>::type point_type;
+
+        ggl::clear(range2);
+        return transform_range_out<point_type>(range1, std::back_inserter(range2), strategy);
+    }
+};
+
+}} // namespace detail::transform
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag1, typename Tag2, typename G1, typename G2>
+struct transform {};
+
+template <typename P1, typename P2>
+struct transform<point_tag, point_tag, P1, P2>
+    : detail::transform::transform_point<P1, P2>
+{
+};
+
+
+template <typename L1, typename L2>
+struct transform<linestring_tag, linestring_tag, L1, L2>
+    : detail::transform::transform_range<L1, L2>
+{
+};
+
+template <typename R1, typename R2>
+struct transform<ring_tag, ring_tag, R1, R2>
+    : detail::transform::transform_range<R1, R2>
+{
+};
+
+template <typename P1, typename P2>
+struct transform<polygon_tag, polygon_tag, P1, P2>
+    : detail::transform::transform_polygon<P1, P2>
+{
+};
+
+template <typename B1, typename B2>
+struct transform<box_tag, box_tag, B1, B2>
+    : detail::transform::transform_box<B1, B2>
+{
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Transforms from one geometry to another geometry using a strategy
+    \ingroup transform
+    \tparam G1 first geometry type
+    \tparam G2 second geometry type
+    \tparam S strategy
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \param strategy the strategy to be used for transformation
+ */
+template <typename G1, typename G2, typename S>
+inline bool transform(G1 const& geometry1, G2& geometry2, S const& strategy)
+{
+    typedef dispatch::transform
+        <
+        typename tag<G1>::type,
+        typename tag<G2>::type,
+        G1,
+        G2
+        > transform_type;
+
+    return transform_type::apply(geometry1, geometry2, strategy);
+}
+
+/*!
+    \brief Transforms from one geometry to another geometry using a strategy
+    \ingroup transform
+    \tparam G1 first geometry type
+    \tparam G2 second geometry type
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \return true if the transformation could be done
+ */
+template <typename G1, typename G2>
+inline bool transform(G1 const& geometry1, G2& geometry2)
+{
+    typename detail::transform::select_strategy<G1, G2>::type strategy;
+    return transform(geometry1, geometry2, strategy);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_TRANSFORM_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/algorithms/within.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/algorithms/within.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,414 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_WITHIN_HPP
+#define GGL_ALGORITHMS_WITHIN_HPP
+
+#include <boost/concept/requires.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/distance.hpp>
+#include <ggl/algorithms/make.hpp>
+#include <ggl/core/access.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/core/concepts/nsphere_concept.hpp>
+#include <ggl/core/cs.hpp>
+#include <ggl/strategies/strategies.hpp>
+#include <ggl/util/loop.hpp>
+
+
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace within {
+
+
+//-------------------------------------------------------------------------------------------------------
+// Implementation for boxes. Supports boxes in 2 or 3 dimensions, in Euclidian system
+// Todo: implement as strategy
+//-------------------------------------------------------------------------------------------------------
+template <typename P, typename B, size_t D, size_t N>
+struct point_in_box
+{
+    static bool inside(P const& p, B const& b)
+    {
+        if (get<D>(p) <= get<min_corner, D>(b)
+            || get<D>(p) >= get<max_corner, D>(b))
+        {
+            return false;
+        }
+
+        return point_in_box<P, B, D + 1, N>::inside(p, b);
+    }
+};
+
+template <typename P, typename B, size_t N>
+struct point_in_box<P, B, N, N>
+{
+    static bool inside(P const& p, B const& b)
+    {
+        return true;
+    }
+};
+
+//-------------------------------------------------------------------------------------------------------
+// Box-in-box, for 2/3 dimensions
+//-------------------------------------------------------------------------------------------------------
+template <typename B1, typename B2, size_t D, size_t N>
+struct box_in_box
+{
+    static inline bool inside(B1 const& b1, B2 const& b2)
+    {
+        if (get<min_corner, D>(b1) <= get<min_corner, D>(b2)
+            || get<max_corner, D>(b1) >= get<max_corner, D>(b2))
+        {
+            return false;
+        }
+
+        return box_in_box<B1, B2, D + 1, N>::inside(b1, b2);
+    }
+};
+
+template <typename B1, typename B2, size_t N>
+struct box_in_box<B1, B2, N, N>
+{
+    static inline bool inside(B1 const& b1, B2 const& b2)
+    {
+        return true;
+    }
+};
+
+
+//-------------------------------------------------------------------------------------------------------
+// Implementation for n-spheres. Supports circles or spheres, in 2 or 3 dimensions, in Euclidian system
+// Circle center might be of other point-type as geometry
+// Todo: implement as strategy
+//-------------------------------------------------------------------------------------------------------
+template<typename P, typename C>
+inline bool point_in_circle(P const& p, C const& c)
+{
+    assert_dimension<C, 2>();
+
+    typedef typename point_type<C>::type point_type;
+    typedef typename strategy_distance
+        <
+            typename cs_tag<P>::type,
+            typename cs_tag<point_type>::type,
+            P,
+            point_type
+        >::type strategy_type;
+    typedef typename strategy_type::return_type return_type;
+
+    P const center = ggl::make<P>(get<0>(c), get<1>(c));
+    strategy_type distance;
+    return_type const r = distance(p, center);
+    return_type const rad = make_distance_result<return_type>(get_radius<0>(c));
+
+    return r < rad;
+}
+/// 2D version
+template<typename T, typename C>
+inline bool point_in_circle(const T& c1, const T& c2, C const& c)
+{
+    typedef typename point_type<C>::type point_type;
+
+    point_type p = ggl::make<point_type>(c1, c2);
+    return point_in_circle(p, c);
+}
+
+template<typename B, typename C>
+inline bool box_in_circle(B const& b, C const& c)
+{
+    typedef typename point_type<B>::type point_type;
+
+    // Currently only implemented for 2d geometries
+    assert_dimension<point_type, 2>();
+    assert_dimension<C, 2>();
+
+    // Box: all four points must lie within circle
+
+    // Check points lower-left and upper-right, then lower-right and upper-left
+    return point_in_circle(get<min_corner, 0>(b), get<min_corner, 1>(b), c)
+        && point_in_circle(get<max_corner, 0>(b), get<max_corner, 1>(b), c)
+        && point_in_circle(get<min_corner, 0>(b), get<max_corner, 1>(b), c)
+        && point_in_circle(get<max_corner, 0>(b), get<min_corner, 1>(b), c);
+}
+
+// Generic "range-in-circle", true if all points within circle
+template<typename R, typename C>
+inline bool range_in_circle(R const& range, C const& c)
+{
+    assert_dimension<R, 2>();
+    assert_dimension<C, 2>();
+
+    for (typename boost::range_const_iterator<R>::type it = boost::begin(range);
+         it != boost::end(range); ++it)
+    {
+        if (! point_in_circle(*it, c))
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+template<typename Y, typename C>
+inline bool polygon_in_circle(Y const& poly, C const& c)
+{
+    return range_in_circle(exterior_ring(poly), c);
+}
+
+template<typename P, typename R, typename S>
+inline bool point_in_ring(P const& p, R const& r, S const& strategy)
+{
+    if (boost::size(r) < 4)
+    {
+        return false;
+    }
+
+    typename S::state_type state(p);
+    if (loop(r, strategy, state))
+    {
+        return state.within();
+    }
+
+    return false;
+}
+
+// Polygon: in exterior ring, and if so, not within interior ring(s)
+template<typename P, typename Y, typename S>
+inline bool point_in_polygon(P const& p, Y const& poly, S const& strategy)
+{
+    if (point_in_ring(p, exterior_ring(poly), strategy))
+    {
+        typedef typename boost::range_const_iterator
+            <typename interior_type<Y>::type>::type iterator_type;
+
+        for (iterator_type it = boost::begin(interior_rings(poly));
+             it != boost::end(interior_rings(poly)); ++it)
+        {
+            if (point_in_ring(p, *it, strategy))
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+    return false;
+}
+
+}} // namespace detail::within
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag1, typename Tag2, typename G1, typename G2>
+struct within {};
+
+template <typename P, typename B>
+struct within<point_tag, box_tag, P, B>
+{
+    static inline bool apply(P const& p, B const& b)
+    {
+        assert_dimension_equal<P, B>();
+
+        return detail::within::point_in_box
+            <
+                P,
+                B,
+                0,
+                dimension<P>::type::value
+            >::inside(p, b);
+    }
+};
+
+template <typename B1, typename B2>
+struct within<box_tag, box_tag, B1, B2>
+{
+    static inline bool apply(B1 const& b1, B2 const& b2)
+    {
+        assert_dimension_equal<B1, B2>();
+
+        return detail::within::box_in_box
+            <
+                B1,
+                B2,
+                0,
+                dimension<B1>::type::value
+            >::inside(b1, b2);
+    }
+};
+
+
+template <typename P, typename C>
+struct within<point_tag, nsphere_tag, P, C>
+{
+    static inline bool apply(P const& p, C const& c)
+    {
+        return detail::within::point_in_circle(p, c);
+    }
+};
+
+template <typename B, typename C>
+struct within<box_tag, nsphere_tag, B, C>
+{
+    static inline bool apply(B const& b, C const& c)
+    {
+        return detail::within::box_in_circle(b, c);
+    }
+};
+
+template <typename R, typename C>
+struct within<linestring_tag, nsphere_tag, R, C>
+{
+    static inline bool apply(R const& ln, C const& c)
+    {
+        return detail::within::range_in_circle(ln, c);
+    }
+};
+
+template <typename R, typename C>
+struct within<ring_tag, nsphere_tag, R, C>
+{
+    static inline bool apply(R const& r, C const& c)
+    {
+        return detail::within::range_in_circle(r, c);
+    }
+};
+
+template <typename Y, typename C>
+struct within<polygon_tag, nsphere_tag, Y, C>
+{
+    static inline bool apply(Y const& poly, C const& c)
+    {
+        return detail::within::polygon_in_circle(poly, c);
+    }
+};
+
+template <typename P, typename R>
+struct within<point_tag, ring_tag, P, R>
+{
+    static inline bool apply(P const& p, R const& r)
+    {
+        typedef typename boost::range_value<R>::type point_type;
+        typedef typename strategy_within
+            <
+                typename cs_tag<P>::type,
+                typename cs_tag<point_type>::type,
+                P,
+                point_type
+            >::type strategy_type;
+
+        return detail::within::point_in_ring(p, r, strategy_type());
+    }
+};
+
+template <typename P, typename Y>
+struct within<point_tag, polygon_tag, P, Y>
+{
+    static inline bool apply(P const& point, Y const& poly)
+    {
+        typedef typename point_type<Y>::type point_type;
+        typedef typename strategy_within
+            <
+                typename cs_tag<P>::type,
+                typename cs_tag<point_type>::type,
+                P,
+                point_type
+            >::type strategy_type;
+
+        return detail::within::point_in_polygon(point, poly, strategy_type());
+    }
+
+    template<typename S>
+    static inline bool apply(P const& point, Y const& poly, S const& strategy)
+    {
+        return detail::within::point_in_polygon(point, poly, strategy);
+    }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Within check
+    \details Examine if one geometry is within another geometry (a.o. point in polygon)
+    \ingroup boolean_relations
+    \param geometry1 geometry which might be within the second geometry
+    \param geometry2 geometry which might contain the first geometry
+    \return true if geometry1 is completely contained within geometry2, else false
+    \note The default strategy is used for within detection
+
+\par Source descriptions:
+- OGC: Returns 1 (TRUE) if this geometric object is "spatially within" another Geometry.
+
+\par Performance
+2776 within determinations using bounding box and polygon are done in 0.09 seconds (other libraries: 0.14 seconds, 3.0 seconds, 3.8)
+
+\par Example:
+The within algorithm is used as following:
+\dontinclude doxygen_examples.cpp
+\skip example_within
+\line {
+\until }
+\par Geometries:
+- POINT + POLYGON: The well-known point-in-polygon, returning true if a point falls within a polygon (and not
+within one of its holes) \image html within_polygon.png
+- POINT + RING: returns true if point is completely within a ring \image html within_ring.png
+
+ */
+template<typename G1, typename G2>
+inline bool within(G1 const& geometry1, G2 const& geometry2)
+{
+    typedef dispatch::within
+        <
+            typename tag<G1>::type,
+            typename tag<G2>::type,
+            G1,
+            G2
+        > within_type;
+
+    return within_type::apply(geometry1, geometry2);
+}
+
+/*!
+    \brief Within check using a strategy
+    \ingroup boolean_relations
+    \param geometry1 geometry which might be within the second geometry
+    \param geometry2 geometry which might contain the first geometry
+    \param strategy strategy to be used
+    \return true if geometry1 is completely contained within geometry2, else false
+ */
+template<typename G1, typename G2, typename S>
+inline bool within(G1 const& geometry1, G2 const& geometry2, S const& strategy)
+{
+    typedef dispatch::within
+        <
+            typename tag<G1>::type,
+            typename tag<G2>::type,
+            G1,
+            G2
+        > within_type;
+
+    return within_type::apply(geometry1, geometry2, strategy);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_WITHIN_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/arithmetic/arithmetic.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/arithmetic/arithmetic.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,209 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ARITHMETIC_ARITHMETIC_HPP
+#define GGL_ARITHMETIC_ARITHMETIC_HPP
+
+#include <functional>
+
+#include <boost/call_traits.hpp>
+#include <boost/concept/requires.hpp>
+
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/util/for_each_coordinate.hpp>
+
+/*!
+\defgroup arithmetic arithmetic: arithmetic operations on points
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename P>
+struct param
+{
+    typedef typename boost::call_traits
+        <
+            typename coordinate_type<P>::type
+        >::param_type type;
+};
+
+template <typename C, template <typename> class Function>
+struct value_operation
+{
+    C m_value;
+
+    inline value_operation(const C& value)
+        : m_value(value)
+    {}
+
+    template <typename P, int I>
+    inline void apply(P& point) const
+    {
+        set<I>(point, Function<C>()(get<I>(point), m_value));
+    }
+};
+
+template <typename PointSrc, template <typename> class Function>
+struct point_operation
+{
+    typedef typename coordinate_type<PointSrc>::type coordinate_type;
+    PointSrc const& m_source_point;
+
+    inline point_operation(const PointSrc& point)
+        : m_source_point(point)
+    {}
+
+    template <typename PointDst, int I>
+    inline void apply(PointDst& dest_point) const
+    {
+        set<I>(dest_point,
+            Function<coordinate_type>()(get<I>(dest_point), get<I>(m_source_point)));
+    }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+/*!
+    \brief Adds a value to each coordinate of a point
+    \ingroup arithmetic
+    \details
+    \param p point
+    \param value value to add
+ */
+template <typename Point>
+inline void add_value(Point& p, typename detail::param<Point>::type value)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+    for_each_coordinate(p, detail::value_operation<typename coordinate_type<Point>::type, std::plus>(value));
+}
+
+/*!
+    \brief Adds a point to another
+    \ingroup arithmetic
+    \details The coordinates of the second point will be added to those of the first point.
+             The second point is not modified.
+    \param p1 first point
+    \param p2 second point
+ */
+template <typename Point1, typename Point2>
+inline void add_point(Point1& p1, Point2 const& p2)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
+
+    for_each_coordinate(p1, detail::point_operation<Point2, std::plus>(p2));
+}
+
+/*!
+    \brief Subtracts a value to each coordinate of a point
+    \ingroup arithmetic
+    \details
+    \param p point
+    \param value value to subtract
+ */
+template <typename Point>
+inline void subtract_value(Point& p, typename detail::param<Point>::type value)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+    for_each_coordinate(p, detail::value_operation<typename coordinate_type<Point>::type, std::minus>(value));
+}
+
+/*!
+    \brief Subtracts a point to another
+    \ingroup arithmetic
+    \details The coordinates of the second point will be subtracted to those of the first point.
+             The second point is not modified.
+    \param p1 first point
+    \param p2 second point
+ */
+template <typename Point1, typename Point2>
+inline void subtract_point(Point1& p1, Point2 const& p2)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
+
+    for_each_coordinate(p1, detail::point_operation<Point2, std::minus>(p2));
+}
+
+/*!
+    \brief Multiplies each coordinate of a point by a value
+    \ingroup arithmetic
+    \details
+    \param p point
+    \param value value to multiply by
+ */
+template <typename Point>
+inline void multiply_value(Point& p, typename detail::param<Point>::type value)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+    for_each_coordinate(p, detail::value_operation<typename coordinate_type<Point>::type, std::multiplies>(value));
+}
+
+/*!
+    \brief Multiplies a point by another
+    \ingroup arithmetic
+    \details The coordinates of the second point will be multiplied by those of the first point.
+             The second point is not modified.
+    \param p1 first point
+    \param p2 second point
+    \note This is *not* a dot, cross or wedge product. It is a mere field-by-field multiplication.
+ */
+template <typename Point1, typename Point2>
+inline void multiply_point(Point1& p1, Point2 const& p2)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
+
+    for_each_coordinate(p1, detail::point_operation<Point2, std::multiplies>(p2));
+}
+
+/*!
+    \brief Divides each coordinate of a point by a value
+    \ingroup arithmetic
+    \details
+    \param p point
+    \param value value to divide by
+ */
+template <typename Point>
+inline void divide_value(Point& p, typename detail::param<Point>::type value)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+    for_each_coordinate(p, detail::value_operation<typename coordinate_type<Point>::type, std::divides>(value));
+}
+
+/*!
+    \brief Divides a point by another
+    \ingroup arithmetic
+    \details The coordinates of the second point will be divided by those of the first point.
+             The second point is not modified.
+    \param p1 first point
+    \param p2 second point
+ */
+template <typename Point1, typename Point2>
+inline void divide_point(Point1& p1, Point2 const& p2)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
+
+    for_each_coordinate(p1, detail::point_operation<Point2, std::divides>(p2));
+}
+
+} // namespace ggl
+
+#endif // GGL_ARITHMETIC_ARITHMETIC_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/arithmetic/dot_product.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/arithmetic/dot_product.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,70 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ARITHMETIC_DOT_PRODUCT_HPP
+#define GGL_ARITHMETIC_DOT_PRODUCT_HPP
+
+#include <boost/concept/requires.hpp>
+
+#include <ggl/core/concepts/point_concept.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename P1, typename P2, std::size_t Dimension, std::size_t DimensionCount>
+struct dot_product_maker
+{
+    static inline typename coordinate_type<P1>::type
+        apply(P1 const& p1, P2 const& p2)
+    {
+        return get<Dimension>(p1) * get<Dimension>(p2)
+            + dot_product_maker<P1, P2, Dimension+1, DimensionCount>::apply(p1, p2);
+    }
+};
+
+template <typename P1, typename P2, std::size_t DimensionCount>
+struct dot_product_maker<P1, P2, DimensionCount, DimensionCount>
+{
+    static inline typename coordinate_type<P1>::type
+        apply(P1 const& p1, P2 const& p2)
+    {
+        return get<DimensionCount>(p1) * get<DimensionCount>(p2);
+    }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief Computes the dot product of 2 points
+    \ingroup arithmetic
+    \param p1 first point
+    \param p2 second point
+    \return the dot product
+ */
+template <typename P1, typename P2>
+inline typename coordinate_type<P1>::type dot_product(P1 const& p1, P2 const& p2)
+{
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P1>) );
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P2>) );
+
+    return detail::dot_product_maker
+        <
+            P1, P2,
+            0, dimension<P1>::type::value - 1
+        >::apply(p1, p2);
+}
+
+} // namespace ggl
+
+#endif // GGL_ARITHMETIC_DOT_PRODUCT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/access.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/access.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,292 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_ACCESS_HPP
+#define GGL_CORE_ACCESS_HPP
+
+#include <cstddef>
+
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/concept_check.hpp>
+
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/core/tag.hpp>
+
+namespace ggl
+{
+
+const int min_corner = 0;
+const int max_corner = 1;
+
+namespace traits
+{
+
+/*!
+    \brief Traits class which gives access (get,set) to points
+    \ingroup traits
+    \par Geometries:
+        - point
+        - n-sphere (circle,sphere) for their center
+    \par Specializations should provide:
+        - static inline T get<I>(const G&)
+        - static inline void set<I>(G&, const T&)
+    \tparam G geometry
+*/
+template <typename G>
+struct access {};
+
+
+/*!
+    \brief Traits class defining "get" and "set" to get and set point coordinate values
+    \tparam G geometry (box, segment)
+    \tparam I index (min_corner/max_corner for box, 0/1 for segment)
+    \tparam D dimension
+    \par Geometries:
+        - box
+        - segment
+    \par Specializations should provide:
+        - static inline T get(const G&)
+        - static inline void set(G&, const T&)
+    \ingroup traits
+*/
+template <typename G, std::size_t I, std::size_t D>
+struct indexed_access {};
+
+
+/*!
+    \brief Traits class, optional, indicating that the std-library should be used
+    \details The default geometry (linestring, ring, multi*) follow std:: for
+        its modifying operations (push_back, clear, size, resize, reserve, etc)
+        If they NOT follow the std:: library they should specialize this traits
+        class
+    \ingroup traits
+    \par Geometries:
+        - linestring
+        - linear_ring
+    \par Specializations should provide:
+        - value (defaults to true)
+ */
+template <typename G>
+struct use_std
+{
+    static const bool value = true;
+};
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+template <typename Tag, typename G, typename T, std::size_t D>
+struct access
+{
+    //static inline T get(const G& ) {}
+    //static inline void set(G& g, const T& value) {}
+};
+
+template <typename Tag, typename G, typename T, std::size_t I, std::size_t D>
+struct indexed_access
+{
+    //static inline T get(const G& ) {}
+    //static inline void set(G& g, const T& value) {}
+};
+
+template <typename P, typename T, std::size_t D>
+struct access<point_tag, P, T, D>
+{
+    static inline T get(const P& p)
+    {
+        return traits::access<P>::template get<D>(p);
+    }
+    static inline void set(P& p, const T& value)
+    {
+        traits::access<P>::template set<D>(p, value);
+    }
+};
+
+template <typename S, typename T, std::size_t D>
+struct access<nsphere_tag, S, T, D>
+{
+    static inline T get(const S& s)
+    {
+        return traits::access<S>::template get<D>(s);
+    }
+    static inline void set(S& s, const T& value)
+    {
+        traits::access<S>::template set<D>(s, value);
+    }
+};
+
+template <typename B, typename T, std::size_t I, std::size_t D>
+struct indexed_access<box_tag, B, T, I, D>
+{
+    static inline T get(const B& b)
+    {
+        return traits::indexed_access<B, I, D>::get(b);
+    }
+    static inline void set(B& b, const T& value)
+    {
+        traits::indexed_access<B, I, D>::set(b, value);
+    }
+};
+
+template <typename S, typename T, std::size_t I, std::size_t D>
+struct indexed_access<segment_tag, S, T, I, D>
+{
+    static inline T get(const S& segment)
+    {
+        return traits::indexed_access<S, I, D>::get(segment);
+    }
+    static inline void set(S& segment, const T& value)
+    {
+        traits::indexed_access<S, I, D>::set(segment, value);
+    }
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+// Two dummy tags to distinguish get/set variants below.
+// They don't have to be specified by the user. The functions are distinguished
+// by template signature also, but for e.g. GCC this is not enough. So give them
+// a different signature.
+struct signature_getset_dimension {};
+struct signature_getset_index_dimension {};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief get a coordinate value of a point / nsphere
+    \return coordinate value
+    \ingroup access
+    \tparam D dimension
+    \tparam G geometry
+    \param geometry geometry to get coordinate value from
+    \param dummy does not have to be specified
+*/
+template <std::size_t D, typename G>
+inline typename coordinate_type<G>::type get(const G& geometry,
+    detail::signature_getset_dimension* dummy = 0)
+{
+    boost::ignore_unused_variable_warning(dummy);
+
+    typedef typename boost::remove_const<G>::type ncg_type;
+
+    typedef core_dispatch::access
+        <
+        typename tag<G>::type,
+        ncg_type,
+        typename coordinate_type<ncg_type>::type,
+        D
+        > coord_access_type;
+
+    return coord_access_type::get(geometry);
+}
+
+
+/*!
+    \brief assign coordinate value to a point / sphere
+    \ingroup access
+    \tparam D dimension
+    \tparam G geometry
+    \param geometry geometry to assign coordinate to
+    \param value coordinate value to assign
+    \param dummy does not have to be specified
+*/
+template <std::size_t D, typename G>
+inline void set(G& geometry, const typename coordinate_type<G>::type& value,
+    detail::signature_getset_dimension* dummy = 0)
+{
+    boost::ignore_unused_variable_warning(dummy);
+
+    typedef typename boost::remove_const<G>::type ncg_type;
+
+    typedef core_dispatch::access
+        <
+        typename tag<G>::type,
+        ncg_type,
+        typename coordinate_type<ncg_type>::type,
+        D
+        > coord_access_type;
+
+    coord_access_type::set(geometry, value);
+}
+
+// Note: doxygen needs a construct to distinguish get/set (like the gcc compiler)
+
+/*!
+    \brief get a coordinate value of a box / segment
+    \return coordinate value
+    \ingroup access
+    \tparam I index, for boxes: min_corner or max_corner. For segment: 0 / 1
+    \tparam D dimension
+    \tparam G geometry
+    \param geometry geometry to get coordinate value from
+    \param dummy does not have to be specified
+*/
+template <std::size_t I, std::size_t D, typename G>
+inline typename coordinate_type<G>::type get(const G& geometry,
+    detail::signature_getset_index_dimension* dummy = 0)
+{
+    boost::ignore_unused_variable_warning(dummy);
+
+    typedef typename boost::remove_const<G>::type ncg_type;
+
+    typedef core_dispatch::indexed_access
+        <
+        typename tag<G>::type,
+        ncg_type,
+        typename coordinate_type<ncg_type>::type,
+        I,
+        D
+        > coord_access_type;
+
+    return coord_access_type::get(geometry);
+}
+
+/*!
+    \brief assign a coordinate value of a box / segment
+    \ingroup access
+    \tparam I index, for boxes: min_corner or max_corner. For segment: 0 / 1
+    \tparam D dimension
+    \tparam G geometry
+    \param geometry geometry to assign coordinate to
+    \param value coordinate value to assign
+    \param dummy does not have to be specified
+*/
+template <std::size_t I, std::size_t D, typename G>
+inline void set(G& geometry, const typename coordinate_type<G>::type& value,
+    detail::signature_getset_index_dimension* dummy = 0)
+{
+    boost::ignore_unused_variable_warning(dummy);
+
+    typedef typename boost::remove_const<G>::type ncg_type;
+
+    typedef core_dispatch::indexed_access
+        <
+        typename tag<G>::type, ncg_type,
+        typename coordinate_type<ncg_type>::type,
+        I,
+        D
+        > coord_access_type;
+
+    coord_access_type::set(geometry, value);
+}
+
+} // namespace ggl
+
+#endif // GGL_CORE_ACCESS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/concepts/box_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/concepts/box_concept.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,109 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_CONCEPTS_BOX_CONCEPT_HPP
+#define GGL_CORE_CONCEPTS_BOX_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/point_type.hpp>
+
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+    \brief Checks box concept, using Boost Concept Check Library and metafunctions
+    \ingroup concepts
+*/
+template <typename B>
+struct Box
+{
+    private :
+        typedef typename point_type<B>::type P;
+
+        /// Internal structure to check if access is OK for all dimensions
+        template <size_t C, size_t D, size_t N>
+        struct dimension_checker
+        {
+            static void check()
+            {
+                B* b;
+                ggl::set<C, D>(*b, ggl::get<C, D>(*b));
+                dimension_checker<C, D + 1, N>::check();
+            }
+        };
+
+        template <size_t C, size_t N>
+        struct dimension_checker<C, N, N>
+        {
+            static void check() {}
+        };
+
+    public :
+        /// BCCL macro to check the Box concept
+        BOOST_CONCEPT_USAGE(Box)
+        {
+            static const size_t N = dimension<B>::value;
+            dimension_checker<min_corner, 0, N>::check();
+            dimension_checker<max_corner, 0, N>::check();
+        }
+};
+
+
+/*!
+    \brief Checks Box concept (const version)
+    \ingroup concepts
+    \details The ConstBox concept check the same as the Box concept,
+    but does not check write access.
+*/
+template <typename B>
+struct ConstBox
+{
+    private :
+        typedef typename point_type<B>::type P;
+        typedef typename coordinate_type<B>::type T;
+
+        /// Internal structure to check if access is OK for all dimensions
+        template <size_t C, size_t D, size_t N>
+        struct dimension_checker
+        {
+            static void check()
+            {
+                const B* b = 0;
+                T coord(ggl::get<C, D>(*b));
+                boost::ignore_unused_variable_warning(coord);
+                dimension_checker<C, D + 1, N>::check();
+            }
+        };
+
+        template <size_t C, size_t N>
+        struct dimension_checker<C, N, N>
+        {
+            static void check() {}
+        };
+
+    public :
+        /// BCCL macro to check the ConstBox concept
+        BOOST_CONCEPT_USAGE(ConstBox)
+        {
+            static const size_t N = dimension<B>::value;
+            dimension_checker<min_corner, 0, N>::check();
+            dimension_checker<max_corner, 0, N>::check();
+        }
+};
+
+}} // namespace ggl::concept
+
+
+#endif // GGL_CORE_CONCEPTS_BOX_CONCEPT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/concepts/linestring_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/concepts/linestring_concept.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,84 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_CONCEPTS_LINESTRING_CONCEPT_HPP
+#define GGL_CORE_CONCEPTS_LINESTRING_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/range/concepts.hpp>
+
+#include <ggl/core/concepts/point_concept.hpp>
+
+
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/point_type.hpp>
+
+#include <ggl/algorithms/clear.hpp>
+#include <ggl/algorithms/append.hpp>
+
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+    \brief Checks linestring concept, using Boost Concept Check Library and metafunctions
+    \ingroup concepts
+*/
+template <typename L>
+struct Linestring
+{
+    private :
+        typedef typename point_type<L>::type P;
+
+        BOOST_CONCEPT_ASSERT( (concept::Point<P>) );
+        BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<L>) );
+
+    public :
+        /// BCCL macro to check the Linestring concept
+        BOOST_CONCEPT_USAGE(Linestring)
+        {
+
+            // Check if it can be modified
+            L* ls;
+            clear(*ls);
+            append(*ls, P());
+        }
+};
+
+
+/*!
+    \brief Checks Linestring concept (const version)
+    \ingroup concepts
+    \details The ConstLinestring concept check the same as the Linestring concept,
+    but does not check write access.
+*/
+template <typename L>
+struct ConstLinestring
+{
+    private :
+        typedef typename point_type<L>::type P;
+
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P>) );
+        BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<L>) );
+
+
+    public :
+        /// BCCL macro to check the ConstLinestring concept
+        BOOST_CONCEPT_USAGE(ConstLinestring)
+        {
+        }
+};
+
+}} // namespace ggl::concept
+
+
+#endif // GGL_CORE_CONCEPTS_LINESTRING_CONCEPT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/concepts/nsphere_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/concepts/nsphere_concept.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,119 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_CONCEPTS_NSPHERE_CONCEPT_HPP
+#define GGL_CORE_CONCEPTS_NSPHERE_CONCEPT_HPP
+
+#include <boost/concept_check.hpp>
+
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/access.hpp>
+#include <ggl/core/radius.hpp>
+
+namespace ggl { namespace concept {
+
+/*!
+    \brief Checks Nsphere concept (const version)
+    \ingroup concepts
+    \details The ConstNsphere concept check the same as the Nsphere concept,
+    but does not check write access.
+*/
+template <typename S>
+struct ConstNsphere
+{
+    private :
+        typedef typename point_type<S>::type P;
+        typedef typename radius_type<S>::type R;
+
+        /// Internal structure to check if access is OK for all dimensions
+        template <size_t D, size_t N>
+        struct dimension_checker
+        {
+            static void check()
+            {
+                typedef typename coordinate_type<S>::type T;
+                const S* s = 0;
+                T coord(ggl::get<D>(*s));
+                (void)sizeof(coord); // To avoid "unused variable" warnings
+                dimension_checker<D + 1, N>::check();
+            }
+        };
+
+        template <size_t N>
+        struct dimension_checker<N, N>
+        {
+            static void check() {}
+        };
+
+    public :
+        /// BCCL macro to check the ConstNsphere concept
+        BOOST_CONCEPT_USAGE(ConstNsphere)
+        {
+            static const size_t N = dimension<S>::value;
+            dimension_checker<0, N>::check();
+            dimension_checker<0, N>::check();
+
+            // Check radius access
+            const S* s = 0;
+            R coord(ggl::get_radius<0>(*s));
+            (void)sizeof(coord); // To avoid "unused variable" warnings
+        }
+};
+
+
+/*!
+    \brief Checks nsphere concept, using Boost Concept Check Library and metafunctions
+    \ingroup concepts
+*/
+template <typename S>
+struct Nsphere
+{
+    private :
+        BOOST_CONCEPT_ASSERT( (concept::ConstNsphere<S>) );
+
+        typedef typename point_type<S>::type P;
+        typedef typename radius_type<S>::type R;
+
+        /// Internal structure to check if access is OK for all dimensions
+        template <size_t D, size_t N>
+        struct dimension_checker
+        {
+            static void check()
+            {
+                S* s;
+                ggl::set<D>(*s, ggl::get<D>(*s));
+                dimension_checker<D + 1, N>::check();
+            }
+        };
+
+        template <size_t N>
+        struct dimension_checker<N, N>
+        {
+            static void check() {}
+        };
+
+    public :
+        /// BCCL macro to check the Nsphere concept
+        BOOST_CONCEPT_USAGE(Nsphere)
+        {
+            static const size_t N = dimension<S>::value;
+            dimension_checker<0, N>::check();
+            dimension_checker<0, N>::check();
+
+            // Check radius access
+            S* s = 0;
+            set_radius<0>(*s, get_radius<0>(*s));
+
+        }
+};
+
+
+
+}} // namespace ggl::concept
+
+#endif // GGL_CORE_CONCEPTS_NSPHERE_CONCEPT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/concepts/point_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/concepts/point_concept.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,146 @@
+// Generic Geometry Library Point concept
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_CONCEPTS_POINT_CONCEPT_HPP
+#define GGL_CORE_CONCEPTS_POINT_CONCEPT_HPP
+
+#include <cstddef>
+
+#include <boost/concept_check.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/coordinate_system.hpp>
+
+
+/*!
+\defgroup concepts concept checking
+Concepts are used to check if pointtypes provide required implementation. Concept checking
+is done using BCCL (Boost Concept Check Library) and MPL (Meta Programming Library)
+*/
+
+namespace ggl { namespace concept {
+
+/*!
+    \brief Checks point concept, using Boost Concept Check Library and metafunctions
+    \ingroup concepts
+    \details The concept is separated into 4 metafunctions:
+    - \ref ggl::traits::coordinate_type "coordinate_type": provides the type of the coordinates of a point
+    - \ref ggl::traits::coordinate_system "coordinate system": provides the coordinate system in which the point is placed
+    - \ref ggl::traits::dimension "dimension": provides the number of coordinates of a point
+    - \ref ggl::traits::access "access": provides access to the coordinates of a point
+
+    In MPL, a metafunction that provides a type must expose is as "type"
+    and a metafunction that provides a value must expose it as "value", so
+    here the same convention are used: coordinate_type<P>::type and
+    dimension<P>::value provide the type and number of coordinates. This
+    makes them compatible with any MPL and Fusion algorithm and
+    metafunction.
+
+    \par Example:
+    First example, using an own pointtype, for example a legacy point, defining the necessary
+    properties outside the pointtype in a traits class
+    \dontinclude doxygen_examples.cpp
+    \skip example_point_1
+    \until //:\\
+    \par Example:
+    Second example, deriving a pointtype from boost::tuple. It defines the necessary properties
+    itself, so a separate traits class is not necessary.
+    \dontinclude doxygen_examples.cpp
+    \skip example_own_point2
+    \line {
+    \until //:\\
+*/
+
+template <typename X>
+struct Point
+{
+private:
+
+    typedef typename coordinate_type<X>::type ctype;
+    typedef typename coordinate_system<X>::type csystem;
+
+    enum { ccount = dimension<X>::value };
+
+    /// Internal structure to check if access is OK for all dimensions
+    template <typename P, std::size_t I, std::size_t Count>
+    struct dimension_checker
+    {
+        static void check()
+        {
+            P* p;
+            ggl::set<I>(*p, ggl::get<I>(*p));
+            dimension_checker<P, I+1, Count>::check();
+        }
+    };
+
+    /// Internal structure to check if access is OK for all dimensions
+    template <typename P, std::size_t Count>
+    struct dimension_checker<P, Count, Count>
+    {
+        static void check() {}
+    };
+
+public:
+
+    /// BCCL macro to check the Point concept
+    BOOST_CONCEPT_USAGE(Point)
+    {
+        dimension_checker<X, 0, ccount>::check();
+    }
+};
+
+
+/*!
+    \brief Checks point concept (const version)
+    \ingroup concepts
+    \details The ConstPoint concept check the same as the Point concept,
+    but does not check write access.
+*/
+template <typename X>
+struct ConstPoint
+{
+private:
+
+    typedef typename coordinate_type<X>::type ctype;
+    typedef typename coordinate_system<X>::type csystem;
+
+    enum { ccount = dimension<X>::value };
+
+    /// Internal structure to check if access is OK for all dimensions
+    template <typename P, std::size_t I, std::size_t Count>
+    struct dimension_checker
+    {
+        static void check()
+        {
+            const P* p = 0;
+            ctype coord(ggl::get<I>(*p));
+            boost::ignore_unused_variable_warning(coord);
+            dimension_checker<P, I+1, Count>::check();
+        }
+    };
+
+    /// Internal structure to check if access is OK for all dimensions
+    template <typename P, std::size_t Count>
+    struct dimension_checker<P, Count, Count>
+    {
+        static void check() {}
+    };
+
+public:
+
+    /// BCCL macro to check the ConstPoint concept
+    BOOST_CONCEPT_USAGE(ConstPoint)
+    {
+        dimension_checker<X, 0, ccount>::check();
+    }
+};
+
+}} // namespace ggl::concept
+
+#endif // GGL_CORE_CONCEPTS_POINT_CONCEPT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/concepts/polygon_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/concepts/polygon_concept.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,120 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_CONCEPTS_POLYGON_CONCEPT_HPP
+#define GGL_CORE_CONCEPTS_POLYGON_CONCEPT_HPP
+
+#include <boost/concept_check.hpp>
+#include <boost/range/concepts.hpp>
+
+#include <ggl/algorithms/append.hpp>
+#include <ggl/algorithms/clear.hpp>
+#include <ggl/core/access.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/core/concepts/ring_concept.hpp>
+
+namespace ggl { namespace concept {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename P>
+struct PolygonChecker
+{
+    typedef typename point_type<P>::type PNT;
+    typedef typename ring_type<P>::type R;
+    typedef typename interior_type<P>::type I;
+
+    BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<I>) );
+
+    void constraints()
+    {
+        P* poly;
+        R& e = exterior_ring(*poly);
+        const R& ce = exterior_ring(*poly);
+
+        I& i = interior_rings(*poly);
+        const I& ci = interior_rings(*poly);
+
+        boost::ignore_unused_variable_warning(e);
+        boost::ignore_unused_variable_warning(ce);
+        boost::ignore_unused_variable_warning(i);
+        boost::ignore_unused_variable_warning(ci);
+    }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+/*!
+    \brief Checks polygon concept, using Boost Concept Check Library and metafunctions
+    \ingroup concepts
+*/
+template <typename P>
+struct Polygon : detail::PolygonChecker<P>
+{
+private:
+
+    typedef typename point_type<P>::type PNT;
+    typedef typename ring_type<P>::type R;
+    typedef typename interior_type<P>::type I;
+
+    BOOST_CONCEPT_ASSERT( (concept::Point<PNT>) );
+    BOOST_CONCEPT_ASSERT( (concept::Ring<R>) );
+
+public:
+
+    /// BCCL macro to check the Polygon concept
+    BOOST_CONCEPT_USAGE(Polygon)
+    {
+        // Check if it can be modified
+        P* poly;
+        clear(*poly);
+        append(*poly, PNT());
+
+        this->constraints();
+    }
+};
+
+
+/*!
+    \brief Checks Polygon concept (const version)
+    \ingroup concepts
+    \details The ConstPolygon concept check the same as the Polygon concept,
+    but does not check write access.
+*/
+template <typename P>
+struct ConstPolygon : detail::PolygonChecker<P>
+{
+private:
+
+    typedef typename point_type<P>::type PNT;
+    typedef typename ring_type<P>::type R;
+    typedef typename interior_type<P>::type I;
+
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<PNT>) );
+    BOOST_CONCEPT_ASSERT( (concept::ConstRing<R>) );
+
+public:
+
+    /// BCCL macro to check the ConstPolygon concept
+    BOOST_CONCEPT_USAGE(ConstPolygon)
+    {
+        this->constraints();
+    }
+};
+
+}} // namespace ggl::concept
+
+#endif // GGL_CORE_CONCEPTS_POLYGON_CONCEPT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/concepts/ring_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/concepts/ring_concept.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,83 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_CONCEPTS_RING_CONCEPT_HPP
+#define GGL_CORE_CONCEPTS_RING_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/range/concepts.hpp>
+
+#include <ggl/core/concepts/point_concept.hpp>
+
+
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/point_type.hpp>
+
+#include <ggl/algorithms/clear.hpp>
+#include <ggl/algorithms/append.hpp>
+
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+    \brief Checks (linear) Ring concept, using Boost Concept Check Library and metafunctions
+    \ingroup concepts
+*/
+template <typename R>
+struct Ring
+{
+    private :
+        typedef typename point_type<R>::type P;
+
+        BOOST_CONCEPT_ASSERT( (concept::Point<P>) );
+        BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<R>) );
+
+
+    public :
+        /// BCCL macro to check the Ring concept
+        BOOST_CONCEPT_USAGE(Ring)
+        {
+            // Check if it can be modified
+            R* ls;
+            clear(*ls);
+            append(*ls, P());
+        }
+};
+
+
+/*!
+    \brief Checks (linear) ring concept (const version)
+    \ingroup concepts
+    \details The ConstLinearRing concept check the same as the Ring concept,
+    but does not check write access.
+*/
+template <typename R>
+struct ConstRing
+{
+    private :
+        typedef typename point_type<R>::type P;
+
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P>) );
+        BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<R>) );
+
+    public :
+        /// BCCL macro to check the ConstLinearRing concept
+        BOOST_CONCEPT_USAGE(ConstRing)
+        {
+        }
+};
+
+}} // namespace ggl::concept
+
+
+#endif // GGL_CORE_CONCEPTS_RING_CONCEPT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/concepts/segment_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/concepts/segment_concept.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,119 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_CONCEPTS_SEGMENT_CONCEPT_HPP
+#define GGL_CORE_CONCEPTS_SEGMENT_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+
+#include <ggl/core/concepts/point_concept.hpp>
+
+
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/point_type.hpp>
+
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+    \brief Checks segment concept, using Boost Concept Check Library and metafunctions
+    \ingroup concepts
+*/
+template <typename S>
+struct Segment
+{
+    private :
+        typedef typename point_type<S>::type P;
+
+        BOOST_CONCEPT_ASSERT( (concept::Point<P>) );
+
+
+        /// Internal structure to check if access is OK for all dimensions
+        template <size_t C, size_t D, size_t N>
+        struct dimension_checker
+        {
+            static void check()
+            {
+                S* s;
+                ggl::set<C, D>(*s, ggl::get<C, D>(*s));
+                dimension_checker<C, D + 1, N>::check();
+            }
+        };
+
+        template <size_t C, size_t N>
+        struct dimension_checker<C, N, N>
+        {
+            static void check() {}
+        };
+
+    public :
+        /// BCCL macro to check the Segment concept
+        BOOST_CONCEPT_USAGE(Segment)
+        {
+            static const size_t N = dimension<P>::value;
+            dimension_checker<0, 0, N>::check();
+            dimension_checker<1, 0, N>::check();
+        }
+};
+
+
+/*!
+    \brief Checks Segment concept (const version)
+    \ingroup concepts
+    \details The ConstSegment concept check the same as the Segment concept,
+    but does not check write access.
+*/
+template <typename S>
+struct ConstSegment
+{
+    private :
+        typedef typename point_type<S>::type P;
+        typedef typename coordinate_type<S>::type T;
+
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P>) );
+
+
+        /// Internal structure to check if access is OK for all dimensions
+        template <size_t C, size_t D, size_t N>
+        struct dimension_checker
+        {
+            static void check()
+            {
+                const S* s = 0;
+                T coord(ggl::get<C, D>(*s));
+                boost::ignore_unused_variable_warning(coord);
+                dimension_checker<C, D + 1, N>::check();
+            }
+        };
+
+        template <size_t C, size_t N>
+        struct dimension_checker<C, N, N>
+        {
+            static void check() {}
+        };
+
+    public :
+        /// BCCL macro to check the ConstSegment concept
+        BOOST_CONCEPT_USAGE(ConstSegment)
+        {
+            static const size_t N = dimension<P>::value;
+            dimension_checker<0, 0, N>::check();
+            dimension_checker<1, 0, N>::check();
+        }
+};
+
+
+}} // namespace ggl::concept
+
+
+#endif // GGL_CORE_CONCEPTS_SEGMENT_CONCEPT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/coordinate_dimension.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/coordinate_dimension.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,111 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_COORDINATE_DIMENSION_HPP
+#define GGL_CORE_COORDINATE_DIMENSION_HPP
+
+#include <cstddef>
+
+#include <boost/mpl/equal_to.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/point_type.hpp>
+
+namespace ggl
+{
+
+namespace traits
+{
+
+/*!
+    \brief Traits class indicating the number of dimensions of a point
+    \par Geometries:
+        - point
+    \par Specializations should provide:
+        - value (should be derived from boost::mpl::int_<D>
+    \ingroup traits
+*/
+template <typename P>
+struct dimension {};
+
+} // namespace traits
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+// Base class derive from its own specialization of point-tag
+template <typename T, typename G>
+struct dimension : dimension<point_tag, typename point_type<T, G>::type> {};
+
+template <typename P>
+struct dimension<point_tag, P> : traits::dimension<P> {};
+
+} // namespace core_dispatch
+#endif
+
+/*!
+    \brief Meta-function which defines coordinate dimensions, i.e. the number of axes of any geometry
+    \ingroup core
+*/
+template <typename G>
+struct dimension
+    : core_dispatch::dimension
+        <
+        typename tag<G>::type,
+        typename boost::remove_const<G>::type
+        >
+{};
+
+/*!
+    \brief assert_dimension, enables compile-time checking if coordinate dimensions are as expected
+    \ingroup utility
+*/
+template <typename G, int D>
+inline void assert_dimension()
+{
+    BOOST_STATIC_ASSERT((
+        boost::mpl::equal_to
+        <
+        ggl::dimension<G>,
+        boost::mpl::int_<D>
+        >::type::value
+        ));
+}
+
+/*!
+    \brief assert_dimension, enables compile-time checking if coordinate dimensions are as expected
+    \ingroup utility
+*/
+template <typename G, int D>
+inline void assert_dimension_less_equal()
+{
+    BOOST_STATIC_ASSERT(( dimension<G>::type::value <= D ));
+}
+
+template <typename G, int D>
+inline void assert_dimension_greater_equal()
+{
+    BOOST_STATIC_ASSERT(( dimension<G>::type::value >= D ));
+}
+
+/*!
+    \brief assert_dimension_equal, enables compile-time checking if coordinate dimensions of two geometries are equal
+    \ingroup utility
+*/
+template <typename G1, typename G2>
+inline void assert_dimension_equal()
+{
+    BOOST_STATIC_ASSERT(( dimension<G1>::type::value == dimension<G2>::type::value ));
+}
+
+} // namespace ggl
+
+#endif // GGL_CORE_COORDINATE_DIMENSION_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/coordinate_system.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/coordinate_system.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,79 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_COORDINATE_SYSTEM_HPP
+#define GGL_CORE_COORDINATE_SYSTEM_HPP
+
+
+#include <boost/type_traits/remove_const.hpp>
+#include <ggl/core/point_type.hpp>
+
+
+namespace ggl
+{
+
+namespace traits
+{
+
+    /*!
+        \brief Traits class defining the coordinate system of a point, important for strategy selection
+        \ingroup traits
+        \par Geometries:
+            - point
+        \par Specializations should provide:
+            - typedef CS type; (cs::cartesian, cs::spherical, etc)
+    */
+    template <typename P>
+    struct coordinate_system {};
+
+} // namespace traits
+
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+    template <typename GeometryTag, typename G>
+    struct coordinate_system
+    {
+        typedef typename point_type<GeometryTag, G>::type P;
+
+        // Call its own specialization on point-tag
+        typedef typename coordinate_system<point_tag, P>::type type;
+    };
+
+
+    template <typename P>
+    struct coordinate_system<point_tag, P>
+    {
+        typedef typename traits::coordinate_system<P>::type type;
+    };
+
+
+} // namespace core_dispatch
+#endif
+
+
+/*!
+    \brief Meta-function which defines coordinate system for any geometry
+    \ingroup core
+*/
+template <typename G>
+struct coordinate_system
+{
+    typedef typename boost::remove_const<G>::type ncg;
+    typedef typename core_dispatch::coordinate_system<
+        typename tag<G>::type, ncg>::type type;
+};
+
+}
+
+
+#endif // GGL_CORE_COORDINATE_SYSTEM_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/coordinate_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/coordinate_type.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,72 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_COORDINATE_TYPE_HPP
+#define GGL_CORE_COORDINATE_TYPE_HPP
+
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/point_type.hpp>
+
+namespace ggl {
+
+namespace traits {
+
+/*!
+    \brief Traits class which indicate the coordinate type (double,float,...) of a point
+    \ingroup traits
+    \par Geometries:
+        - point
+    \par Specializations should provide:
+        - typedef T type; (double,float,int,etc)
+*/
+template <typename P>
+struct coordinate_type {};
+
+} // namespace traits
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename GeometryTag, typename G>
+struct coordinate_type
+{
+    typedef typename point_type<GeometryTag, G>::type point_type;
+
+    // Call its own specialization on point-tag
+    typedef typename coordinate_type<point_tag, point_type>::type type;
+};
+
+template <typename P>
+struct coordinate_type<point_tag, P>
+{
+    typedef typename traits::coordinate_type<P>::type type;
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+/*!
+    \brief Meta-function which defines coordinate type (int, float, double, etc) of any geometry
+    \ingroup core
+*/
+template <typename G>
+struct coordinate_type
+{
+    typedef typename boost::remove_const<G>::type ncg;
+    typedef typename core_dispatch::coordinate_type
+        <
+            typename tag<G>::type,
+            ncg
+        >::type type;
+};
+
+} // namespace ggl
+
+#endif // GGL_CORE_COORDINATE_TYPE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/cs.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/cs.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,234 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_CS_HPP
+#define GGL_CORE_CS_HPP
+
+#include <cstddef>
+
+#include <boost/type_traits.hpp>
+
+#include <ggl/core/coordinate_system.hpp>
+#include <ggl/core/tags.hpp>
+
+/*!
+\defgroup cs coordinate systems
+\brief Defines coordinate systems
+\details Coordinate systems are essential for any point in the Generic Geometry Library. Many
+algorithms such as distance or transform use coordinate systems to select the strategy to use.
+*/
+
+namespace ggl
+{
+
+/*!
+    \brief Unit of plan angles: degrees
+    \ingroup utility
+*/
+class degree {};
+
+
+/*!
+    \brief Unit of plan angles: radians
+    \ingroup utility
+*/
+class radian {};
+
+namespace cs
+{
+
+/*!
+    \brief Cartesian coordinate system
+    \details Defines the Cartesian or rectangular coordinate system where points are defined in 2 or 3 (or more)
+    dimensions and usually (but not always) known as x,y,z
+    \see http://en.wikipedia.org/wiki/Cartesian_coordinate_system
+    \ingroup cs
+*/
+struct cartesian {};
+
+
+/*!
+    \brief EPSG Cartesian coordinate system
+    \details EPSG (European Petrol Survey Group) has a standard list of projections,
+        each having a code
+    \see
+    \ingroup cs
+    \tparam Code the EPSG code
+    \todo Maybe derive from boost::mpl::int_<EpsgCode>
+*/
+template<std::size_t Code>
+struct epsg
+{
+    static const std::size_t epsg_code = Code;
+};
+
+
+/*!
+    \brief Geographic coordinate system, in degree or in radian
+    \details Defines the geographic coordinate system where points are defined in two angles and usually
+    known as lat,long or lo,la or phi,lambda
+    \see http://en.wikipedia.org/wiki/Geographic_coordinate_system
+    \ingroup cs
+*/
+template<typename DegreeOrRadian>
+struct geographic
+{
+    typedef DegreeOrRadian units;
+};
+
+/*!
+    \brief Earth Centered, Earth Fixed
+    \details Defines a Cartesian coordinate system x,y,z with the center of the earth as its origin,
+        going through the Greenwich
+    \see http://en.wikipedia.org/wiki/ECEF
+    \see http://en.wikipedia.org/wiki/Geodetic_system
+    \note Also known as "Geocentric", but geocentric is also an astronomic coordinate system
+    \ingroup cs
+*/
+struct ecef
+{
+};
+
+/*!
+    \brief Spherical coordinate system, in degree or in radian
+    \details Defines the spherical coordinate system where points are defined in two angles
+        and an optional radius usually known as r, theta, phi
+    \par Coordinates:
+    - coordinate 0:
+        0 <= phi < 2pi is the angle between the positive x-axis and the line from the origin to the P projected onto the xy-plane.
+    - coordinate 1:
+        0 <= theta <= pi is the angle between the positive z-axis and the line formed between the origin and P.
+    - coordinate 2 (if specified):
+        r >= 0 is the distance from the origin to a given point P.
+
+    \see http://en.wikipedia.org/wiki/Spherical_coordinates
+    \ingroup cs
+*/
+template<typename DegreeOrRadian>
+struct spherical
+{
+    typedef DegreeOrRadian units;
+};
+
+/*!
+    \brief Polar coordinate system
+    \details Defines the polar coordinate system "in which each point on a plane is determined by an angle and a distance"
+    \see http://en.wikipedia.org/wiki/Polar_coordinates
+    \ingroup cs
+*/
+template<typename DegreeOrRadian>
+struct polar
+{
+    typedef DegreeOrRadian units;
+};
+
+
+namespace celestial
+{
+
+/*!
+    \brief Ecliptic (celestial) coordinate system
+    \details Defines the astronomical ecliptic coordinate system "that uses the ecliptic for its fundamental plane"
+    It uses Beta and Lambda as its latitude and longitude.
+    \see http://en.wikipedia.org/wiki/Ecliptic_coordinate_system
+    \ingroup cs
+*/
+template<typename DegreeOrRadian>
+struct ecliptic
+{
+    typedef DegreeOrRadian units;
+};
+
+// TODO: More celestial coordinate systems could be defined
+
+} // namespace celestial
+
+} // namespace cs
+
+namespace traits
+{
+/*!
+    \brief Traits class defining coordinate system tag, bound to coordinate system
+    \ingroup traits
+    \tparam CoordinateSystem coordinate system
+*/
+template <typename CoordinateSystem>
+struct cs_tag
+{
+};
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+template<typename DegreeOrRadian>
+struct cs_tag<cs::geographic<DegreeOrRadian> >
+{
+    typedef geographic_tag type;
+};
+
+template<typename DegreeOrRadian>
+struct cs_tag<cs::spherical<DegreeOrRadian> >
+{
+    typedef spherical_tag type;
+};
+
+template<>
+struct cs_tag<cs::cartesian>
+{
+    typedef cartesian_tag type;
+};
+
+template<>
+struct cs_tag<cs::ecef>
+{
+    typedef cartesian_tag type;
+};
+
+template <std::size_t C>
+struct cs_tag<cs::epsg<C> >
+{
+    typedef cartesian_tag type;
+};
+
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+} // namespace traits
+
+/*!
+    \brief Meta-function returning coordinate system tag (cs family) of any geometry
+    \ingroup core
+*/
+template <typename G>
+struct cs_tag
+{
+    typedef typename traits::cs_tag
+        <
+        typename ggl::coordinate_system<G>::type
+        >::type type;
+};
+
+
+/*!
+    \brief Meta-function to verify if a coordinate system is radian
+    \ingroup core
+*/
+template <typename CoordinateSystem>
+struct is_radian : boost::true_type {};
+
+
+#ifndef DOXYGEN_NO_SPECIALIZATIONS
+
+// Specialization for any degree coordinate systems
+template <template<typename> class CoordinateSystem>
+struct is_radian< CoordinateSystem<degree> > : boost::false_type
+{
+};
+
+#endif // DOXYGEN_NO_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_CORE_CS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/exception.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/exception.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,26 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_EXCEPTION_HPP
+#define GGL_CORE_EXCEPTION_HPP
+
+#include <exception>
+
+namespace ggl {
+
+/*!
+\brief Base exception class for GGL
+\ingroup core
+*/
+struct exception : public std::exception
+{
+};
+
+} // namespace ggl
+
+#endif // GGL_CORE_EXCEPTION_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/exterior_ring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/exterior_ring.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,100 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_EXTERIOR_RING_HPP
+#define GGL_CORE_EXTERIOR_RING_HPP
+
+
+#include <boost/type_traits/remove_const.hpp>
+
+
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+namespace ggl {
+
+namespace traits {
+
+/*!
+    \brief Traits class defining access to exterior_ring of a polygon
+    \details Should define const and non const access
+    \ingroup traits
+    \tparam G geometry
+    \par Geometries:
+        - polygon
+    \par Specializations should provide:
+        - static inline RING& get(POLY& )
+        - static inline const RING& get(const POLY& )
+*/
+template <typename P>
+struct exterior_ring {};
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename T, typename G>
+struct exterior_ring {};
+
+template <typename P>
+struct exterior_ring<polygon_tag, P>
+{
+    static inline typename ring_type<polygon_tag, P>::type& get(P& polygon)
+    {
+        return traits::exterior_ring<P>::get(polygon);
+    }
+
+    static inline const typename ring_type<polygon_tag, P>::type& get(const P& polygon)
+    {
+        return traits::exterior_ring<P>::get(polygon);
+    }
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Function to get the exterior_ring ring of a polygon
+    \ingroup access
+    \note OGC compliance: instead of ExteriorRing
+    \tparam P polygon type
+    \param polygon the polygon to get the exterior ring from
+    \return a reference to the exterior ring
+*/
+template <typename P>
+inline typename ring_type<P>::type& exterior_ring(P& polygon)
+{
+    return core_dispatch::exterior_ring<typename tag<P>::type, P>::get(polygon);
+}
+
+/*!
+    \brief Function to get the exterior ring of a polygon (const version)
+    \ingroup access
+    \note OGC compliance: instead of ExteriorRing
+    \tparam P polygon type
+    \param polygon the polygon to get the exterior ring from
+    \return a const reference to the exterior ring
+*/
+template <typename P>
+inline const typename ring_type<P>::type& exterior_ring(const P& polygon)
+{
+    return core_dispatch::exterior_ring<typename tag<P>::type, P>::get(polygon);
+}
+
+
+} // namespace ggl
+
+
+#endif // GGL_CORE_EXTERIOR_RING_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/geometry_id.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/geometry_id.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,80 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_GEOMETRY_ID_HPP
+#define GGL_CORE_GEOMETRY_ID_HPP
+
+
+#include <boost/mpl/int.hpp>
+#include <boost/type_traits.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename GeometryTag>
+struct geometry_id {};
+
+
+template <>
+struct geometry_id<point_tag>      : boost::mpl::int_<1> {};
+
+
+template <>
+struct geometry_id<linestring_tag> : boost::mpl::int_<2> {};
+
+
+template <>
+struct geometry_id<polygon_tag>    : boost::mpl::int_<3> {};
+
+
+template <>
+struct geometry_id<nsphere_tag>    : boost::mpl::int_<91> {};
+
+
+template <>
+struct geometry_id<segment_tag>    : boost::mpl::int_<92> {};
+
+
+template <>
+struct geometry_id<ring_tag>       : boost::mpl::int_<93> {};
+
+
+template <>
+struct geometry_id<box_tag>        : boost::mpl::int_<94> {};
+
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+/*!
+    \brief Meta-function the id for a geometry type
+    \note Used for e.g. reverse meta-function
+    \ingroup core
+*/
+template <typename Geometry>
+struct geometry_id : core_dispatch::geometry_id<typename tag<Geometry>::type>
+{};
+
+
+} // namespace ggl
+
+
+#endif // GGL_CORE_GEOMETRY_ID_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/interior_rings.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/interior_rings.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,165 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_INTERIOR_RINGS_HPP
+#define GGL_CORE_INTERIOR_RINGS_HPP
+
+
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+namespace ggl
+{
+
+namespace traits
+{
+
+    /*!
+        \brief Traits class indicating interior container type of a polygon
+        \details defines inner container type, so the container containing the interior rings
+        \ingroup traits
+        \par Geometries:
+            - polygon
+        \par Specializations should provide:
+            - typedef CONTAINER<RING<P> > type (e.g. std::vector<linear_ring<P> >)
+        \tparam G geometry
+    */
+    template <typename G>
+    struct interior_type { };
+
+
+    /*!
+        \brief Traits class defining access to interior_rings of a polygon
+        \details defines access (const and non const) to interior ring
+        \ingroup traits
+        \par Geometries:
+            - polygon
+        \par Specializations should provide:
+            - static inline INTERIOR& get(POLY&)
+            - static inline const INTERIOR& get(const POLY&)
+        \tparam G geometry
+    */
+    template <typename G>
+    struct interior_rings
+    {
+    };
+
+
+} // namespace traits
+
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+    template <typename GeometryTag, typename G> struct interior_type {};
+
+    template <typename P>
+    struct interior_type<polygon_tag, P>
+    {
+        typedef typename traits::interior_type<P>::type type;
+    };
+
+
+
+    template <typename GeometryTag, typename G>
+    struct interior_rings {};
+
+
+    template <typename P>
+    struct interior_rings<polygon_tag, P>
+    {
+        static inline typename interior_type<polygon_tag, P>::type& get(P& polygon)
+        {
+            return traits::interior_rings<P>::get(polygon);
+        }
+
+        static inline const typename interior_type<polygon_tag, P>::type& get(const P& polygon)
+        {
+            return traits::interior_rings<P>::get(polygon);
+        }
+    };
+
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+
+/*!
+    \brief Meta-function defining container type of inner rings of (multi)polygon geometriy
+    \details the interior rings should be organized as a container (std::vector, std::deque, boost::array) with
+        boost range support. This meta function defines the type of that container.
+    \ingroup core
+*/
+template <typename G>
+struct interior_type
+{
+    typedef typename boost::remove_const<G>::type ncg;
+    typedef typename core_dispatch::interior_type<
+        typename tag<G>::type, ncg>::type type;
+};
+
+
+
+/*!
+    \brief Function to get the interior rings of a polygon (non const version)
+    \ingroup access
+    \note OGC compliance: instead of InteriorRingN
+    \tparam P polygon type
+    \param polygon the polygon to get the interior rings from
+    \return a reference to the interior rings
+*/
+template <typename P>
+inline typename interior_type<P>::type& interior_rings(P& polygon)
+{
+    return core_dispatch::interior_rings<typename tag<P>::type, P>::get(polygon);
+}
+
+
+/*!
+    \brief Function to get the interior rings of a polygon (const version)
+    \ingroup access
+    \note OGC compliance: instead of InteriorRingN
+    \tparam P polygon type
+    \param polygon the polygon to get the interior rings from
+    \return a const reference to the interior rings
+*/
+template <typename P>
+inline const typename interior_type<P>::type& interior_rings(const P& polygon)
+{
+    return core_dispatch::interior_rings<typename tag<P>::type, P>::get(polygon);
+}
+
+
+
+/*!
+    \brief Function to get the number of interior rings of a polygon
+    \ingroup access
+    \note Defined by OGC as "numInteriorRing". To be consistent with "numPoints"
+        letter "s" is appended
+    \tparam P polygon type
+    \param polygon the polygon
+    \return the nubmer of interior rings
+*/
+template <typename P>
+inline size_t num_interior_rings(const P& polygon)
+{
+    return boost::size(interior_rings(polygon));
+}
+
+}
+
+
+#endif // GGL_CORE_INTERIOR_RINGS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/is_linear.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/is_linear.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,59 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_IS_LINEAR_HPP
+#define GGL_CORE_IS_LINEAR_HPP
+
+
+#include <boost/type_traits.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename GeometryTag>
+struct is_linear : boost::false_type {};
+
+
+template <>
+struct is_linear<linestring_tag> : boost::true_type {};
+
+
+template <>
+struct is_linear<ring_tag>       : boost::true_type {};
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+/*!
+    \brief Meta-function defining "true" for linear types (linestring,ring),
+        "false" for non-linear typse
+    \note Used for tag dispatching and meta-function finetuning
+    \ingroup core
+*/
+template <typename Geometry>
+struct is_linear : core_dispatch::is_linear<typename tag<Geometry>::type>
+{};
+
+
+} // namespace ggl
+
+
+#endif // GGL_CORE_IS_LINEAR_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/is_multi.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/is_multi.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,49 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_IS_MULTI_HPP
+#define GGL_CORE_IS_MULTI_HPP
+
+
+#include <boost/type_traits.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename GeometryTag>
+struct is_multi : boost::false_type {};
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+
+/*!
+    \brief Meta-function defining "true" for multi geometries (multi_point, etc)
+    \ingroup core
+*/
+template <typename Geometry>
+struct is_multi : core_dispatch::is_multi<typename tag<Geometry>::type>
+{};
+
+
+} // namespace ggl
+
+#endif // GGL_CORE_IS_MULTI_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/point_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/point_type.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,109 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_POINT_TYPE_HPP
+#define GGL_CORE_POINT_TYPE_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+namespace ggl {
+
+namespace traits {
+
+/*!
+    \brief Traits class indicating the type of contained points
+    \ingroup traits
+    \par Geometries:
+        - all geometries except point
+    \par Specializations should provide:
+        - typedef P type (where P should fulfil the Point concept)
+    \tparam G geometry
+*/
+template <typename G>
+struct point_type
+{};
+
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct point_type
+{
+    // Default: call traits to get point type
+    typedef typename boost::remove_const
+        <
+            typename traits::point_type<Geometry>::type
+        >::type type;
+};
+
+
+// Specialization for point: the point itself
+template <typename Point>
+struct point_type<point_tag, Point>
+{
+    typedef Point type;
+};
+
+// Specializations for linestring/linear ring, via boost::range
+template <typename Linestring>
+struct point_type<linestring_tag, Linestring>
+{
+    typedef typename boost::range_value<Linestring>::type type;
+};
+
+template <typename Ring>
+struct point_type<ring_tag, Ring>
+{
+    typedef typename boost::range_value<Ring>::type type;
+};
+
+// Specialization for polygon: the point-type is the point-type of its rinsg
+template <typename Polygon>
+struct point_type<polygon_tag, Polygon>
+{
+    typedef typename point_type
+        <
+            ring_tag,
+            typename ring_type<polygon_tag, Polygon>::type
+        >::type type;
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Meta-function which defines point type of any geometry
+    \ingroup core
+*/
+template <typename Geometry>
+struct point_type
+{
+    typedef typename boost::remove_const<Geometry>::type ncg;
+    typedef typename core_dispatch::point_type<
+        typename tag<Geometry>::type, ncg>::type type;
+
+
+
+
+};
+
+} // namespace ggl
+
+#endif // GGL_CORE_POINT_TYPE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/radian_access.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/radian_access.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,118 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_RADIAN_ACCESS_HPP
+#define GGL_CORE_RADIAN_ACCESS_HPP
+
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/cs.hpp>
+
+
+#include <ggl/util/math.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail {
+
+template <std::size_t D, typename G, typename DR>
+struct radian_access
+{
+};
+
+template <std::size_t D, typename G, template<typename> class CS>
+struct radian_access<D, G, CS<radian> >
+{
+    typedef typename coordinate_type<G>::type coordinate_type;
+
+    static inline coordinate_type get(G const& geometry)
+    {
+        return ggl::get<D>(geometry);
+    }
+
+    static inline void set(G& geometry, coordinate_type const& radians)
+    {
+        ggl::set<D>(geometry, radians);
+    }
+};
+
+template <std::size_t D, typename G, template<typename> class CS>
+struct radian_access<D, G, CS<degree> >
+{
+    typedef typename coordinate_type<G>::type coordinate_type;
+
+    static inline coordinate_type get(G const& geometry)
+    {
+        return boost::numeric_cast
+            <
+                coordinate_type
+            >(ggl::get<D>(geometry) * math::d2r);
+    }
+
+    static inline void set(G& geometry, coordinate_type const& radians)
+    {
+        ggl::set<D>(geometry, boost::numeric_cast
+            <
+                coordinate_type
+            >(radians * math::r2d));
+    }
+
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief get a coordinate value of a point, result is in RADIAN
+    \details also if coordinate system was in degree, result is in radian
+    \return coordinate value
+    \ingroup access
+    \tparam D dimension
+    \tparam G geometry
+    \param geometry geometry to get coordinate value from
+*/
+template <std::size_t D, typename G>
+inline typename coordinate_type<G>::type get_as_radian(const G& geometry)
+{
+    return detail::radian_access<D, G,
+            typename coordinate_system<G>::type>::get(geometry);
+}
+
+
+/*!
+    \brief assign coordinate value (which is in radian) to a point
+    \details if coordinate system of point is in degree, will be converted
+        to degree
+    \ingroup access
+    \tparam D dimension
+    \tparam G geometry
+    \param geometry geometry to assign coordinate to
+    \param radians coordinate value to assign
+*/
+template <std::size_t D, typename G>
+inline void set_from_radian(G& geometry,
+            const typename coordinate_type<G>::type& radians)
+{
+    detail::radian_access<D, G,
+            typename coordinate_system<G>::type>::set(geometry, radians);
+}
+
+
+} // namespace ggl
+
+
+#endif // GGL_CORE_RADIAN_ACCESS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/radius.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/radius.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,152 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_RADIUS_HPP
+#define GGL_CORE_RADIUS_HPP
+
+
+#include <cstddef>
+
+
+#include <boost/type_traits/remove_const.hpp>
+
+
+#include <ggl/core/tag.hpp>
+
+
+namespace ggl {
+
+namespace traits {
+
+/*!
+    \brief Traits class to get/set radius of a circle/sphere/(ellipse)
+    \details the radius access meta-functions give read/write access to the radius of a circle or a sphere,
+    or to the major/minor axis or an ellipse, or to one of the 3 equatorial radii of an ellipsoid.
+
+    It should be specialized per geometry, in namespace core_dispatch. Those specializations should
+    forward the call via traits to the geometry class, which could be specified by the user.
+
+    There is a corresponding generic radius_get and radius_set function
+    \par Geometries:
+        - n-sphere (circle,sphere)
+        - upcoming ellipse
+    \par Specializations should provide:
+        - inline static T get(const G& geometry)
+        - inline static void set(G& geometry, const T& radius)
+    \ingroup traits
+*/
+template <typename G, typename T, std::size_t D>
+struct radius_access {};
+
+
+/*!
+    \brief Traits class indicating the type (double,float,...) of the radius of a circle or a sphere
+    \par Geometries:
+        - n-sphere (circle,sphere)
+        - upcoming ellipse
+    \par Specializations should provide:
+        - typedef T type (double,float,int,etc)
+    \ingroup traits
+*/
+template <typename G>
+struct radius_type {};
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename Tag, typename G>
+struct radius_type
+{
+    //typedef core_dispatch_specialization_required type;
+};
+
+/*!
+    \brief radius access meta-functions, used by concept n-sphere and upcoming ellipse.
+*/
+template <typename Tag, typename G, typename T, std::size_t D>
+struct radius_access
+{
+    //static inline T get(const G& ) {}
+    //static inline void set(G& g, const T& value) {}
+};
+
+template <typename S>
+struct radius_type<nsphere_tag, S>
+{
+    typedef typename traits::radius_type<S>::type type;
+};
+
+template <typename S, typename T, std::size_t D>
+struct radius_access<nsphere_tag, S, T, D>
+{
+    BOOST_STATIC_ASSERT((D == 0));
+    static inline T get(const S& s)
+    {
+        return traits::radius_access<S, T, D>::get(s);
+    }
+    static inline void set(S& s, const T& radius)
+    {
+        traits::radius_access<S, T, D>::set(s, radius);
+    }
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template <typename G>
+struct radius_type
+{
+    typedef typename boost::remove_const<G>::type rconst;
+    typedef typename core_dispatch::radius_type<typename tag<G>::type, rconst>::type type;
+};
+
+/*!
+    \brief Function to get radius
+    \return radius of a circle / sphere / ellipse
+    \ingroup access
+    \param geometry the geometry to get the radius from
+    \tparam I index, for circle/sphere always zero, for ellipse major/minor axis,
+        for ellipsoid one of the 3 equatorial radii
+*/
+template <std::size_t I, typename G>
+inline typename radius_type<G>::type get_radius(const G& geometry)
+{
+    typedef typename boost::remove_const<G>::type rconst;
+
+    return core_dispatch::radius_access<typename tag<G>::type, rconst,
+           typename radius_type<G>::type, I>::get(geometry);
+}
+
+/*!
+    \brief Function to set the radius of a circle / sphere / (ellipse)
+    \ingroup access
+    \tparam I index, for circle/sphere always zero, for ellipse major/minor axis,
+        for ellipsoid one of the 3 equatorial radii
+    \param geometry the geometry to change
+    \param radius the radius to set
+*/
+template <std::size_t I, typename G>
+inline void set_radius(G& geometry, const typename radius_type<G>::type& radius)
+{
+    typedef typename boost::remove_const<G>::type rconst;
+
+    core_dispatch::radius_access<typename tag<G>::type, G,
+        typename radius_type<G>::type, I>::set(geometry, radius);
+}
+
+
+} // namespace ggl
+
+
+#endif // GGL_RADIUS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/replace_point_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/replace_point_type.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,99 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_REPLACE_POINT_TYPE_HPP
+#define GGL_CORE_REPLACE_POINT_TYPE_HPP
+
+
+#include <boost/type_traits/remove_const.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+#include <ggl/core/coordinate_type.hpp>
+
+// For now: use ggl-provided geometries
+// TODO: figure out how to get the class and replace the type
+// TODO: take "const" into account
+#include <ggl/geometries/point.hpp>
+#include <ggl/geometries/linestring.hpp>
+#include <ggl/geometries/linear_ring.hpp>
+#include <ggl/geometries/polygon.hpp>
+#include <ggl/geometries/segment.hpp>
+#include <ggl/geometries/box.hpp>
+#include <ggl/geometries/nsphere.hpp>
+
+
+namespace ggl {
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+template <typename GeometryTag, typename Geometry, typename NewPointType>
+struct replace_point_type {};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<point_tag, Geometry, NewPointType>
+{
+    typedef NewPointType type;
+};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<linestring_tag, Geometry, NewPointType>
+{
+    typedef linestring<NewPointType> type;
+};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<segment_tag, Geometry, NewPointType>
+{
+    typedef segment<NewPointType> type;
+};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<ring_tag, Geometry, NewPointType>
+{
+    typedef linear_ring<NewPointType> type;
+};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<box_tag, Geometry, NewPointType>
+{
+    typedef box<NewPointType> type;
+};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<polygon_tag, Geometry, NewPointType>
+{
+    typedef polygon<NewPointType> type;
+};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<nsphere_tag, Geometry, NewPointType>
+{
+    typedef typename ggl::coordinate_type<Geometry>::type coortype;
+    typedef nsphere<NewPointType, coortype> type;
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type : core_dispatch::replace_point_type
+        <
+        typename tag<Geometry>::type,
+        typename boost::remove_const<Geometry>::type,
+        NewPointType
+        >
+{};
+
+} // namespace ggl
+
+#endif // GGL_CORE_REPLACE_POINT_TYPE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/reverse_dispatch.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/reverse_dispatch.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,61 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_REVERSE_DISPATCH_HPP
+#define GGL_CORE_REVERSE_DISPATCH_HPP
+
+
+#include <boost/type_traits.hpp>
+
+#include <boost/mpl/greater.hpp>
+
+#include <ggl/core/geometry_id.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+// Different geometries: reverse_dispatch if second ID < first ID
+// Note: if "boost::mpl::greater is used, with geometry_id instead of geometry_id::type::value,
+// it is not working correctly!!!! TODO: find out why not.
+template <std::size_t GeometryId1, std::size_t GeometryId2>
+struct reverse_dispatch : boost::mpl::if_c
+<
+    (GeometryId1 > GeometryId2),
+    boost::true_type,
+    boost::false_type
+>
+{};
+
+
+// Same geometry: never reverse_dispatch
+template <std::size_t GeometryId>
+struct reverse_dispatch<GeometryId, GeometryId> : boost::false_type {};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+template <typename Geometry1, typename Geometry2>
+struct reverse_dispatch : detail::reverse_dispatch
+    <
+    geometry_id<Geometry1>::type::value,
+    geometry_id<Geometry2>::type::value
+    >
+{};
+
+
+} // namespace ggl
+
+#endif // GGL_CORE_REVERSE_DISPATCH_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/ring_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/ring_type.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,97 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_RING_TYPE_HPP
+#define GGL_CORE_RING_TYPE_HPP
+
+
+#include <boost/type_traits/remove_const.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+namespace ggl
+{
+
+namespace traits
+{
+
+
+/*!
+    \brief Traits class to indicate ring-type  of a polygon's exterior ring/interior rings
+    \ingroup traits
+    \par Geometries:
+        - polygon
+    \par Specializations should provide:
+        - typedef XXX type (e.g. linear_ring<P>)
+    \tparam G geometry
+*/
+template <typename G>
+struct ring_type
+{
+    // should define type
+};
+
+
+
+
+} // namespace traits
+
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+
+template <typename GeometryTag, typename Geometry> struct ring_type
+{};
+
+
+
+template <typename Polygon>
+struct ring_type<polygon_tag, Polygon>
+{
+    typedef typename traits::ring_type<Polygon>::type type;
+};
+
+
+
+
+} // namespace core_dispatch
+#endif
+
+
+/*!
+    \brief Meta-function which defines ring type of (multi)polygon geometry
+    \details a polygon contains one exterior ring and zero or more interior rings (holes).
+        The type of those rings is assumed to be equal. This meta function retrieves the type
+        of such rings.
+    \ingroup core
+*/
+template <typename Geometry>
+struct ring_type
+{
+    typedef typename boost::remove_const<Geometry>::type ncg;
+    typedef typename core_dispatch::ring_type
+        <
+            typename tag<Geometry>::type, ncg
+        >::type type;
+};
+
+
+
+
+}
+
+
+#endif // GGL_CORE_RING_TYPE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/tag.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/tag.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,65 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_TAG_HPP
+#define GGL_CORE_TAG_HPP
+
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/tags.hpp>
+
+/*!
+\defgroup core core: meta-functions for geometry types
+*/
+
+namespace ggl
+{
+
+namespace traits
+{
+
+/*!
+    \brief Traits class to attach a tag to a geometry
+    \details All geometries should implement a traits::tag<G>::type metafunction to indicate their
+        own geometry type.
+    \ingroup traits
+    \par Geometries:
+        - all geometries
+    \par Specializations should provide:
+        - typedef XXX_tag type; (point_tag, box_tag, ...)
+    \tparam Geometry geometry
+*/
+template <typename Geometry>
+struct tag
+{
+    typedef geometry_not_recognized_tag type;
+};
+
+} // namespace traits
+
+
+/*!
+    \brief Meta-function to get the tag of any geometry type
+    \details All geometries tell their geometry type (point, linestring, polygon, etc) by implementing
+      a tag traits class. This meta-function uses that traits class to retrieve the tag.
+      If the input type is not a geometry at all, a geometry_not_recognized_tag will be returned.
+    \tparam Geometry geometry
+    \ingroup core
+*/
+template <typename Geometry>
+struct tag
+{
+    typedef typename traits::tag
+        <
+        typename boost::remove_const<Geometry>::type
+        >::type type;
+};
+
+} // namespace ggl
+
+#endif // GGL_CORE_TAG_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/tags.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/tags.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,64 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_TAGS_HPP
+#define GGL_CORE_TAGS_HPP
+
+
+/*!
+\defgroup traits traits: adapt geometries
+\brief Traits classes are small classes or structs to adapt geometries
+such that they are recognized by the Generic Geometry Library
+*/
+
+namespace ggl
+{
+
+// Tags defining strategies linked to coordinate systems
+
+
+/// Tag indicating Cartesian coordinate system family (cartesian,epsg)
+struct cartesian_tag {};
+
+/// Tag indicating Geographic coordinate system family (geographic)
+struct geographic_tag {};
+
+/// Tag indicating Spherical coordinate system family (spherical,celestial,...)
+struct spherical_tag {};
+
+
+// Tags defining geometry types
+
+
+/// "default" tag
+struct geometry_not_recognized_tag {};
+
+/// OGC Point identifying tag
+struct point_tag {};
+
+/// OGC Linestring identifying tag
+struct linestring_tag {};
+
+/// OGC Polygon identifying tag
+struct polygon_tag {};
+
+/// Convenience (linear) ring identifying tag
+struct ring_tag {};
+
+/// Convenience 2D or 3D box (mbr) identifying tag
+struct box_tag {};
+
+/// Convenience 2D (circle) or 3D (sphere) n-sphere identifying tag
+struct nsphere_tag {};
+
+/// Convenience segment (2-points) identifying tag
+struct segment_tag {};
+
+} // namespace ggl
+
+#endif // GGL_CORE_TAGS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/core/topological_dimension.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/core/topological_dimension.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,89 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_TOPOLOGICAL_DIMENSION_HPP
+#define GGL_CORE_TOPOLOGICAL_DIMENSION_HPP
+
+
+#include <boost/mpl/int.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch {
+
+
+template <typename GeometryTag>
+struct top_dim {};
+
+
+template <>
+struct top_dim<point_tag>      : boost::mpl::int_<0> {};
+
+
+template <>
+struct top_dim<linestring_tag> : boost::mpl::int_<1> {};
+
+
+template <>
+struct top_dim<segment_tag>    : boost::mpl::int_<1> {};
+
+
+// ring: topological dimension of two, but some people say: 1 !!
+template <>
+struct top_dim<ring_tag>       : boost::mpl::int_<2> {};
+
+
+template <>
+struct top_dim<box_tag>        : boost::mpl::int_<2> {};
+
+
+template <>
+struct top_dim<polygon_tag>    : boost::mpl::int_<2> {};
+
+
+// nsphere: 2, but there is discussion. Is it CLOSED? Then 2, but
+// then it should be called "disk"...
+template <>
+struct top_dim<nsphere_tag>    : boost::mpl::int_<2> {};
+
+
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+
+
+/*!
+    \brief Meta-function returning the topological dimension of a geometry
+    \details The topological dimension defines a point as 0-dimensional,
+        a linestring as 1-dimensional,
+        and a ring or polygon as 2-dimensional.
+    \see http://www.math.okstate.edu/mathdept/dynamics/lecnotes/node36.html
+    \ingroup core
+*/
+template <typename Geometry>
+struct topological_dimension
+    : core_dispatch::top_dim<typename tag<Geometry>::type> {};
+
+
+} // namespace ggl
+
+
+#endif // GGL_CORE_TOPOLOGICAL_DIMENSION_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/detail/wkt.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/detail/wkt.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,45 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2008-2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_IO_WKT_DETAIL_WKT_HPP
+#define GGL_IO_WKT_DETAIL_WKT_HPP
+
+
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt {
+
+
+struct prefix_point
+{
+    static inline const char* apply() { return "POINT"; }
+};
+
+struct prefix_polygon
+{
+    static inline const char* apply() { return "POLYGON"; }
+};
+
+struct prefix_linestring
+{
+    static inline const char* apply() { return "LINESTRING"; }
+};
+
+
+
+}} // namespace wkt::impl
+#endif
+
+
+
+} // namescpae ggl
+
+#endif // GGL_IO_WKT_DETAIL_WKT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/detail/wkt_multi.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/detail/wkt_multi.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,51 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2008-2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_IO_WKT_DETAIL_WKT_HPP
+#define GGL_MULTI_IO_WKT_DETAIL_WKT_HPP
+
+
+#include <ggl/extensions/gis/io/wkt/write_wkt.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt {
+
+struct prefix_null
+{
+    static inline const char* apply() { return ""; }
+};
+
+struct prefix_multipoint
+{
+    static inline const char* apply() { return "MULTIPOINT"; }
+};
+
+struct prefix_multilinestring
+{
+    static inline const char* apply() { return "MULTILINESTRING"; }
+};
+
+struct prefix_multipolygon
+{
+    static inline const char* apply() { return "MULTIPOLYGON"; }
+};
+
+
+
+}} // namespace wkt::impl
+#endif
+
+
+
+} // namescpae ggl
+
+#endif // GGL_MULTI_IO_WKT_DETAIL_WKT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/read_wkt.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/read_wkt.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,624 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2008-2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_IO_WKT_READ_WKT_HPP
+#define GGL_EXTENSIONS_GIS_IO_WKT_READ_WKT_HPP
+
+#include <string>
+
+#include <boost/lexical_cast.hpp>
+#include <boost/tokenizer.hpp>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/concept/requires.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/type_traits.hpp>
+
+
+#include <ggl/algorithms/clear.hpp>
+#include <ggl/core/access.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/core/exception.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+
+#include <ggl/extensions/gis/io/wkt/detail/wkt.hpp>
+
+namespace ggl
+{
+
+
+
+/*!
+\brief Exception showing things wrong with WKT parsing
+\ingroup wkt
+*/
+struct read_wkt_exception : public ggl::exception
+{
+    template <typename Iterator>
+    read_wkt_exception(std::string const& msg,
+            Iterator const& it, Iterator const& end, std::string const& wkt)
+        : message(msg)
+        , wkt(wkt)
+    {
+        if (it != end)
+        {
+            source = " at '";
+            source += it->c_str();
+            source += "'";
+        }
+        complete = message + source + " in '" + wkt.substr(0, 100) + "'";
+    }
+
+    read_wkt_exception(std::string const& msg, std::string const& wkt)
+        : message(msg)
+        , wkt(wkt)
+    {
+        complete = message + "' in (" + wkt.substr(0, 100) + ")";
+    }
+
+    virtual ~read_wkt_exception() throw() {}
+
+    virtual const char* what() const throw()
+    {
+        return complete.c_str();
+    }
+private :
+    std::string source;
+    std::string message;
+    std::string wkt;
+    std::string complete;
+};
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+// (wkt: Well Known Text, defined by OGC for all geometries and implemented by e.g. databases (MySQL, PostGIS))
+namespace detail { namespace wkt {
+
+typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+
+template <typename Point, std::size_t Dimension, std::size_t DimensionCount>
+struct parsing_assigner
+{
+    static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+            Point& point, std::string const& wkt)
+    {
+        typedef typename coordinate_type<Point>::type coordinate_type;
+        typedef typename boost::mpl::if_c
+            <
+                boost::is_fundamental<coordinate_type>::type::value,
+                coordinate_type,
+                double
+            >::type type;
+
+
+
+        // Stop at end of tokens, or at "," ot ")"
+        bool finished = (it == end || *it == "," || *it == ")");
+
+        try
+        {
+            // Initialize missing coordinates to default constructor (zero)
+            // OR
+            // Use lexical_cast for conversion to double/int
+            // Note that it is much slower than atof. However, it is more standard
+            // and in parsing the change in performance falls probably away against
+            // the tokenizing
+            set<Dimension>(point, (finished ? type() : boost::lexical_cast<type>(it->c_str())));
+        }
+        catch(boost::bad_lexical_cast const& blc)
+        {
+            throw read_wkt_exception(blc.what(), it, end, wkt);
+        }
+        catch(std::exception const& e)
+        {
+            throw read_wkt_exception(e.what(), it, end, wkt);
+        }
+        catch(...)
+        {
+            throw read_wkt_exception("", it, end, wkt);
+        }
+
+        parsing_assigner<Point, Dimension + 1, DimensionCount>::apply(
+                        (finished ? it : ++it), end, point, wkt);
+    }
+};
+
+template <typename Point, std::size_t DimensionCount>
+struct parsing_assigner<Point, DimensionCount, DimensionCount>
+{
+    static inline void apply(tokenizer::iterator&, tokenizer::iterator, Point&,
+                std::string const&)
+    {
+    }
+};
+
+
+
+template <typename Iterator>
+inline void handle_open_parenthesis(Iterator& it,
+            Iterator const& end, std::string const& wkt)
+{
+    if (it == end || *it != "(")
+    {
+        throw read_wkt_exception("Expected '('", it, end, wkt);
+    }
+    ++it;
+}
+
+
+template <typename Iterator>
+inline void handle_close_parenthesis(Iterator& it,
+            Iterator const& end, std::string const& wkt)
+{
+    if (it != end && *it == ")")
+    {
+        ++it;
+    }
+    else
+    {
+        throw read_wkt_exception("Expected ')'", it, end, wkt);
+    }
+}
+
+template <typename Iterator>
+inline void check_end(Iterator& it,
+            Iterator const& end, std::string const& wkt)
+{
+    if (it != end)
+    {
+        throw read_wkt_exception("Too much tokens", it, end, wkt);
+    }
+}
+
+/*!
+\brief Internal, parses coordinate sequences, strings are formated like "(1 2,3 4,...)"
+\param it token-iterator, should be pre-positioned at "(", is post-positions after last ")"
+\param end end-token-iterator
+\param out Output itererator receiving coordinates
+*/
+template <typename Point>
+struct container_inserter
+{
+    // Version with output iterator
+    template <typename OutputIterator>
+    static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+        std::string const& wkt, OutputIterator out)
+    {
+        handle_open_parenthesis(it, end, wkt);
+
+        Point point;
+
+        // Parse points until closing parenthesis
+
+        while (it != end && *it != ")")
+        {
+            parsing_assigner
+                <
+                    Point,
+                    0,
+                    dimension<Point>::value
+                >::apply(it, end, point, wkt);
+            out = point;
+            ++out;
+            if (it != end && *it == ",")
+            {
+                ++it;
+            }
+        }
+
+        handle_close_parenthesis(it, end, wkt);
+    }
+};
+
+/*!
+\brief Internal, parses a point from a string like this "(x y)"
+\note used for parsing points and multi-points
+*/
+template <typename P>
+struct point_parser
+{
+    static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+        std::string const& wkt, P& point)
+    {
+        handle_open_parenthesis(it, end, wkt);
+        parsing_assigner<P, 0, dimension<P>::value>::apply(it, end, point, wkt);
+        handle_close_parenthesis(it, end, wkt);
+    }
+};
+
+
+template <typename Geometry>
+struct linestring_parser
+{
+    static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+                std::string const& wkt, Geometry& geometry)
+    {
+        container_inserter
+            <
+                typename point_type<Geometry>::type
+            >::apply(it, end, wkt, std::back_inserter(geometry));
+    }
+};
+
+
+template <typename Ring>
+struct ring_parser
+{
+    static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+                std::string const& wkt, Ring& ring)
+    {
+        // A ring should look like polygon((x y,x y,x y...))
+        // So handle the extra opening/closing parentheses
+        // and in between parse using the container-inserter
+        handle_open_parenthesis(it, end, wkt);
+        container_inserter
+            <
+                typename point_type<Ring>::type
+            >::apply(it, end, wkt, std::back_inserter(ring));
+        handle_close_parenthesis(it, end, wkt);
+    }
+};
+
+
+
+
+/*!
+\brief Internal, parses a polygon from a string like this "((x y,x y),(x y,x y))"
+\note used for parsing polygons and multi-polygons
+*/
+template <typename Polygon>
+struct polygon_parser
+{
+    static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+                std::string const& wkt, Polygon& poly)
+    {
+        typedef container_inserter
+            <
+                typename point_type<Polygon>::type
+            > container_inserter;
+
+        handle_open_parenthesis(it, end, wkt);
+
+        int n = -1;
+
+        // Stop at ")"
+        while (it != end && *it != ")")
+        {
+            // Parse ring
+            if (++n == 0)
+            {
+                container_inserter::apply(it, end, wkt,
+                        std::back_inserter(exterior_ring(poly)));
+            }
+            else
+            {
+                interior_rings(poly).resize(n);
+                container_inserter::apply(it, end, wkt,
+                        std::back_inserter(interior_rings(poly).back()));
+            }
+
+            if (it != end && *it == ",")
+            {
+                // Skip "," after ring is parsed
+                ++it;
+            }
+        }
+
+        handle_close_parenthesis(it, end, wkt);
+    }
+};
+
+inline bool one_of(tokenizer::iterator const& it, std::string const& value,
+            bool& is_present)
+{
+    if (boost::iequals(*it, value))
+    {
+        is_present = true;
+        return true;
+    }
+    return false;
+}
+
+inline bool one_of(tokenizer::iterator const& it, std::string const& value,
+            bool& present1, bool& present2)
+{
+    if (boost::iequals(*it, value))
+    {
+        present1 = true;
+        present2 = true;
+        return true;
+    }
+    return false;
+}
+
+
+inline void handle_empty_z_m(tokenizer::iterator& it, tokenizer::iterator end,
+            bool& has_empty, bool& has_z, bool& has_m)
+{
+    has_empty = false;
+    has_z = false;
+    has_m = false;
+
+    // WKT can optionally have Z and M (measured) values as in
+    // POINT ZM (1 1 5 60), POINT M (1 1 80), POINT Z (1 1 5)
+    // GGL supports any of them as coordinate values, but is not aware
+    // of any Measured value.
+    while (it != end
+           && (one_of(it, "M", has_m)
+               || one_of(it, "Z", has_z)
+               || one_of(it, "EMPTY", has_empty)
+               || one_of(it, "MZ", has_m, has_z)
+               || one_of(it, "ZM", has_z, has_m)
+               )
+           )
+    {
+        ++it;
+    }
+}
+
+/*!
+\brief Internal, starts parsing
+\param tokens boost tokens, parsed with separator " " and keeping separator "()"
+\param geometry string to compare with first token
+*/
+template <typename Geometry>
+inline bool initialize(tokenizer const& tokens,
+            std::string const& geometry_name, std::string const& wkt,
+            tokenizer::iterator& it)
+{
+    it = tokens.begin();
+    if (it != tokens.end() && boost::iequals(*it++, geometry_name))
+    {
+        bool has_empty, has_z, has_m;
+
+        handle_empty_z_m(it, tokens.end(), has_empty, has_z, has_m);
+
+        if (has_z && dimension<Geometry>::type::value < 3)
+        {
+            throw read_wkt_exception("Z only allowed for 3 or more dimensions", wkt);
+        }
+        if (has_empty)
+        {
+            check_end(it, tokens.end(), wkt);
+            return false;
+        }
+        // M is ignored at all.
+
+        return true;
+    }
+    throw read_wkt_exception(std::string("Should start with '") + geometry_name + "'", wkt);
+}
+
+
+template <typename Geometry, template<typename> class Parser, typename PrefixPolicy>
+struct geometry_parser
+{
+    static inline void apply(std::string const& wkt, Geometry& geometry)
+    {
+        ggl::clear(geometry);
+
+        tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+        tokenizer::iterator it;
+        if (initialize<Geometry>(tokens, PrefixPolicy::apply(), wkt, it))
+        {
+            Parser<Geometry>::apply(it, tokens.end(), wkt, geometry);
+            check_end(it, tokens.end(), wkt);
+        }
+    }
+};
+
+
+
+/*!
+\brief Supports box parsing
+\note OGC does not define the box geometry, and WKT does not support boxes.
+    However, to be generic GGL supports reading and writing from and to boxes.
+    Boxes are outputted as a standard POLYGON. GGL can read boxes from
+    a standard POLYGON, from a POLYGON with 2 points of from a BOX
+\tparam Box the box
+*/
+template <typename Box>
+struct box_parser
+{
+    static inline void apply(std::string const& wkt, Box& box)
+    {
+        bool should_close = false;
+        tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+        tokenizer::iterator it = tokens.begin();
+        tokenizer::iterator end = tokens.end();
+        if (it != end && boost::iequals(*it, "POLYGON"))
+        {
+            ++it;
+            bool has_empty, has_z, has_m;
+            handle_empty_z_m(it, end, has_empty, has_z, has_m);
+            if (has_empty)
+            {
+                assign_zero(box);
+                return;
+            }
+            handle_open_parenthesis(it, end, wkt);
+            should_close = true;
+        }
+        else if (it != end && boost::iequals(*it, "BOX"))
+        {
+            ++it;
+        }
+        else
+        {
+            throw read_wkt_exception("Should start with 'POLYGON' or 'BOX'", wkt);
+        }
+
+        typedef typename point_type<Box>::type point_type;
+        std::vector<point_type> points;
+        container_inserter<point_type>::apply(it, end, wkt, std::back_inserter(points));
+
+        if (should_close)
+        {
+            handle_close_parenthesis(it, end, wkt);
+        }
+        check_end(it, end, wkt);
+
+        int index = 0;
+        int n = boost::size(points);
+        if (n == 2)
+        {
+            index = 1;
+        }
+        else if (n == 4 || n == 5)
+        {
+            // In case of 4 or 5 points, we do not check the other ones, just
+            // take the opposite corner which is always 2
+            index = 2;
+        }
+        else
+        {
+            throw read_wkt_exception("Box should have 2,4 or 5 points", wkt);
+        }
+        set<min_corner, 0>(box, get<0>(points[0]));
+        set<min_corner, 1>(box, get<1>(points[0]));
+        set<max_corner, 0>(box, get<0>(points[index]));
+        set<max_corner, 1>(box, get<1>(points[index]));
+    }
+};
+
+
+
+}} // namespace detail::wkt
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct read_wkt {};
+
+
+template <typename Point>
+struct read_wkt<point_tag, Point>
+    : detail::wkt::geometry_parser
+        <
+            Point,
+            detail::wkt::point_parser,
+            detail::wkt::prefix_point
+        >
+{
+private :
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+};
+
+
+template <typename L>
+struct read_wkt<linestring_tag, L>
+    : detail::wkt::geometry_parser
+        <
+            L,
+            detail::wkt::linestring_parser,
+            detail::wkt::prefix_linestring
+        >
+{};
+
+template <typename Ring>
+struct read_wkt<ring_tag, Ring>
+    : detail::wkt::geometry_parser
+        <
+            Ring,
+            detail::wkt::ring_parser,
+            detail::wkt::prefix_polygon
+        >
+{};
+
+template <typename Geometry>
+struct read_wkt<polygon_tag, Geometry>
+    : detail::wkt::geometry_parser
+        <
+            Geometry,
+            detail::wkt::polygon_parser,
+            detail::wkt::prefix_polygon
+        >
+{};
+
+
+// Box (Non-OGC)
+template <typename Box>
+struct read_wkt<box_tag, Box>
+    : detail::wkt::box_parser<Box>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Parses OGC Well-Known Text (\ref WKT) into a geometry (any geometry)
+\ingroup wkt
+\param wkt string containing \ref WKT
+\param geometry output geometry
+\par Example:
+\note It is case insensitive and can have the WKT forms "point", "point m", "point z", "point zm", "point mz"
+\note Empty sequences can have forms as "LINESTRING ()" or "POLYGON(())"
+Small example showing how to use read_wkt to build a point
+\dontinclude doxygen_examples.cpp
+\skip example_from_wkt_point
+\line {
+\until }
+\par Example:
+Small example showing how to use read_wkt to build a linestring
+\dontinclude doxygen_examples.cpp
+\skip example_from_wkt_linestring
+\line {
+\until }
+\par Example:
+Small example showing how to use read_wkt to build a polygon
+\dontinclude doxygen_examples.cpp
+\skip example_from_wkt_polygon
+\line {
+\until }
+*/
+template <typename Geometry>
+inline void read_wkt(std::string const& wkt, Geometry& geometry)
+{
+    dispatch::read_wkt<typename tag<Geometry>::type, Geometry>::apply(wkt, geometry);
+}
+
+/*!
+\brief Parses OGC Well-Known Text (\ref WKT) and outputs using an output iterator
+\ingroup wkt
+\param wkt string containing \ref WKT
+\param out output iterator
+\note Because the output iterator doesn't always have the type value_type, it should be
+specified in the function call.
+\par Example:
+Small example showing how to use read_wkt with an output iterator
+\dontinclude doxygen_examples.cpp
+\skip example_from_wkt_output_iterator
+\line {
+\until }
+*/
+template <typename P, typename Out>
+inline void read_wkt(std::string const& wkt, Out out)
+{
+    // Todo: maybe take this from the string, or do not call initialize, such that
+    // any coordinate string is parsed and outputted
+    std::string const& tag = "linestring";
+
+    detail::wkt::tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+    detail::wkt::tokenizer::iterator it;
+    if (detail::wkt::initialize<P>(tokens, tag, wkt, it))
+    {
+        detail::wkt::container_inserter<P>::apply(it, tokens.end(), wkt, out);
+    }
+}
+
+} // namespace ggl
+
+#endif // GGL_EXTENSIONS_GIS_IO_WKT_READ_WKT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/read_wkt_multi.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/read_wkt_multi.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,105 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2008-2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_IO_WKT_READ_WKT_MULTI_HPP
+#define GGL_EXTENSIONS_GIS_IO_WKT_READ_WKT_MULTI_HPP
+
+#include <string>
+
+#include <ggl/multi/core/tags.hpp>
+#include <ggl/multi/core/point_type.hpp>
+
+#include <ggl/extensions/gis/io/wkt/read_wkt.hpp>
+#include <ggl/extensions/gis/io/wkt/detail/wkt_multi.hpp>
+
+
+namespace ggl
+{
+
+namespace detail { namespace wkt {
+
+template <typename MultiGeometry, template<typename> class Parser, typename PrefixPolicy>
+struct multi_parser
+{
+    static inline void apply(std::string const& wkt, MultiGeometry& geometry)
+    {
+        geometry.clear();
+
+        tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+        tokenizer::iterator it;
+        if (initialize<MultiGeometry>(tokens, PrefixPolicy::apply(), wkt, it))
+        {
+            handle_open_parenthesis(it, tokens.end(), wkt);
+
+            // Parse sub-geometries
+            while(it != tokens.end() && *it != ")")
+            {
+                geometry.resize(geometry.size() + 1);
+                Parser
+                    <
+                        typename boost::range_value<MultiGeometry>::type
+                    >::apply(it, tokens.end(), wkt, geometry.back());
+                if (it != tokens.end() && *it == ",")
+                {
+                    // Skip "," after multi-element is parsed
+                    ++it;
+                }
+            }
+
+            handle_close_parenthesis(it, tokens.end(), wkt);
+        }
+    }
+};
+
+
+
+
+}} // namespace detail::wkt
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename MultiGeometry>
+struct read_wkt<multi_point_tag, MultiGeometry>
+    : detail::wkt::multi_parser
+            <
+                MultiGeometry,
+                detail::wkt::point_parser,
+                detail::wkt::prefix_multipoint
+            >
+{};
+
+
+template <typename MultiGeometry>
+struct read_wkt<multi_linestring_tag, MultiGeometry>
+    : detail::wkt::multi_parser
+            <
+                MultiGeometry,
+                detail::wkt::linestring_parser,
+                detail::wkt::prefix_multilinestring
+            >
+{};
+
+
+template <typename MultiGeometry>
+struct read_wkt<multi_polygon_tag, MultiGeometry>
+    : detail::wkt::multi_parser
+            <
+                MultiGeometry,
+                detail::wkt::polygon_parser,
+                detail::wkt::prefix_multipolygon
+            >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+} // namespace ggl
+
+#endif // GGL_EXTENSIONS_GIS_IO_WKT_READ_WKT_MULTI_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/stream_wkt.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/stream_wkt.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,36 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2008-2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_IO_WKT_STREAM_WKT_HPP
+#define GGL_EXTENSIONS_GIS_IO_WKT_STREAM_WKT_HPP
+
+#include <ggl/extensions/gis/io/wkt/write_wkt.hpp>
+
+// This short file contains only one manipulator, streaming as WKT
+// Don't move contents to as_wkt, developers must be able to choose how to stream
+
+// Don't use namespace ggl, to enable the library to stream custom geometries which
+// are living outside the namespace ggl
+
+//namespace ggl
+//{
+
+
+/*!
+\brief Streams a geometry as Well-Known Text
+\ingroup wkt
+*/
+template<typename CH, typename TR, typename G>
+inline std::basic_ostream<CH,TR>& operator<<(std::basic_ostream<CH,TR> &os, const G& geometry)
+{
+    os << ggl::wkt(geometry);
+    return os;
+}
+
+//} // namespace ggl
+
+#endif // GGL_EXTENSIONS_GIS_IO_WKT_STREAM_WKT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/wkt.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/wkt.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,19 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2008-2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_IO_WKT_WKT_HPP
+#define GGL_EXTENSIONS_GIS_IO_WKT_WKT_HPP
+
+
+#include <ggl/extensions/gis/io/wkt/read_wkt.hpp>
+#include <ggl/extensions/gis/io/wkt/write_wkt.hpp>
+
+#include <ggl/extensions/gis/io/wkt/read_wkt_multi.hpp>
+#include <ggl/extensions/gis/io/wkt/write_wkt_multi.hpp>
+
+
+#endif // GGL_EXTENSIONS_GIS_IO_WKT_WKT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/write_wkt.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/write_wkt.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,360 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2008-2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_IO_WKT_WRITE_WKT_HPP
+#define GGL_EXTENSIONS_GIS_IO_WKT_WRITE_WKT_HPP
+
+#include <iostream>
+#include <string>
+
+#include <boost/concept/assert.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/convert.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/ring_type.hpp>
+#include <ggl/geometries/linear_ring.hpp>
+
+#include <ggl/extensions/gis/io/wkt/detail/wkt.hpp>
+
+/*!
+\defgroup wkt wkt: parse and stream WKT (Well-Known Text)
+The wkt classes stream the specified geometry as \ref OGC Well Known Text (\ref WKT). It is defined for OGC geometries.
+It is therefore not defined for all geometries (e.g. not for circle)
+\note The implementation is independant from point type, point_xy and point_ll are supported,
+as well as points with more than two coordinates.
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt {
+
+template <typename P, int I, int Count>
+struct stream_coordinate
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os, P const& p)
+    {
+        os << (I > 0 ? " " : "") << get<I>(p);
+        stream_coordinate<P, I + 1, Count>::apply(os, p);
+    }
+};
+
+template <typename P, int Count>
+struct stream_coordinate<P, Count, Count>
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>&, P const&)
+    {}
+};
+
+struct prefix_linestring_par
+{
+    static inline const char* apply() { return "LINESTRING("; }
+};
+
+struct prefix_ring_par_par
+{
+    // Note, double parentheses are intentional, indicating WKT ring begin/end
+    static inline const char* apply() { return "POLYGON(("; }
+};
+
+struct opening_parenthesis
+{
+    static inline const char* apply() { return "("; }
+};
+
+struct closing_parenthesis
+{
+    static inline const char* apply() { return ")"; }
+};
+
+struct double_closing_parenthesis
+{
+    static inline const char* apply() { return "))"; }
+};
+
+
+
+
+/*!
+\brief Stream points as \ref WKT
+*/
+template <typename Point, typename Policy>
+struct wkt_point
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os, Point const& p)
+    {
+        os << Policy::apply() << "(";
+        stream_coordinate<Point, 0, dimension<Point>::type::value>::apply(os, p);
+        os << ")";
+    }
+
+    private:
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point>) );
+};
+
+/*!
+\brief Stream ranges as WKT
+\note policy is used to stream prefix/postfix, enabling derived classes to override this
+*/
+template <typename Range, typename PrefixPolicy, typename SuffixPolicy>
+struct wkt_range
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                Range const& range)
+    {
+        typedef typename boost::range_const_iterator<Range>::type iterator_type;
+
+        bool first = true;
+
+        os << PrefixPolicy::apply();
+
+        // TODO: check EMPTY here
+
+        for (iterator_type it = boost::begin(range);
+            it != boost::end(range);
+            ++it)
+        {
+            os << (first ? "" : ",");
+            stream_coordinate<point, 0, dimension<point>::type::value>::apply(os, *it);
+            first = false;
+        }
+
+        os << SuffixPolicy::apply();
+    }
+
+    private:
+        typedef typename boost::range_value<Range>::type point;
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<point>) );
+};
+
+/*!
+\brief Stream sequence of points as WKT-part, e.g. (1 2),(3 4)
+\note Used in polygon, all multi-geometries
+*/
+
+
+
+template <typename Range>
+struct wkt_sequence
+    : wkt_range
+        <
+            Range,
+            opening_parenthesis,
+            closing_parenthesis
+        >
+{};
+
+
+template <typename Polygon, typename PrefixPolicy>
+struct wkt_poly
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                Polygon const& poly)
+    {
+        typedef typename ring_type<Polygon>::type ring;
+        typedef typename boost::range_const_iterator<
+                    typename interior_type<Polygon>::type>::type iterator;
+
+        os << PrefixPolicy::apply();
+        // TODO: check EMPTY here
+        os << "(";
+        wkt_sequence<ring>::apply(os, exterior_ring(poly));
+        for (iterator it = boost::begin(interior_rings(poly));
+            it != boost::end(interior_rings(poly));
+            ++it)
+        {
+            os << ",";
+            wkt_sequence<ring>::apply(os, *it);
+        }
+        os << ")";
+    }
+
+    private:
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<typename point_type<Polygon>::type>) );
+};
+
+
+template <typename Box>
+struct wkt_box
+{
+    typedef typename point_type<Box>::type point_type;
+
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                Box const& box)
+    {
+        // Convert to linear ring, then stream
+        typedef linear_ring<point_type> ring_type;
+        ring_type ring;
+        ggl::convert(box, ring);
+        os << "POLYGON(";
+        wkt_sequence<ring_type>::apply(os, ring);
+        os << ")";
+    }
+
+    private:
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<point_type>) );
+
+        inline wkt_box()
+        {
+            // Only streaming of boxes with two dimensions is support, otherwise it is a polyhedron!
+            //assert_dimension<B, 2>();
+        }
+};
+
+}} // namespace detail::wkt
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+template <typename Tag, typename Geometry>
+struct wkt {};
+
+
+template <typename Point>
+struct wkt<point_tag, Point>
+    : detail::wkt::wkt_point
+        <
+            Point,
+            detail::wkt::prefix_point
+        >
+{};
+
+
+template <typename Linestring>
+struct wkt<linestring_tag, Linestring>
+    : detail::wkt::wkt_range
+        <
+            Linestring,
+            detail::wkt::prefix_linestring_par,
+            detail::wkt::closing_parenthesis
+        >
+{};
+
+
+/*!
+\brief Specialization to stream a box as WKT
+\details A "box" does not exist in WKT.
+It is therefore streamed as a polygon
+*/
+template <typename Box>
+struct wkt<box_tag, Box>
+    : detail::wkt::wkt_box<Box>
+{};
+
+
+/*!
+\brief Specialization to stream a ring as WKT
+\details A "linear_ring" does not exist in WKT.
+A linear ring is equivalent to a polygon without inner rings
+It is therefore streamed as a polygon
+*/
+template <typename Ring>
+struct wkt<ring_tag, Ring>
+    : detail::wkt::wkt_range
+        <
+            Ring,
+            detail::wkt::prefix_ring_par_par,
+            detail::wkt::double_closing_parenthesis
+        >
+{};
+
+
+/*!
+\brief Specialization to stream polygon as WKT
+*/
+template <typename Polygon>
+struct wkt<polygon_tag, Polygon>
+    : detail::wkt::wkt_poly
+        <
+            Polygon,
+            detail::wkt::prefix_polygon
+        >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Generic geometry template manipulator class, takes corresponding output class from traits class
+\ingroup wkt
+\details Stream manipulator, streams geometry classes as \ref WKT streams
+\par Example:
+Small example showing how to use the wkt class
+\dontinclude doxygen_examples.cpp
+\skip example_as_wkt_point
+\line {
+\until }
+*/
+template <typename Geometry>
+class wkt_manipulator
+{
+public:
+
+    inline wkt_manipulator(Geometry const& g)
+        : m_geometry(g)
+    {}
+
+    template <typename Char, typename Traits>
+    inline friend std::basic_ostream<Char, Traits>& operator<<(
+            std::basic_ostream<Char, Traits>& os,
+            wkt_manipulator const& m)
+    {
+        dispatch::wkt
+            <
+                typename tag<Geometry>::type,
+                Geometry
+            >::apply(os, m.m_geometry);
+        os.flush();
+        return os;
+    }
+
+private:
+    Geometry const& m_geometry;
+};
+
+/*!
+\brief Main WKT-streaming function
+\ingroup wkt
+\par Example:
+Small example showing how to use the wkt helper function
+\dontinclude doxygen_examples.cpp
+\skip example_as_wkt_vector
+\line {
+\until }
+*/
+template <typename Geometry>
+inline wkt_manipulator<Geometry> wkt(Geometry const& geometry)
+{
+    return wkt_manipulator<Geometry>(geometry);
+}
+
+
+// Backward compatibility
+template <typename Geometry>
+inline wkt_manipulator<Geometry> make_wkt(Geometry const& geometry)
+{
+    return wkt_manipulator<Geometry>(geometry);
+}
+
+} // namespace ggl
+
+#endif // GGL_EXTENSIONS_GIS_IO_WKT_WRITE_WKT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/write_wkt_multi.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/extensions/gis/io/wkt/write_wkt_multi.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,109 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2008-2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_IO_WKT_WRITE_WKT_MULTI_HPP
+#define GGL_EXTENSIONS_GIS_IO_WKT_WRITE_WKT_MULTI_HPP
+
+
+
+#include <ggl/multi/core/tags.hpp>
+
+#include <ggl/extensions/gis/io/wkt/write_wkt.hpp>
+#include <ggl/extensions/gis/io/wkt/detail/wkt_multi.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt {
+
+
+template <typename Multi, typename StreamPolicy, typename PrefixPolicy>
+struct wkt_multi
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                Multi const& geometry)
+    {
+        os << PrefixPolicy::apply();
+        // TODO: check EMPTY here
+        os << "(";
+
+        for (typename boost::range_const_iterator<Multi>::type
+                    it = boost::begin(geometry);
+            it != boost::end(geometry);
+            ++it)
+        {
+            if (it != boost::begin(geometry))
+            {
+                os << ",";
+            }
+            StreamPolicy::apply(os, *it);
+        }
+
+        os << ")";
+    }
+};
+
+}} // namespace wkt::impl
+#endif
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+
+template <typename Multi>
+struct wkt<multi_point_tag, Multi>
+    : detail::wkt::wkt_multi
+        <
+            Multi,
+            detail::wkt::wkt_point
+                <
+                    typename boost::range_value<Multi>::type,
+                    detail::wkt::prefix_null
+                >,
+            detail::wkt::prefix_multipoint
+        >
+{};
+
+
+template <typename Multi>
+struct wkt<multi_linestring_tag, Multi>
+    : detail::wkt::wkt_multi
+        <
+            Multi,
+            detail::wkt::wkt_sequence
+                <
+                    typename boost::range_value<Multi>::type
+                >,
+            detail::wkt::prefix_multilinestring
+        >
+{};
+
+
+template <typename Multi>
+struct wkt<multi_polygon_tag, Multi>
+    : detail::wkt::wkt_multi
+        <
+            Multi,
+            detail::wkt::wkt_poly
+                <
+                    typename boost::range_value<Multi>::type,
+                    detail::wkt::prefix_null
+                >,
+            detail::wkt::prefix_multipolygon
+        >
+{};
+
+} // namespace dispatch
+#endif
+
+}
+
+#endif // GGL_EXTENSIONS_GIS_IO_WKT_WRITE_WKT_MULTI_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/extensions/io/svg/write_svg.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/extensions/io/svg/write_svg.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,269 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_IO_SVG_WRITE_SVG_HPP
+#define GGL_IO_SVG_WRITE_SVG_HPP
+
+#include <iostream>
+#include <string>
+
+#include <boost/concept/assert.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/ring_type.hpp>
+
+/*!
+\defgroup svg svg: stream SVG (Scalable Vector Graphics)
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace svg {
+
+
+template <typename Point>
+struct svg_point
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                Point const& p, std::string const& style, int size)
+    {
+        os << "<circle cx=\"" << p.x()
+            << "\" cy=\"" << p.y()
+            << "\" r=\"" << (size < 0 ? 5 : size)
+            << "\" style=\"" << style << "\"/>";
+    }
+
+    private:
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point>) );
+};
+
+
+template <typename Box>
+struct svg_box
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                Box const& box, std::string const& style, int size)
+    {
+        int x = ggl::get<ggl::min_corner, 0>(box);
+        int y = ggl::get<ggl::min_corner, 1>(box);
+        int width = std::abs(ggl::get<ggl::max_corner, 0>(box) - x);
+        int height = std::abs(ggl::get<ggl::max_corner, 1>(box) - y);
+
+        os << "<rect x=\"" << x << "\" y=\"" << y
+            << "\" width=\"" << width << "\" height=\"" << height
+            << "\" style=\"" << style << "\"/>";
+    }
+
+    private:
+        typedef typename ggl::point_type<Box>::type point_type;
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<point_type>) );
+};
+
+
+/*!
+\brief Stream ranges as SVG
+\note policy is used to select type (polyline/polygon)
+*/
+template <typename Range, typename Policy>
+struct svg_range
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+        Range const& range, std::string const& style, int size)
+    {
+        typedef typename boost::range_const_iterator<Range>::type iterator;
+
+        bool first = true;
+
+        os << "<" << Policy::prefix() << " points=\"";
+
+        for (iterator it = boost::begin(range);
+            it != boost::end(range);
+            ++it, first = false)
+        {
+            os << (first ? "" : " " ) << it->x() << "," << it->y();
+        }
+        os << "\" style=\"" << style << Policy::style() << "\"/>";
+    }
+
+    private:
+        typedef typename boost::range_value<Range>::type point;
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<point>) );
+};
+
+
+
+template <typename Polygon>
+struct svg_poly
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+        Polygon const& polygon, std::string const& style, int size)
+    {
+        typedef typename ggl::ring_type<Polygon>::type ring_type;
+        typedef typename boost::range_const_iterator<ring_type>::type iterator_type;
+
+        bool first = true;
+        os << "<g fill-rule=\"evenodd\"><path d=\"";
+
+        ring_type const& ring = ggl::exterior_ring(polygon);
+        for (iterator_type it = boost::begin(ring);
+            it != boost::end(ring);
+            ++it, first = false)
+        {
+            os << (first ? "M" : " L") << " " << it->x() << "," << it->y();
+        }
+
+        // Inner rings:
+        {
+            typedef typename boost::range_const_iterator
+                <
+                    typename ggl::interior_type<Polygon>::type
+                >::type ring_iterator_type;
+            for (ring_iterator_type rit = boost::begin(interior_rings(polygon));
+                 rit != boost::end(interior_rings(polygon));
+                 ++rit)
+            {
+                first = true;
+                for (iterator_type it = boost::begin(*rit);
+                    it != boost::end(*rit);
+                    ++it, first = false)
+                {
+                    os << (first ? "M" : " L") << " " << it->x() << "," << it->y();
+                }
+            }
+        }
+        os << " z \" style=\"" << style << "\"/></g>";
+
+    }
+
+    private:
+        BOOST_CONCEPT_ASSERT
+            (
+                (concept::ConstPoint<typename point_type<Polygon>::type>)
+            );
+};
+
+
+
+struct prefix_linestring
+{
+    static inline const char* prefix() { return "polyline"; }
+    static inline const char* style() { return ";fill:none"; }
+};
+
+
+struct prefix_ring
+{
+    static inline const char* prefix() { return "polygon"; }
+    static inline const char* style() { return ""; }
+};
+
+
+
+}} // namespace detail::svg
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+/*!
+\brief Dispatching base struct for SVG streaming, specialized below per geometry type
+\details Specializations should implement a static method "stream" to stream a geometry
+The static method should have the signature:
+
+template <typename Char, typename Traits>
+static inline void apply(std::basic_ostream<Char, Traits>& os, const G& geometry)
+*/
+template <typename GeometryTag, typename Geometry>
+struct svg {};
+
+template <typename Point>
+struct svg<point_tag, Point> : detail::svg::svg_point<Point> {};
+
+template <typename Box>
+struct svg<box_tag, Box> : detail::svg::svg_box<Box> {};
+
+template <typename Linestring>
+struct svg<linestring_tag, Linestring>
+    : detail::svg::svg_range<Linestring, detail::svg::prefix_linestring> {};
+
+template <typename Ring>
+struct svg<ring_tag, Ring>
+    : detail::svg::svg_range<Ring, detail::svg::prefix_ring> {};
+
+template <typename Polygon>
+struct svg<polygon_tag, Polygon>
+    : detail::svg::svg_poly<Polygon> {};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Generic geometry template manipulator class, takes corresponding output class from traits class
+\ingroup svg
+\details Stream manipulator, streams geometry classes as Virtual Earth shape
+*/
+template <typename G>
+class svg_manipulator
+{
+public:
+
+    inline svg_manipulator(G const& g, std::string const& style, int size)
+        : m_geometry(g)
+        , m_style(style)
+        , m_size(size)
+    {}
+
+    template <typename Char, typename Traits>
+    inline friend std::basic_ostream<Char, Traits>& operator<<(
+                    std::basic_ostream<Char, Traits>& os, svg_manipulator const& m)
+    {
+        dispatch::svg
+            <
+                typename tag<G>::type, G
+            >::apply(os, m.m_geometry, m.m_style, m.m_size);
+        os.flush();
+        return os;
+    }
+
+private:
+    G const& m_geometry;
+    std::string const& m_style;
+    int m_size;
+};
+
+/*!
+\brief Object generator to conveniently stream objects without including streamsvg
+\ingroup svg
+\par Example:
+Small example showing how to use the make_svg helper function
+\dontinclude doxygen_examples.cpp
+\skip example_as_svg_vector
+\line {
+\until }
+*/
+template <typename Geometry>
+inline svg_manipulator<Geometry> svg(Geometry const& t, std::string const& style, int size = -1)
+{
+    return svg_manipulator<Geometry>(t, style, size);
+}
+
+} // namespace ggl
+
+#endif // GGL_IO_SVG_WRITE_SVG_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/extensions/io/svg/write_svg_multi.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/extensions/io/svg/write_svg_multi.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,73 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_IO_SVG_WRITE_SVG_MULTI_HPP
+#define GGL_IO_SVG_WRITE_SVG_MULTI_HPP
+
+
+#include <ggl/extensions/io/svg/write_svg.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace svg {
+
+
+template <typename MultiGeometry, typename Policy>
+struct svg_multi
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+        MultiGeometry const& multi, std::string const& style, int size)
+    {
+        for (typename boost::range_const_iterator<MultiGeometry>::type
+                    it = boost::begin(multi);
+            it != boost::end(multi);
+            ++it)
+        {
+            Policy::apply(os, *it, style, size);
+        }
+
+    }
+
+};
+
+
+
+}} // namespace detail::svg
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+
+template <typename MultiPolygon>
+struct svg<multi_polygon_tag, MultiPolygon>
+    : detail::svg::svg_multi
+        <
+            MultiPolygon,
+            detail::svg::svg_poly
+                <
+                    typename boost::range_value<MultiPolygon>::type
+                >
+
+        >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+} // namespace ggl
+
+#endif // GGL_IO_SVG_WRITE_SVG_MULTI_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/boost_array_as_linestring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/boost_array_as_linestring.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,40 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_ADAPTED_BOOST_ARRAY_AS_LINESTRING_HPP
+#define GGL_ADAPTED_BOOST_ARRAY_AS_LINESTRING_HPP
+
+
+#ifdef _GEOMETRY_ADAPTED_BOOST_ARRAY_RANGE_TAG_DEFINED
+#error Include only one headerfile to register tag for adapted boost::array
+#endif
+
+#define GGL_ADAPTED_BOOST_ARRAY_RANGE_TAG_DEFINED
+
+
+#include <boost/array.hpp>
+
+namespace ggl
+{
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+    template <typename T, size_t N>
+    struct tag< boost::array<T, N> >
+    {
+        typedef linestring_tag type;
+    };
+
+}
+#endif
+}
+
+
+#endif
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/boost_array_as_ring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/boost_array_as_ring.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,40 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_ADAPTED_BOOST_ARRAY_AS_RING_HPP
+#define GGL_ADAPTED_BOOST_ARRAY_AS_RING_HPP
+
+
+#ifdef _GEOMETRY_ADAPTED_BOOST_ARRAY_RANGE_TAG_DEFINED
+#error Include only one headerfile to register tag for adapted boost::array
+#endif
+
+#define GGL_ADAPTED_BOOST_ARRAY_RANGE_TAG_DEFINED
+
+
+#include <boost/array.hpp>
+
+namespace ggl
+{
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+    template <typename T, size_t N>
+    struct tag< boost::array<T, N> >
+    {
+        typedef ring_tag type;
+    };
+
+}
+#endif
+}
+
+
+#endif
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/c_array.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/c_array.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,88 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_ADAPTED_C_ARRAY_HPP
+#define GGL_GEOMETRIES_ADAPTED_C_ARRAY_HPP
+
+#include <cstddef>
+
+#include <boost/type_traits/is_arithmetic.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/cs.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/core/tags.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+// Create class and specialization to indicate the tag
+// for normal cases and the case that the type of the c-array is arithmetic
+template <bool>
+struct c_array_tag
+{
+    typedef geometry_not_recognized_tag type;
+};
+
+template <>
+struct c_array_tag<true>
+{
+    typedef point_tag type;
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+// Assign the point-tag, preventing arrays of points getting a point-tag
+template <typename T, std::size_t N>
+struct tag<T[N]> : detail::c_array_tag<boost::is_arithmetic<T>::value> {};
+
+template <typename T, std::size_t N>
+struct coordinate_type<T[N]>
+{
+    typedef T type;
+};
+
+template <typename T, std::size_t N>
+struct dimension<T[N]>: boost::mpl::int_<N> {};
+
+template <typename T, std::size_t N>
+struct access<T[N]>
+{
+    template <std::size_t I>
+    static inline T get(const T p[N])
+    {
+        return p[I];
+    }
+
+    template <std::size_t I>
+    static inline void set(T p[N], const T& value)
+    {
+        p[I] = value;
+    }
+};
+
+// The library user has
+// 1) either to specify the coordinate system
+// 2) or include <ggl/geometries/adapted/c_array__at_.hpp> where @=cartesian,geographic,...
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_ADAPTED_C_ARRAY_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/c_array_cartesian.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/c_array_cartesian.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,37 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_ADAPTED_C_ARRAY_CARTESIAN_HPP
+#define GGL_ADAPTED_C_ARRAY_CARTESIAN_HPP
+
+#ifdef _GEOMETRY_ADAPTED_C_ARRAY_COORDINATE_SYSTEM_DEFINED
+#error Include only one headerfile to register coordinate coordinate_system for adapted c array
+#endif
+
+#define GGL_ADAPTED_C_ARRAY_COORDINATE_SYSTEM_DEFINED
+
+
+#include <ggl/geometries/adapted/c_array.hpp>
+
+
+namespace ggl
+{
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+    template <typename T, int N>
+    struct coordinate_system<T[N]>
+    { typedef cs::cartesian type; };
+
+}
+#endif
+}
+
+
+#endif
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/std_as_linestring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/std_as_linestring.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,61 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_ADAPTED_STD_AS_LINESTRING_HPP
+#define GGL_ADAPTED_STD_AS_LINESTRING_HPP
+
+
+#ifdef _GEOMETRY_ADAPTED_STD_RANGE_TAG_DEFINED
+#error Include only one headerfile to register tag for adapted std:: containers or iterator pair
+#endif
+
+#define GGL_ADAPTED_STD_RANGE_TAG_DEFINED
+
+
+#include <vector>
+#include <deque>
+#include <list>
+#include <utility>
+
+
+namespace ggl
+{
+#ifndef DOXYGEN_NO_DETAIL
+namespace util
+{
+    struct std_as_linestring
+    {
+        typedef linestring_tag type;
+    };
+
+}
+#endif
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+    // specialization for an iterator pair (read only)
+    template <typename P> struct tag< std::pair<P, P> > : util::std_as_linestring {};
+
+    // Indicate that std::library is not used to add things to std::pair.
+    // Don't implement anything else -> adding points or clearing not possible
+    template <typename P> struct use_std< std::pair<P, P> > : boost::mpl::false_ {};
+
+    // specializations for a std:: containers: vector, deque, list
+    template <typename P> struct tag< std::vector<P> > : util::std_as_linestring {};
+    template <typename P> struct tag< std::deque<P> > : util::std_as_linestring {};
+    template <typename P> struct tag< std::list<P> > : util::std_as_linestring {};
+
+}
+#endif
+}
+
+
+#endif
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/std_as_ring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/std_as_ring.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,43 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_ADAPTED_STD_AS_RING_HPP
+#define GGL_ADAPTED_STD_AS_RING_HPP
+
+
+#ifdef _GEOMETRY_ADAPTED_STD_RANGE_TAG_DEFINED
+#error Include only one headerfile to register tag for adapted std:: containers or iterator pair
+#endif
+
+#define GGL_ADAPTED_STD_RANGE_TAG_DEFINED
+
+
+#include <vector>
+#include <deque>
+#include <list>
+#include <utility>
+
+namespace ggl
+{
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+    // specialization for an iterator pair
+    template <typename T> struct tag< std::pair<T, T> > { typedef ring_tag type; };
+
+    // specialization for a std:: containers: vector, deque, list
+    template <typename T> struct tag< std::vector<T> > { typedef ring_tag type; };
+    template <typename T> struct tag< std::deque<T> > { typedef ring_tag type; };
+    template <typename T> struct tag< std::list<T> > { typedef ring_tag type; };
+}
+#endif
+}
+
+
+#endif
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/tuple.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/tuple.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,100 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_ADAPTED_TUPLE_HPP
+#define GGL_GEOMETRIES_ADAPTED_TUPLE_HPP
+
+#include <boost/tuple/tuple.hpp>
+
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/core/tags.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+// boost::tuple, 2D
+template <typename T>
+struct coordinate_type<boost::tuple<T, T> >
+{
+    typedef T type;
+};
+
+template <typename T>
+struct dimension<boost::tuple<T, T> > : boost::mpl::int_<2> {};
+
+template <typename T>
+struct access<boost::tuple<T, T> >
+{
+    template <int I>
+    static inline T get(const boost::tuple<T, T>& p)
+    {
+        return p.get<I>();
+    }
+
+    template <int I>
+    static inline void set(boost::tuple<T, T>& p, const T& value)
+    {
+        p.get<I>() = value;
+    }
+};
+
+template <typename T>
+struct tag<boost::tuple<T, T> >
+{
+    typedef point_tag type;
+};
+
+// boost::tuple, 3D
+template <typename T>
+struct coordinate_type<boost::tuple<T, T, T> >
+{
+    typedef T type;
+};
+
+template <typename T>
+struct dimension<boost::tuple<T, T, T> > : boost::mpl::int_<3> {};
+
+template <typename T>
+struct access<boost::tuple<T, T, T> >
+{
+    template <int I>
+    static inline T get(const boost::tuple<T, T, T>& p)
+    {
+        return p.get<I>();
+    }
+
+    template <int I>
+    static inline void set(boost::tuple<T, T, T>& p, const T& value)
+    {
+        p.get<I>() = value;
+    }
+};
+
+template <typename T>
+struct tag<boost::tuple<T, T, T> >
+{
+    typedef point_tag type;
+};
+
+// The library user has
+// 1) either to specify the coordinate system using a traits class
+// 2) or include <ggl/geometries/adapted/tuple__at_.hpp> where @=cartesian,geographic,...
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_ADAPTED_TUPLE_HPP
+
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/tuple_cartesian.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/adapted/tuple_cartesian.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,41 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_ADAPTED_TUPLE_CARTESIAN_HPP
+#define GGL_ADAPTED_TUPLE_CARTESIAN_HPP
+
+#ifdef _GEOMETRY_ADAPTED_TUPLE_COORDINATE_SYSTEM_DEFINED
+#error Include only one headerfile to register coordinate coordinate_system for adapted tuple
+#endif
+
+#define GGL_ADAPTED_TUPLE_COORDINATE_SYSTEM_DEFINED
+
+
+#include <ggl/geometries/adapted/tuple.hpp>
+
+
+namespace ggl
+{
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+    template <typename T>
+    struct coordinate_system<boost::tuple<T, T> >
+    { typedef cs::cartesian type; };
+
+    template <typename T>
+    struct coordinate_system<boost::tuple<T, T, T> >
+    { typedef cs::cartesian type; };
+
+}
+#endif
+}
+
+
+#endif
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/box.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/box.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,110 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_BOX_HPP
+#define GGL_GEOMETRIES_BOX_HPP
+
+#include <cstddef>
+
+#include <ggl/algorithms/assign.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/util/copy.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief Class box: defines a box made of two describing points
+    \ingroup Geometry
+    \details Box is always described by a min_corner() and a max_corner() point. If another
+    rectangle is used, use linear_ring or polygon.
+    \note Boxes are for selections and for calculating the envelope of geometries. Not all algorithms
+    are implemented for box. Boxes are also used in Spatial Indexes.
+    \tparam P point type. The box takes a point type as template parameter.
+    The point type can be any point type.
+    It can be 2D but can also be 3D or more dimensional.
+    The box can also take a latlong point type as template parameter.
+ */
+
+template<typename P>
+class box
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<P>) );
+
+public:
+
+    inline box() {}
+
+    /*!
+        \brief Constructor taking the minimum corner point and the maximum corner point
+    */
+    inline box(P const& min_corner, P const& max_corner)
+    {
+        copy_coordinates(min_corner, m_min_corner);
+        copy_coordinates(max_corner, m_max_corner);
+    }
+
+    inline P const& min_corner() const { return m_min_corner; }
+    inline P const& max_corner() const { return m_max_corner; }
+
+    inline P& min_corner() { return m_min_corner; }
+    inline P& max_corner() { return m_max_corner; }
+
+private:
+
+    P m_min_corner;
+    P m_max_corner;
+};
+
+
+// Traits specializations for box above
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename P>
+struct tag< box<P> >
+{
+    typedef box_tag type;
+};
+
+template <typename P>
+struct point_type<box<P> >
+{
+    typedef P type;
+};
+
+template <typename P, std::size_t C, std::size_t D>
+struct indexed_access<box<P>, C, D>
+{
+    typedef box<P> box_type;
+
+    static inline typename ggl::coordinate_type<box_type>::type get(box_type const& b)
+    {
+        return (C == min_corner ? ggl::get<D>(b.min_corner()) : ggl::get<D>(b.max_corner()));
+    }
+
+    static inline void set(box_type& b, typename ggl::coordinate_type<box_type>::type const& value)
+    {
+        if (C == min_corner)
+        {
+            ggl::set<D>(b.min_corner(), value);
+        }
+        else
+        {
+            ggl::set<D>(b.max_corner(), value);
+        }
+    }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_BOX_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/cartesian2d.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/cartesian2d.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,29 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_CARTESIAN2D_HPP
+#define GGL_GEOMETRIES_CARTESIAN2D_HPP
+
+// Predeclare common Cartesian 2D points for convenience
+
+#include <ggl/geometries/geometries.hpp>
+
+namespace ggl
+{
+
+typedef point_xy<double, cs::cartesian> point_2d;
+typedef linestring<point_2d> linestring_2d;
+typedef linear_ring<point_2d> ring_2d;
+typedef polygon<point_2d> polygon_2d;
+typedef box<point_2d> box_2d;
+typedef segment<point_2d> segment_2d;
+typedef nsphere<point_2d, double> circle;
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_CARTESIAN2D_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/cartesian3d.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/cartesian3d.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,28 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CARTESIAN3D_HPP
+#define GGL_CARTESIAN3D_HPP
+
+// Predeclare common Cartesian 3D points for convenience
+
+#include <ggl/geometries/geometries.hpp>
+
+namespace ggl
+{
+typedef point<double, 3, cs::cartesian> point_3d;
+typedef linestring<point_3d> linestring_3d;
+typedef linear_ring<point_3d> ring_3d;
+typedef polygon<point_3d> polygon_3d;
+typedef box<point_3d> box_3d;
+
+typedef nsphere<point_3d, double> sphere;
+}
+
+
+#endif // GGL_CARTESIAN3D_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/geometries.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/geometries.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,25 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_HPP
+#define GGL_GEOMETRIES_HPP
+
+#include <ggl/geometries/adapted/c_array.hpp>
+#include <ggl/geometries/adapted/tuple.hpp>
+
+#include <ggl/geometries/point.hpp>
+#include <ggl/geometries/point_xy.hpp>
+#include <ggl/geometries/linear_ring.hpp>
+#include <ggl/geometries/linestring.hpp>
+#include <ggl/geometries/polygon.hpp>
+
+#include <ggl/geometries/box.hpp>
+#include <ggl/geometries/nsphere.hpp>
+#include <ggl/geometries/segment.hpp>
+
+#endif // GGL_GEOMETRIES_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/linear_ring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/linear_ring.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,64 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_LINEAR_RING_HPP
+#define GGL_GEOMETRIES_LINEAR_RING_HPP
+
+#include <memory>
+#include <vector>
+
+#include <boost/concept/assert.hpp>
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+#include <ggl/core/concepts/point_concept.hpp>
+
+
+namespace ggl
+{
+
+/*!
+    \brief A linear_ring (linear linear_ring) is a closed line which should not be selfintersecting
+    \ingroup Geometry
+    \tparam P point type
+    \tparam V optional container type, for example std::vector, std::list, std::deque
+    \tparam A optional container-allocator-type
+*/
+template
+<
+    typename P,
+    template<typename, typename> class V = std::vector,
+    template<typename> class A = std::allocator
+>
+class linear_ring : public V<P, A<P> >
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<P>) );
+};
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+    typename P,
+    template<typename, typename> class V,
+    template<typename> class A
+>
+struct tag< linear_ring<P, V, A> >
+{
+    typedef ring_tag type;
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_LINEAR_RING_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/linestring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/linestring.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,69 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_LINESTRING_HPP
+#define GGL_GEOMETRIES_LINESTRING_HPP
+
+#include <memory>
+#include <vector>
+
+#include <boost/concept/assert.hpp>
+#include <boost/range/functions.hpp>
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+#include <ggl/core/concepts/point_concept.hpp>
+
+
+namespace ggl
+{
+
+/*!
+    \brief A linestring (named so by OGC) is a collection (default a vector) of points.
+    \ingroup Geometry
+    \tparam P point type
+    \tparam V optional container type, for example std::vector, std::list, std::deque
+    \tparam A optional container-allocator-type
+    (see http://accu.org/index.php/journals/427#ftn.d0e249 )
+    \par Concepts:
+    All algorithms work on ranges, based on a container with point types fulfilling
+    the point concepts. They will take linestring, but also vector, std::pair, or other containers.
+*/
+template
+<
+    typename P,
+    template<typename,typename> class V = std::vector,
+    template<typename> class A = std::allocator
+>
+class linestring : public V<P, A<P> >
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<P>) );
+};
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+    typename P,
+    template<typename,typename> class V,
+    template<typename> class A
+>
+struct tag<linestring<P, V, A> >
+{
+    typedef linestring_tag type;
+};
+} // namespace traits
+
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_LINESTRING_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/nsphere.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/nsphere.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,130 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_NSPHERE_HPP
+#define GGL_GEOMETRIES_NSPHERE_HPP
+
+#include <cstddef>
+
+#include <ggl/algorithms/assign.hpp>
+#include <ggl/core/concepts/nsphere_concept.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/util/copy.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief Class nsphere: defines a circle or a sphere: a point with radius
+    \ingroup Geometry
+    \details The name nsphere is quite funny but the best description of the class. It can be a circle (2D),
+    a sphere (3D), or higher (hypersphere) or lower. According to Wikipedia this name is the most appropriate.
+    It was mentioned on the Boost list.
+    An alternative is the more fancy name "sphercle" but that might be a bit too much an invention.
+    \note Circle is currently used for selections, for example polygon_in_circle. Currently not all
+    algorithms are implemented for n-spheres.
+    \tparam P point type of the center
+    \tparam T number type of the radius
+ */
+template <typename P, typename T>
+class nsphere
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<P>) );
+
+public:
+
+    typedef T radius_type;
+    typedef typename coordinate_type<P>::type coordinate_type;
+
+    nsphere()
+        : m_radius(0)
+    {
+        detail::assign::assign_value(m_center, coordinate_type());
+    }
+
+    nsphere(P const& center, T const& radius)
+        : m_radius(radius)
+    {
+        copy_coordinates(center, m_center);
+    }
+
+    inline P const& center() const { return m_center; }
+    inline T const& radius() const { return m_radius; }
+
+    inline void radius(T const& r) { m_radius = r; }
+    inline P& center() { return m_center; }
+
+private:
+
+    P m_center;
+    T m_radius;
+};
+
+// Traits specializations for n-sphere above
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename P, typename T>
+struct tag< nsphere<P, T> >
+{
+    typedef nsphere_tag type;
+};
+
+template <typename P, typename T>
+struct point_type<nsphere<P, T> >
+{
+    typedef P type;
+};
+
+template <typename P, typename T>
+struct radius_type<nsphere<P, T> >
+{
+    typedef T type;
+};
+
+template <typename P, typename T>
+struct access<nsphere<P, T> >
+{
+    typedef nsphere<P, T> nsphere_type;
+
+    template <std::size_t D>
+    static inline typename ggl::coordinate_type<nsphere_type>::type get(nsphere_type const& s)
+    {
+        return ggl::get<D>(s.center());
+    }
+
+    template <std::size_t D>
+    static inline void set(nsphere_type& s, typename ggl::coordinate_type<nsphere_type>::type const& value)
+    {
+        ggl::set<D>(s.center(), value);
+    }
+};
+
+template <typename P, typename T>
+struct radius_access<nsphere<P, T>, T, 0>
+{
+    typedef nsphere<P, T> nsphere_type;
+
+    static inline T get(nsphere_type const& s)
+    {
+        return s.radius();
+    }
+
+    static inline void set(nsphere_type& s, T const& value)
+    {
+        s.radius(value);
+    }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_NSPHERE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/point.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/point.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,125 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_POINT_HPP
+#define GGL_GEOMETRIES_POINT_HPP
+
+#include <cstddef>
+
+#include <boost/mpl/int.hpp>
+#include <boost/static_assert.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/core/coordinate_system.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/util/math.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief Basic point class, having coordinates defined in a neutral way
+    \ingroup Geometry
+    \tparam T numeric type, for example double, float, int
+    \tparam D coordinate dimension as number of coordinates, for example 2
+    \tparam C coordinate system, for example cs::cartesian
+*/
+template<typename T, std::size_t D, typename C>
+class point
+{
+public:
+
+    // Concept typedefs and members
+    typedef T coordinate_type;
+    typedef C coordinate_system;
+
+    static const std::size_t coordinate_count = D;
+
+    /// Default constructor, no initialization at all
+    inline point()
+    {}
+
+    /// Constructs with one, or optionally two or three values
+    inline point(T const& v0, T const& v1 = 0, T const& v2 = 0)
+    {
+        if (D >= 1) m_values[0] = v0;
+        if (D >= 2) m_values[1] = v1;
+        if (D >= 3) m_values[2] = v2;
+    }
+
+
+    /// Compile time access to coordinate values
+    template <std::size_t K>
+    inline T const& get() const
+    {
+        BOOST_STATIC_ASSERT(K < D);
+        return m_values[K];
+    }
+
+    template <std::size_t K>
+    inline void set(T value)
+    {
+        BOOST_STATIC_ASSERT(K < D);
+        m_values[K] = value;
+    }
+
+
+private:
+
+    T m_values[D];
+};
+
+
+// Adapt the point to the concept
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+template <typename T, std::size_t D, typename C>
+struct tag<point<T, D, C> >
+{
+    typedef point_tag type;
+};
+
+template<typename T, std::size_t D, typename C>
+struct coordinate_type<point<T, D, C> >
+{
+    typedef T type;
+};
+
+template<typename T, std::size_t D, typename C>
+struct coordinate_system<point<T, D, C> >
+{
+    typedef C type;
+};
+
+template<typename T, std::size_t D, typename C>
+struct dimension<point<T, D, C> > : boost::mpl::int_<D> {};
+
+template<typename T, std::size_t D, typename C>
+struct access<point<T, D, C> >
+{
+    template <std::size_t I>
+    static inline T get(point<T, D, C> const& p)
+    {
+        return p.template get<I>();
+    }
+
+    template <std::size_t I>
+    static inline void set(point<T, D, C>& p, T const& value)
+    {
+        p.template set<I>(value);
+    }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_POINT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/point_xy.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/point_xy.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,109 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_POINT_XY_HPP
+#define GGL_GEOMETRIES_POINT_XY_HPP
+
+#include <cstddef>
+
+#include <boost/mpl/int.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/geometries/point.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief 2D point in Cartesian coordinate system
+    \ingroup Geometry
+    \tparam T numeric type, arguments can be, for example, double, float, int
+*/
+template<typename T, typename C = cs::cartesian>
+class point_xy : public point<T, 2, C>
+{
+public:
+
+    /// Default constructor, does not initialize anything
+    inline point_xy() : point<T, 2, C>() {}
+
+    /// Constructor with x/y values
+    inline point_xy(T const& x, T const& y) : point<T, 2, C>(x, y) {}
+
+    /// Get x-value
+    inline T const& x() const
+    { return this->template get<0>(); }
+
+    /// Get y-value
+    inline T const& y() const
+    { return this->template get<1>(); }
+
+    /// Set x-value
+    inline void x(T const& v)
+    { this->template set<0>(v); }
+
+    /// Set y-value
+    inline void y(T const& v)
+    { this->template set<1>(v); }
+
+    /// Compare two points
+    inline bool operator<(point_xy const& other) const
+    {
+        return math::equals(x(), other.x()) ? y() < other.y() : x() < other.x();
+    }
+
+};
+
+// Adapt the point_xy to the concept
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename T, typename C>
+struct tag<point_xy<T, C> >
+{
+    typedef point_tag type;
+};
+
+template<typename T, typename C>
+struct coordinate_type<point_xy<T, C> >
+{
+    typedef T type;
+};
+
+template<typename T, typename C>
+struct coordinate_system<point_xy<T, C> >
+{
+    typedef C type;
+};
+
+template<typename T, typename C>
+struct dimension<point_xy<T, C> > : boost::mpl::int_<2> {};
+
+template<typename T, typename C>
+struct access<point_xy<T, C> >
+{
+    template <std::size_t I>
+    static inline T get(point_xy<T, C> const& p)
+    {
+        return p.template get<I>();
+    }
+
+    template <std::size_t I>
+    static inline void set(point_xy<T, C>& p, T const& value)
+    {
+        p.template set<I>(value);
+    }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_POINT_XY_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/polygon.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/polygon.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,179 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_POLYGON_HPP
+#define GGL_GEOMETRIES_POLYGON_HPP
+
+#include <memory>
+#include <vector>
+
+#include <boost/concept/assert.hpp>
+
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/geometries/linear_ring.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief The \b polygon contains an outer ring and zero or more inner rings.
+    \ingroup Geometry
+    \tparam P point type
+    \tparam PointList optional container type for points, for example std::vector, std::list, std::deque
+    \tparam RingList optional container type for inner rings, for example std::vector, std::list, std::deque
+    \tparam PointAlloc container-allocator-type
+    \tparam RingAlloc container-allocator-type
+    \note The container collecting the points in the rings can be different from the
+    container collecting the inner rings. They all default to vector.
+*/
+template
+<
+    typename Point,
+    template<typename, typename> class PointList = std::vector,
+    template<typename, typename> class RingList = std::vector,
+    template<typename> class PointAlloc = std::allocator,
+    template<typename> class RingAlloc = std::allocator
+>
+class polygon
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+public:
+
+    // Member types
+    typedef Point point_type;
+    typedef linear_ring<Point, PointList, PointAlloc> ring_type;
+    typedef RingList<ring_type , RingAlloc<ring_type > > inner_container_type;
+
+    inline ring_type const& outer() const { return m_outer; }
+    inline inner_container_type const& inners() const { return m_inners; }
+
+    inline ring_type& outer() { return m_outer; }
+    inline inner_container_type & inners() { return m_inners; }
+
+    /// Utility method, clears outer and inner rings
+    inline void clear()
+    {
+        m_outer.clear();
+        m_inners.clear();
+    }
+
+private:
+
+    ring_type m_outer;
+    inner_container_type m_inners;
+};
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+    typename Point,
+    template<typename, typename> class PointList,
+    template<typename, typename> class RingList,
+    template<typename> class PointAlloc,
+    template<typename> class RingAlloc
+>
+struct tag<polygon<Point, PointList, RingList, PointAlloc, RingAlloc> >
+{
+    typedef polygon_tag type;
+};
+
+template
+<
+    typename Point,
+    template<typename, typename> class PointList,
+    template<typename, typename> class RingList,
+    template<typename> class PointAlloc,
+    template<typename> class RingAlloc
+>
+struct ring_type<polygon<Point, PointList, RingList, PointAlloc, RingAlloc> >
+{
+    typedef typename polygon
+        <
+            Point, PointList, RingList, PointAlloc, RingAlloc
+        >::ring_type type;
+};
+
+template
+<
+    typename Point,
+    template<typename, typename> class PointList,
+    template<typename, typename> class RingList,
+    template<typename> class PointAlloc,
+    template<typename> class RingAlloc
+>
+struct interior_type< polygon<Point, PointList, RingList, PointAlloc, RingAlloc> >
+{
+    typedef typename polygon
+        <
+            Point, PointList, RingList, PointAlloc, RingAlloc
+        >::inner_container_type type;
+};
+
+template
+<
+    typename Point,
+    template<typename, typename> class PointList,
+    template<typename, typename> class RingList,
+    template<typename> class PointAlloc,
+    template<typename> class RingAlloc
+>
+struct exterior_ring< polygon<Point, PointList, RingList, PointAlloc, RingAlloc> >
+{
+    typedef polygon<Point, PointList, RingList, PointAlloc, RingAlloc> polygon_type;
+
+    static inline typename polygon_type::ring_type& get(polygon_type& p)
+    {
+        return p.outer();
+    }
+
+    static inline typename polygon_type::ring_type const & get(polygon_type const& p)
+    {
+        return p.outer();
+    }
+};
+
+template
+<
+    typename Point,
+    template<typename, typename> class PointList,
+    template<typename, typename> class RingList,
+    template<typename> class PointAlloc,
+    template<typename> class RingAlloc
+>
+struct interior_rings< polygon<Point, PointList, RingList, PointAlloc, RingAlloc> >
+{
+    typedef polygon<Point, PointList, RingList, PointAlloc, RingAlloc> polygon_type;
+
+    static inline typename polygon_type::inner_container_type& get(
+                    polygon_type& p)
+    {
+        return p.inners();
+    }
+
+    static inline typename polygon_type::inner_container_type const& get(
+                    polygon_type const& p)
+    {
+        return p.inners();
+    }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_POLYGON_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/register/box.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/register/box.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,106 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_REGISTER_BOX_HPP
+#define GGL_GEOMETRIES_REGISTER_BOX_HPP
+
+
+#ifndef DOXYGEN_NO_SPECIALIZATIONS
+
+// box based on point
+#define GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS(Box, Point, MinCorner, MaxCorner) \
+template <size_t C, size_t D> \
+struct indexed_access<Box, C, D> \
+{ \
+    static inline typename coordinate_type<Point>::type get(const Box& b) \
+    { \
+        return C == min_corner ? ggl::get<D>(b. MinCorner) : ggl::get<D>(b. MaxCorner); \
+    } \
+    static inline void set(Box& b, const typename coordinate_type<Point>::type& value) \
+    { \
+        if (C == min_corner) ggl::set<D>(b. MinCorner, value); else ggl::set<D>(b. MaxCorner, value); \
+    } \
+};
+
+
+#define GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS_TEMPLATIZED(Box, MinCorner, MaxCorner) \
+template <typename P, size_t C, size_t D> \
+struct indexed_access<Box<P>, C, D> \
+{ \
+    static inline typename coordinate_type<P>::type get(const Box<P>& b) \
+    { \
+        return C == min_corner ? ggl::get<D>(b. MinCorner) : ggl::get<D>(b. MaxCorner); \
+    } \
+    static inline void set(Box<P>& b, const typename coordinate_type<P>::type& value) \
+    { \
+        if (C == min_corner) ggl::set<D>(b. MinCorner, value); else ggl::set<D>(b. MaxCorner, value); \
+    } \
+};
+
+
+#define GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS_4VALUES(Box, Point, Left, Bottom, Right, Top) \
+template <size_t C, size_t D> \
+struct indexed_access<Box, C, D> \
+{ \
+    static inline typename coordinate_type<Point>::type get(const Box& b) \
+    { \
+        return C == min_corner && D == 0 ? b. Left \
+            : C == min_corner && D == 1 ? b. Bottom \
+            : C == max_corner && D == 0 ? b. Right \
+            : C == max_corner && D == 1 ? b. Top \
+            : 0; \
+    } \
+    static inline void set(Box& b, const typename coordinate_type<Point>::type& value) \
+    { \
+        if (C == min_corner && D == 0) b. Left = value; \
+        else if (C == min_corner && D == 1) b. Bottom = value; \
+        else if (C == max_corner && D == 0) b. Right = value; \
+        else if (C == max_corner && D == 1) b. Top = value; \
+    } \
+};
+
+
+
+#define GEOMETRY_DETAIL_SPECIALIZE_BOX_TRAITS(Box, PointType) \
+    template<> struct tag<Box > { typedef box_tag type; }; \
+    template<> struct point_type<Box > { typedef PointType type; };
+
+#define GEOMETRY_DETAIL_SPECIALIZE_BOX_TRAITS_TEMPLATIZED(Box) \
+    template<typename P> struct tag<Box<P> > { typedef box_tag type; }; \
+    template<typename P> struct point_type<Box<P> > { typedef P type; };
+
+#endif // DOXYGEN_NO_SPECIALIZATIONS
+
+
+
+#define GEOMETRY_REGISTER_BOX(Box, PointType, MinCorner, MaxCorner) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_BOX_TRAITS(Box, PointType) \
+    GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS(Box, PointType, MinCorner, MaxCorner) \
+}}
+
+
+#define GEOMETRY_REGISTER_BOX_TEMPLATIZED(Box, MinCorner, MaxCorner) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_BOX_TRAITS_TEMPLATIZED(Box) \
+    GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS_TEMPLATIZED(Box, MinCorner, MaxCorner) \
+}}
+
+#define GEOMETRY_REGISTER_BOX_2D_4VALUES(Box, PointType, Left, Bottom, Right, Top) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_BOX_TRAITS(Box, PointType) \
+    GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS_4VALUES(Box, PointType, Left, Bottom, Right, Top) \
+}}
+
+
+
+// CONST versions are for boxes probably not that common. Leave this for the moment.
+
+
+#endif // GGL_GEOMETRIES_REGISTER_BOX_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/register/linestring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/register/linestring.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,25 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_REGISTER_LINESTRING_HPP
+#define GGL_GEOMETRIES_REGISTER_LINESTRING_HPP
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+#define GEOMETRY_REGISTER_LINESTRING(Linestring) \
+namespace ggl { namespace traits {  \
+    template<> struct tag<Linestring> { typedef linestring_tag type; }; \
+}}
+
+
+
+#endif // GGL_GEOMETRIES_REGISTER_LINESTRING_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/register/point.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/register/point.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,154 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_REGISTER_POINT_HPP
+#define GGL_GEOMETRIES_REGISTER_POINT_HPP
+
+
+
+// This file implements a "macro party", nevertheless very useful for registration of custom geometry types
+
+#ifndef DOXYGEN_NO_SPECIALIZATIONS
+
+// Starting point, specialize basic traits necessary to register a point
+// (the 'accessor' is technically not specialization but definition, specialized in another macro)
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, Dim, CoordinateType, CoordinateSystem) \
+    template<> struct tag<Point> { typedef point_tag type; }; \
+    template<> struct dimension<Point> : boost::mpl::int_<Dim> {}; \
+    template<> struct coordinate_type<Point> { typedef CoordinateType type; }; \
+    template<> struct coordinate_system<Point> { typedef CoordinateSystem type; }; \
+    template<int I> struct Point##accessor {};
+
+
+// Non Const version
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS(Point, CoordinateType) \
+    template<> struct access<Point> { \
+         template <int I> \
+        static inline CoordinateType get(const Point& p) { return Point##accessor<I>::get(p); } \
+        template <int I> \
+        static inline void set(Point& p, const CoordinateType& value) { Point##accessor<I>::set(p, value); } \
+    };
+
+// Const version
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST(Point, CoordinateType) \
+    template<> struct access<Point> { \
+         template <int I> \
+        static inline CoordinateType get(const Point& p) { return Point##accessor<I>::get(p); } \
+    };
+
+
+
+
+// Specialize the point-specific-accessor class, declared below, per dimension
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR(Point, Dim, CoordinateType, Get, Set) \
+    template<> struct Point##accessor< Dim > \
+    { \
+        static inline CoordinateType get(const Point& p) { return  p. Get; } \
+        static inline void set(Point& p, const CoordinateType& value) { p. Set = value; } \
+    };
+
+
+// Const version
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_CONST(Point, Dim, CoordinateType, Get) \
+    template<> struct Point##accessor< Dim > \
+    { \
+        static inline CoordinateType get(const Point& p) { return  p. Get; } \
+    };
+
+
+// Get/set version
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_GET_SET(Point, Dim, CoordinateType, Get, Set) \
+    template<> struct Point##accessor< Dim > \
+    { \
+        static inline CoordinateType get(const Point& p) { return  p. Get (); } \
+        static inline void set(Point& p, const CoordinateType& value) { p. Set ( value ); } \
+    };
+
+
+
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_2D(Point, CoordinateType, Get0, Get1, Set0, Set1) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR(Point, 0, CoordinateType, Get0, Set0) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR(Point, 1, CoordinateType, Get1, Set1)
+
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_3D(Point, CoordinateType, Get0, Get1, Get2, Set0, Set1, Set2) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR(Point, 0, CoordinateType, Get0, Set0) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR(Point, 1, CoordinateType, Get1, Set1) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR(Point, 2, CoordinateType, Get2, Set2)
+
+// Const versions
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST_2D(Point, CoordinateType, Get0, Get1) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_CONST(Point, 0, CoordinateType, Get0) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_CONST(Point, 1, CoordinateType, Get1)
+
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST_3D(Point, CoordinateType, Get0, Get1, Get2) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_CONST(Point, 0, CoordinateType, Get0) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_CONST(Point, 1, CoordinateType, Get1) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_CONST(Point, 2, CoordinateType, Get2)
+
+#endif // DOXYGEN_NO_SPECIALIZATIONS
+
+
+
+// Library user macro to register a custom 2D point
+#define GEOMETRY_REGISTER_POINT_2D(Point, CoordinateType, CoordinateSystem, Field0, Field1) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 2, CoordinateType, CoordinateSystem) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS(Point, CoordinateType) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_2D(Point, CoordinateType, Field0, Field1, Field0, Field1) \
+}}
+
+// Library user macro to register a custom 3D point
+#define GEOMETRY_REGISTER_POINT_3D(Point, CoordinateType, CoordinateSystem, Field0, Field1, Field2) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 3, CoordinateType, CoordinateSystem) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS(Point, CoordinateType) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_3D(Point, CoordinateType, Field0, Field1, Field2, Field0, Field1, Field2) \
+}}
+
+
+
+// Library user macro to register a custom 2D point (CONST version)
+#define GEOMETRY_REGISTER_POINT_2D_CONST(Point, CoordinateType, CoordinateSystem, Field0, Field1) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 2, CoordinateType, CoordinateSystem) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST(Point, CoordinateType) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST_2D(Point, CoordinateType, Field0, Field1) \
+}}
+
+// Library user macro to register a custom 3D point (CONST version)
+#define GEOMETRY_REGISTER_POINT_3D_CONST(Point, CoordinateType, CoordinateSystem, Field0, Field1, Field2) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 3, CoordinateType, CoordinateSystem) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST(Point, CoordinateType) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST_3D(Point, CoordinateType, Field0, Field1, Field2) \
+}}
+
+
+// Library user macro to register a custom 2D point (having separate get/set methods)
+#define GEOMETRY_REGISTER_POINT_2D_GET_SET(Point, CoordinateType, CoordinateSystem, Get0, Get1, Set0, Set1) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 2, CoordinateType, CoordinateSystem) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS(Point, CoordinateType) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_GET_SET(Point, 0, CoordinateType, Get0, Set0) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_GET_SET(Point, 1, CoordinateType, Get1, Set1) \
+}}
+
+
+// Library user macro to register a custom 3D point (having separate get/set methods)
+#define GEOMETRY_REGISTER_POINT_3D_GET_SET(Point, CoordinateType, CoordinateSystem, Get0, Get1, Get2, Set0, Set1, Set2) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 3, CoordinateType, CoordinateSystem) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS(Point, CoordinateType) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_GET_SET(Point, 0, CoordinateType, Get0, Set0) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_GET_SET(Point, 1, CoordinateType, Get1, Set1) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_GET_SET(Point, 2, CoordinateType, Get2, Set2) \
+}}
+
+
+#endif // GGL_GEOMETRIES_REGISTER_POINT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/register/register_box.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/register/register_box.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,22 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_REGISTER_REGISTER_BOX_HPP
+#define GGL_GEOMETRIES_REGISTER_REGISTER_BOX_HPP
+
+#include <ggl/geometries/register/box.hpp>
+
+#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
+#  pragma message ("Warning: This header is deprecated. Please use: ggl/geometries/register/box.hpp")
+#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
+#  warning "This header is deprecated. Please use: ggl/geometries/register/box.hpp")
+#endif
+
+
+#endif // GGL_GEOMETRIES_REGISTER_REGISTER_BOX_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/register/register_point.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/register/register_point.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,22 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_REGISTER_REGISTER_POINT_HPP
+#define GGL_GEOMETRIES_REGISTER_REGISTER_POINT_HPP
+
+#include <ggl/geometries/register/point.hpp>
+
+#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
+#  pragma message ("Warning: This header is deprecated. Please use: ggl/geometries/register/point.hpp")
+#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
+#  warning "This header is deprecated. Please use: ggl/geometries/register/point.hpp")
+#endif
+
+
+#endif // GGL_GEOMETRIES_REGISTER_REGISTER_POINT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/register/ring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/register/ring.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,28 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_REGISTER_RING_HPP
+#define GGL_GEOMETRIES_REGISTER_RING_HPP
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+#define GEOMETRY_REGISTER_RING(Ring) \
+namespace ggl { namespace traits {  \
+    template<> struct tag<Ring> { typedef ring_tag type; }; \
+}}
+
+
+#define GEOMETRY_REGISTER_RING_TEMPLATIZED(Ring) \
+namespace ggl { namespace traits {  \
+    template<typename P> struct tag< Ring<P> > { typedef ring_tag type; }; \
+}}
+
+
+#endif // GGL_GEOMETRIES_REGISTER_RING_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/geometries/segment.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/geometries/segment.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,105 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_SEGMENT_HPP
+#define GGL_GEOMETRIES_SEGMENT_HPP
+
+#include <cstddef>
+
+#include <boost/concept/assert.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_const.hpp>
+
+#include <ggl/core/concepts/point_concept.hpp>
+
+namespace ggl
+{
+
+/*!
+\brief Class segment: small containing two (templatized) point references
+\ingroup Geometry
+\details From Wikipedia: In geometry, a line segment is a part of a line that is bounded
+ by two distinct end points, and contains every point on the line between its end points.
+\note The structure is like std::pair, and can often be used interchangeable.
+So points are public available. We cannot derive from std::pair<P&, P&> because of
+reference assignments. Points are not const and might be changed by the algorithm
+(used in intersection_linestring).
+\tparam P point type of the segment
+*/
+template<typename P>
+struct segment
+{
+private:
+
+    BOOST_CONCEPT_ASSERT( (typename boost::mpl::if_
+        <
+            boost::is_const<P>,
+            concept::ConstPoint<P>,
+            concept::Point<P>
+        >
+    ) );
+
+public:
+
+    typedef P point_type;
+
+    P& first;
+    P& second;
+
+    inline segment(P& p1, P& p2)
+        : first(p1), second(p2)
+    {}
+};
+
+// Traits specializations for segment above
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename P>
+struct tag< segment<P> >
+{
+    typedef segment_tag type;
+};
+
+template <typename P>
+struct point_type<segment<P> >
+{
+    typedef P type;
+};
+
+template <typename P, std::size_t I, std::size_t D>
+struct indexed_access<segment<P>, I, D>
+{
+    typedef segment<P> segment_type;
+    typedef typename ggl::coordinate_type<segment_type>::type coordinate_type;
+
+    static inline coordinate_type get(segment_type const& s)
+    {
+        return (I == 0 ? ggl::get<D>(s.first) : ggl::get<D>(s.second));
+    }
+
+    static inline void set(segment_type& s, coordinate_type const& value)
+    {
+        if (I == 0)
+        {
+            ggl::set<D>(s.first, value);
+        }
+        else
+        {
+            ggl::set<D>(s.second, value);
+        }
+    }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_SEGMENT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/ggl.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/ggl.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,72 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GGL_HPP
+#define GGL_GGL_HPP
+
+// Shortcut to include all header files
+
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/core/concepts/ring_concept.hpp>
+#include <ggl/core/concepts/linestring_concept.hpp>
+#include <ggl/core/concepts/polygon_concept.hpp>
+
+#include <ggl/core/concepts/box_concept.hpp>
+#include <ggl/core/concepts/nsphere_concept.hpp>
+#include <ggl/core/concepts/segment_concept.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/radian_access.hpp>
+#include <ggl/core/topological_dimension.hpp>
+
+#include <ggl/core/replace_point_type.hpp>
+
+#include <ggl/arithmetic/arithmetic.hpp>
+#include <ggl/arithmetic/dot_product.hpp>
+
+#include <ggl/strategies/strategies.hpp>
+
+#include <ggl/algorithms/append.hpp>
+#include <ggl/algorithms/area.hpp>
+#include <ggl/algorithms/assign.hpp>
+#include <ggl/algorithms/buffer.hpp>
+#include <ggl/algorithms/centroid.hpp>
+#include <ggl/algorithms/clear.hpp>
+#include <ggl/algorithms/convert.hpp>
+#include <ggl/algorithms/convex_hull.hpp>
+#include <ggl/algorithms/correct.hpp>
+#include <ggl/algorithms/distance.hpp>
+#include <ggl/algorithms/envelope.hpp>
+#include <ggl/algorithms/for_each.hpp>
+#include <ggl/algorithms/intermediate.hpp>
+#include <ggl/algorithms/intersection.hpp>
+#include <ggl/algorithms/intersects.hpp>
+#include <ggl/algorithms/length.hpp>
+#include <ggl/algorithms/make.hpp>
+#include <ggl/algorithms/num_points.hpp>
+#include <ggl/algorithms/perimeter.hpp>
+#include <ggl/algorithms/sectionalize.hpp>
+#include <ggl/algorithms/selected.hpp>
+#include <ggl/algorithms/simplify.hpp>
+#include <ggl/algorithms/transform.hpp>
+#include <ggl/algorithms/within.hpp>
+
+
+#include <ggl/util/copy.hpp>
+#include <ggl/util/for_each_coordinate.hpp>
+#include <ggl/util/loop.hpp>
+#include <ggl/util/math.hpp>
+#include <ggl/util/select_most_precise.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+#include <ggl/util/write_dsv.hpp>
+
+#endif // GGL_GGL_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/iterators/base.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/iterators/base.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,55 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ITERATORS_BASE_HPP
+#define GGL_ITERATORS_BASE_HPP
+
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+
+namespace ggl { namespace detail { namespace iterators {
+
+template <typename T, typename Iterator>
+struct iterator_base :
+    public  boost::iterator_adaptor
+    <
+        T,
+        Iterator,
+        boost::use_default,
+        typename boost::mpl::if_
+        <
+            boost::is_convertible
+            <
+                typename boost::iterator_traversal<Iterator>::type,
+                boost::random_access_traversal_tag
+            >,
+            boost::bidirectional_traversal_tag,
+            boost::use_default
+        >::type
+    >
+{
+    // Define operator cast to Iterator to be able to write things like Iterator it = myit++
+    inline operator Iterator() const
+    {
+        return this->base();
+    }
+
+    /*inline bool operator==(const Iterator& other) const
+    {
+        return this->base() == other;
+    }
+    inline bool operator!=(const Iterator& other) const
+    {
+        return ! operator==(other);
+    }*/
+};
+
+}}} // namespace ggl::detail::iterators
+
+#endif // GGL_ITERATORS_BASE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/iterators/ever_circling_iterator.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/iterators/ever_circling_iterator.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,86 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ITERATORS_EVER_CIRCLING_ITERATOR_HPP
+#define GGL_ITERATORS_EVER_CIRCLING_ITERATOR_HPP
+
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+
+#include <ggl/iterators/base.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief Iterator which ever circles through a range
+    \tparam Iterator iterator on which this class is based on
+    \ingroup iterators
+    \details If the iterator arrives at range.end() it restarts from the
+     beginning. So it has to be stopped in another way.
+    Don't call for(....; it++) because it will turn in an endless loop
+    \note Name inspired on David Bowie's
+    "Chant Of The Ever Circling Skeletal Family"
+*/
+template <typename Iterator>
+struct ever_circling_iterator :
+    public detail::iterators::iterator_base
+    <
+        ever_circling_iterator<Iterator>,
+        Iterator
+    >
+{
+    friend class boost::iterator_core_access;
+
+    explicit inline ever_circling_iterator(Iterator begin, Iterator end)
+      : m_begin(begin)
+      , m_end(end)
+    {
+        this->base_reference() = begin;
+    }
+
+    explicit inline ever_circling_iterator(Iterator begin, Iterator end, Iterator start)
+      : m_begin(begin)
+      , m_end(end)
+    {
+        this->base_reference() = start;
+    }
+
+    /// Navigate to a certain position, should be in [start .. end], it at end
+    /// it will circle again.
+    inline void moveto(Iterator it)
+    {
+        this->base_reference() = it;
+        check_end();
+    }
+
+private:
+
+    inline void increment()
+    {
+        (this->base_reference())++;
+        check_end();
+    }
+
+    inline void check_end()
+    {
+        if (this->base() == this->m_end)
+        {
+            this->base_reference() = this->m_begin;
+        }
+    }
+
+    Iterator m_begin;
+    Iterator m_end;
+};
+
+
+} // namespace ggl
+
+#endif // GGL_ITERATORS_EVER_CIRCLING_ITERATOR_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/iterators/point_const_iterator.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/iterators/point_const_iterator.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,76 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_ITERATORS_POINT_CONST_ITERATOR_HPP
+#define GGL_ITERATORS_POINT_CONST_ITERATOR_HPP
+
+
+#include <boost/type_traits/remove_const.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+#include <boost/range/metafunctions.hpp>
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct point_const_iterator
+{
+    // The default: meta-forward this to boost
+    // This enables calling this function using std::vector as well, even if they
+    // are not registered.
+    // It also requires less specializations
+    typedef typename boost::range_const_iterator<Geometry>::type type;
+};
+
+
+template <typename Polygon>
+struct point_const_iterator<polygon_tag, Polygon>
+{
+    typedef typename boost::range_const_iterator
+        <
+            typename ring_type<Polygon>::type
+        >::type type;
+};
+
+
+
+
+} // namespace dispatch
+#endif
+
+
+/*!
+    \brief Meta-function which defines point-const-iterator type
+    \ingroup iterators
+*/
+template <typename Geometry>
+struct point_const_iterator
+{
+    typedef typename boost::remove_const<Geometry>::type ncg;
+    typedef typename dispatch::point_const_iterator<
+        typename tag<Geometry>::type, ncg>::type type;
+};
+
+
+
+
+}
+
+
+#endif // GGL_ITERATORS_POINT_CONST_ITERATOR_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/iterators/segment_iterator.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/iterators/segment_iterator.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,139 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Mateusz Loskot 2009, mateusz_at_[hidden]
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ITERATORS_SEGMENT_ITERATOR_HPP
+#define GGL_ITERATORS_SEGMENT_ITERATOR_HPP
+
+// TODO: This is very experimental version of input iterator
+// reading collection of points as segments - proof of concept.
+// --mloskot
+
+// TODO: Move to boost::iterator_adaptor
+
+#include <iterator>
+
+#include <boost/assert.hpp>
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+
+#include <ggl/algorithms/equals.hpp>
+#include <ggl/geometries/segment.hpp>
+
+namespace ggl
+{
+
+template <typename Base, typename Point>
+struct segment_iterator
+{
+    typedef Base base_type;
+    typedef Point point_type;
+    typedef typename ggl::segment<Point> segment_type;
+
+    typedef std::input_iterator_tag iterator_category;
+    typedef typename std::iterator_traits<Base>::difference_type difference_type;
+    typedef segment_type value_type;
+    typedef segment_type* pointer;
+    typedef segment_type& reference;
+
+    explicit segment_iterator(Base const& end)
+        : m_segment(p1 , p2)
+        , m_prev(end)
+        , m_it(end)
+        , m_end(end)
+    {
+        BOOST_ASSERT(ggl::equals(point_type(), m_segment.first));
+        BOOST_ASSERT(ggl::equals(point_type(), m_segment.second));
+    }
+
+    segment_iterator(Base const& it, Base const& end)
+        : m_segment(p1 , p2)
+        , m_prev(it)
+        , m_it(it)
+        , m_end(end)
+    {
+        if (m_it != m_end)
+        {
+            BOOST_ASSERT(m_prev != m_end);
+            ++m_it;
+        }
+    }
+
+    reference operator*()
+    {
+        BOOST_ASSERT(m_it != m_end && m_prev != m_end);
+
+        p1 = *m_prev;
+        p2 = *m_it;
+
+        return m_segment;
+    }
+
+    pointer operator->()
+    {
+        return &(operator*());
+    }
+
+    segment_iterator& operator++()
+    {
+        ++m_prev;
+        ++m_it;
+        return *this;
+    }
+
+    segment_iterator operator++(int)
+    {
+        segment_iterator it(*this);
+        ++(*this);
+        return it;
+    }
+
+    Base const& base() const { return m_it; }
+
+private:
+
+    point_type p1;
+    point_type p2;
+    segment_type m_segment;
+
+    Base m_prev;
+    Base m_it;
+    Base m_end;
+};
+
+template <typename Base, typename Point>
+bool operator==(segment_iterator<Base, Point> const& lhs,
+                segment_iterator<Base, Point> const& rhs)
+{
+    return (lhs.base() == rhs.base());
+}
+
+template <typename Base, typename Point>
+bool operator!=(segment_iterator<Base, Point> const& lhs,
+                segment_iterator<Base, Point> const& rhs)
+{
+    return (lhs.base() != rhs.base());
+}
+
+template <typename C>
+segment_iterator
+<
+    typename C::iterator,
+    typename C::value_type
+>
+make_segment_iterator(C& c)
+{
+    typedef typename C::iterator base_iterator;
+    typedef typename C::value_type point_type;
+    return segment_iterator<base_iterator, point_type>(c.begin(), c.end());
+}
+
+} // namespace ggl
+
+#endif // GGL_ITERATORS_SEGMENT_ITERATOR_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/area.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/area.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,37 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_AREA_HPP
+#define GGL_MULTI_ALGORITHMS_AREA_HPP
+
+#include <ggl/algorithms/area.hpp>
+#include <ggl/multi/core/point_type.hpp>
+#include <ggl/multi/algorithms/detail/multi_sum.hpp>
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+    template <typename MultiGeometry, typename Strategy>
+    struct area<multi_polygon_tag, MultiGeometry, Strategy>
+        : detail::multi_sum<double, MultiGeometry, Strategy,
+            detail::area::polygon_area<
+                typename boost::range_value<MultiGeometry>::type, Strategy> >
+    {};
+
+
+} // namespace dispatch
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_AREA_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/centroid.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/centroid.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,81 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_CENTROID_HPP
+#define GGL_MULTI_ALGORITHMS_CENTROID_HPP
+
+#include <ggl/algorithms/centroid.hpp>
+#include <ggl/multi/core/point_type.hpp>
+#include <ggl/multi/algorithms/detail/multi_sum.hpp>
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace centroid {
+
+template<typename MultiPolygon, typename Point, typename Strategy>
+struct centroid_multi_polygon
+{
+    static inline void apply(MultiPolygon const& multi, Point& c, Strategy const& strategy)
+    {
+        typedef typename boost::range_const_iterator<MultiPolygon>::type iterator;
+
+        typename Strategy::state_type state;
+
+        for (iterator it = boost::begin(multi); it != boost::end(multi); ++it)
+        {
+// TODO: make THIS the building block!
+            typedef typename boost::range_value<MultiPolygon>::type polygon_type;
+            polygon_type const& poly = *it;
+            if (ring_ok(exterior_ring(poly), c))
+            {
+
+                loop(exterior_ring(poly), strategy, state);
+
+                typedef typename boost::range_const_iterator
+                    <
+                        typename interior_type<polygon_type>::type
+                    >::type iterator_type;
+
+                for (iterator_type it = boost::begin(interior_rings(poly));
+                     it != boost::end(interior_rings(poly));
+                     ++it)
+                {
+                    loop(*it, strategy, state);
+                }
+            }
+        }
+        state.centroid(c);
+    }
+};
+
+
+
+}} // namespace detail::centroid
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+    template <typename MultiPolygon, typename Point, typename Strategy>
+    struct centroid<multi_polygon_tag, MultiPolygon, Point, Strategy>
+        : detail::centroid::centroid_multi_polygon<MultiPolygon, Point, Strategy>
+    {};
+
+
+} // namespace dispatch
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_CENTROID_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/convex_hull.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/convex_hull.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,95 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_CONVEX_HULL_HPP
+#define GGL_MULTI_ALGORITHMS_CONVEX_HULL_HPP
+
+
+#include <ggl/util/as_range.hpp>
+
+#include <ggl/multi/core/tags.hpp>
+#include <ggl/multi/core/is_multi.hpp>
+#include <ggl/multi/core/point_type.hpp>
+
+#include <ggl/algorithms/convex_hull.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace convex_hull {
+
+
+template <typename MultiGeometry, typename OutputIterator>
+struct convex_hull_multi
+{
+    static inline OutputIterator apply(MultiGeometry const& multi,
+            OutputIterator out)
+    {
+        using namespace boost;
+
+        typedef typename point_type<MultiGeometry>::type point;
+        typename strategy_convex_hull
+            <
+                typename cs_tag<point>::type,
+                point
+            >::type strategy;
+
+        typedef typename range_const_iterator<MultiGeometry>::type iterator;
+        typedef typename range_value<MultiGeometry>::type single;
+        for(iterator it = begin(multi); it != end(multi); ++it)
+        {
+            strategy.add_range(as_range
+                    <typename as_range_type<single>::type>(*it));
+        }
+        strategy.handle_input();
+
+        strategy.get(out);
+        return out;
+    }
+};
+
+
+}} // namespace detail::convex_hull
+
+#endif
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// Specialize for multi's
+template
+<
+    typename MultiTag,
+    typename MultiGeometry,
+    typename OutputIterator
+>
+struct convex_hull<MultiTag, true, MultiGeometry, OutputIterator>
+    : detail::convex_hull::convex_hull_multi<MultiGeometry, OutputIterator> 
+{};
+
+
+// Specialize more for point
+template <typename MultiPoint, typename OutputIterator>
+struct convex_hull<multi_point_tag, true, MultiPoint, OutputIterator>
+    : detail::convex_hull::hull<MultiPoint, OutputIterator> 
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_CONVEX_HULL_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/correct.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/correct.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,53 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_CORRECT_HPP
+#define GGL_MULTI_CORRECT_HPP
+
+#include <vector>
+
+#include <ggl/algorithms/correct.hpp>
+
+
+//FIX ME it is not yet adapted to tag-dispatching
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+    namespace correct
+    {
+        // correct a multi-polygon
+        template <typename O>
+        inline void correct_multi_polygon(O& o)
+        {
+            for (typename O::iterator it = o.begin(); it != o.end(); it++)
+            {
+                correct_polygon(*it);
+            }
+        }
+    }
+}
+#endif
+
+template<typename Y,
+        template<typename,typename> class V, template<typename> class A>
+void correct(multi_polygon<Y, V, A>& mp)
+{
+    detail::correct::correct_multi_polygon(mp);
+}
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_CORRECT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/detail/modify_with_predicate.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/detail/modify_with_predicate.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,46 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_DETAIL_MODIFY_WITH_PREDICATE_HPP
+#define GGL_MULTI_ALGORITHMS_DETAIL_MODIFY_WITH_PREDICATE_HPP
+
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail {
+
+template <typename MultiGeometry, typename Predicate, typename Policy>
+struct multi_modify_with_predicate
+{
+    static inline void apply(MultiGeometry& multi, Predicate const& predicate)
+    {
+        typedef typename boost::range_iterator<MultiGeometry>::type iterator_type;
+        for (iterator_type it = boost::begin(multi);
+            it != boost::end(multi);
+            ++it)
+        {
+            Policy::apply(*it, predicate);
+        }
+    }
+};
+
+
+} // namespace detail
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_DETAIL_MODIFY_WITH_PREDICATE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/detail/multi_sum.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/detail/multi_sum.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,54 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_SUM_HPP
+#define GGL_MULTI_SUM_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+namespace ggl
+{
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template
+<
+    typename T,
+    typename MultiGeometry,
+    typename Strategy,
+    typename Policy
+>
+struct multi_sum
+{
+    static inline T apply(MultiGeometry const& geometry, Strategy const& strategy)
+    {
+        typedef typename boost::range_const_iterator
+            <
+                MultiGeometry
+            >::type iterator_type;
+        T sum = T();
+        for (iterator_type it = boost::begin(geometry);
+            it != boost::end(geometry);
+            ++it)
+        {
+            sum += Policy::apply(*it, strategy);
+        }
+        return sum;
+    }
+};
+
+
+} // namespace detail
+#endif
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_SUM_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/distance.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/distance.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,121 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_DISTANCE_HPP
+#define GGL_MULTI_ALGORITHMS_DISTANCE_HPP
+
+
+#include <boost/numeric/conversion/bounds.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/multi/core/tags.hpp>
+#include <ggl/multi/core/is_multi.hpp>
+#include <ggl/multi/core/geometry_id.hpp>
+#include <ggl/multi/core/point_type.hpp>
+
+#include <ggl/algorithms/distance.hpp>
+
+
+namespace ggl {
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace distance {
+
+
+template<typename Geometry, typename MultiGeometry, typename Strategy>
+struct distance_single_to_multi
+{
+    typedef typename Strategy::return_type return_type;
+    static inline return_type apply(Geometry const& geometry,
+                MultiGeometry const& multi,
+                Strategy const& strategy)
+    {
+        using namespace boost;
+
+        return_type mindist = make_distance_result<return_type>(
+                        numeric::bounds<typename select_coordinate_type<Geometry, MultiGeometry>::type>::highest());
+        typedef typename range_const_iterator<MultiGeometry>::type iterator;
+        for(iterator it = begin(multi); it != end(multi); ++it)
+        {
+            return_type dist = ggl::distance(geometry, *it);
+            if (dist < mindist)
+            {
+                mindist = dist;
+            }
+        }
+
+        return mindist;
+    }
+};
+
+template<typename Multi1, typename Multi2, typename Strategy>
+struct distance_multi_to_multi
+{
+    typedef typename Strategy::return_type return_type;
+
+    static inline return_type apply(Multi1 const& multi1,
+                Multi2 const& multi2, Strategy const& strategy)
+    {
+        using namespace boost;
+
+        return_type mindist
+            = make_distance_result<return_type>(
+                numeric::bounds<typename select_coordinate_type<Multi1,
+                            Multi2>::type>::highest());
+
+        for(typename range_const_iterator<Multi1>::type it = begin(multi1);
+                it != end(multi1);
+                ++it)
+        {
+            return_type dist = distance_single_to_multi
+                <
+                    typename range_value<Multi1>::type,
+                    Multi2,
+                    Strategy
+                >::apply(*it, multi2, strategy);
+            if (dist < mindist)
+            {
+                mindist = dist;
+            }
+        }
+
+        return mindist;
+    }
+};
+
+
+}} // namespace detail::distance
+#endif
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename GeometryTag1, typename GeometryTag2,
+        typename G1, typename G2, typename Strategy>
+struct distance<GeometryTag1, GeometryTag2, G1, G2, strategy_tag_distance_point_point, Strategy, false, true>
+    : detail::distance::distance_single_to_multi<G1, G2, Strategy>
+{};
+
+template <typename GeometryTag1, typename GeometryTag2,
+        typename G1, typename G2, typename Strategy>
+struct distance<GeometryTag1, GeometryTag2, G1, G2, strategy_tag_distance_point_point, Strategy, true, true>
+    : detail::distance::distance_multi_to_multi<G1, G2, Strategy>
+{};
+
+} // namespace dispatch
+#endif
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_DISTANCE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/envelope.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/envelope.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,98 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ENVELOPE_HPP
+#define GGL_MULTI_ENVELOPE_HPP
+
+#include <vector>
+
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/algorithms/envelope.hpp>
+
+#include <ggl/multi/core/point_type.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+
+namespace detail { namespace envelope {
+
+
+template<typename MultiLinestring, typename Box, typename Strategy>
+struct envelope_multi_linestring
+{
+    static inline void apply(MultiLinestring const& mp, Box& mbr, Strategy const& strategy)
+    {
+        typename Strategy::state_type state(mbr);
+        for (typename boost::range_const_iterator<MultiLinestring>::type
+                    it = mp.begin();
+            it != mp.end();
+            ++it)
+        {
+            envelope_range_state(*it, strategy, state);
+        }
+    }
+};
+
+
+// version for multi_polygon: outer linear_ring's of all polygons
+template<typename MultiPolygon, typename Box, typename Strategy>
+struct envelope_multi_polygon
+{
+    static inline void apply(MultiPolygon const& mp, Box& mbr, Strategy const& strategy)
+    {
+        typename Strategy::state_type state(mbr);
+        for (typename boost::range_const_iterator<MultiPolygon>::type
+                    it = mp.begin();
+            it != mp.end();
+            ++it)
+        {
+            envelope_range_state(exterior_ring(*it), strategy, state);
+        }
+    }
+};
+
+
+}} // namespace detail::envelope
+
+#endif
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename M, typename B, typename S>
+struct envelope<multi_point_tag, box_tag, M, B, S>
+    : detail::envelope::envelope_range<M, B, S>
+{};
+
+template <typename M, typename B, typename S>
+struct envelope<multi_linestring_tag, box_tag, M, B, S>
+    : detail::envelope::envelope_multi_linestring<M, B, S>
+{};
+
+
+template <typename M, typename B, typename S>
+struct envelope<multi_polygon_tag, box_tag, M, B, S>
+    : detail::envelope::envelope_multi_polygon<M, B, S>
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ENVELOPE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/foreach.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/foreach.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,222 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_FOREACH_HPP
+#define GGL_MULTI_FOREACH_HPP
+
+#include <vector>
+
+#include <ggl/algorithms/for_each.hpp>
+
+FIX ME it is not yet adapted to tag-dispatching
+
+
+namespace ggl
+{
+
+template<typename MP, typename F>
+inline F for_each_point_multi_point(MP& mp, F f)
+{
+    return (for_each_point_container(mp, f));
+}
+
+template<typename ML, typename F>
+inline F for_each_point_multi_linestring(ML& ml, F f)
+{
+    for (typename ML::iterator it = ml.begin(); it != ml.end(); it++)
+    {
+        f = for_each_point_linestring(*it, f);
+    }
+    return (f);
+}
+
+template<typename MY, typename F>
+inline F for_each_point_multi_polygon(MY& mp, F f)
+{
+    for (typename MY::iterator it = mp.begin(); it != mp.end(); it++)
+    {
+        f = for_each_point_polygon(*it, f);
+    }
+    return (f);
+}
+
+
+
+
+template<typename MP, typename F>
+inline F for_each_point_multi_point(const MP& mp, F f)
+{
+    return (for_each_point_container(mp, f));
+}
+
+
+template<typename ML, typename F>
+inline F for_each_point_multi_linestring(const ML& ml, F f)
+{
+    for (typename ML::const_iterator it = ml.begin(); it != ml.end(); it++)
+    {
+        f = for_each_point_linestring(*it, f);
+    }
+    return (f);
+}
+
+template<typename MY, typename F>
+inline F for_each_point_multi_polygon(const MY& mp, F f)
+{
+    for (typename MY::const_iterator it = mp.begin(); it != mp.end(); it++)
+    {
+        f = for_each_point_polygon(*it, f);
+    }
+    return (f);
+}
+
+
+
+template<typename ML, typename F>
+inline F for_each_segment_multi_linestring(ML& ml, F f)
+{
+    for (typename ML::iterator it = ml.begin(); it != ml.end(); it++)
+    {
+        f = for_each_segment_linestring(*it, f);
+    }
+    return (f);
+}
+
+template<typename MY, typename F>
+inline F for_each_segment_multi_polygon(MY& mp, F f)
+{
+    for (typename MY::iterator it = mp.begin(); it != mp.end(); it++)
+    {
+        f = for_each_segment_polygon(*it, f);
+    }
+    return (f);
+}
+
+
+
+
+
+
+template<typename ML, typename F>
+inline F for_each_segment_multi_linestring(const ML& ml, F f)
+{
+    for (typename ML::const_iterator it = ml.begin(); it != ml.end(); it++)
+    {
+        f = for_each_segment_linestring(*it, f);
+    }
+    return (f);
+}
+
+template<typename MY, typename F>
+inline F for_each_segment_multi_polygon(const MY& mp, F f)
+{
+    for (typename MY::const_iterator it = mp.begin(); it != mp.end(); it++)
+    {
+        f = for_each_segment_polygon(*it, f);
+    }
+    return (f);
+}
+
+
+
+
+
+
+template<typename P,
+        template<typename,typename> class V, template<typename> class A,
+        typename F>
+inline F for_each_point(multi_point<P, V, A>& mp, F f)
+{
+    return (for_each_point_multi_point(mp, f));
+}
+
+template<typename L,
+        template<typename,typename> class V, template<typename> class A,
+        typename F>
+inline F for_each_point(multi_linestring<L, V, A>& ml, F f)
+{
+    return (for_each_point_multi_linestring(ml, f));
+}
+
+template<typename Y,
+        template<typename,typename> class V, template<typename> class A,
+        typename F>
+inline F for_each_point(multi_polygon<Y, V, A>& mp, F f)
+{
+    return (for_each_point_multi_polygon(mp, f));
+}
+
+
+
+
+template<typename P,
+        template<typename,typename> class V, template<typename> class A,
+        typename F>
+inline F for_each_point(const multi_point<P, V, A>& mp, F f)
+{
+    return (for_each_point_multi_point(mp, f));
+}
+
+template<typename L,
+        template<typename,typename> class V, template<typename> class A,
+        typename F>
+inline F for_each_point(const multi_linestring<L, V, A>& ml, F f)
+{
+    return (for_each_point_multi_linestring(ml, f));
+}
+
+
+template<typename Y,
+        template<typename,typename> class V, template<typename> class A,
+        typename F>
+inline F for_each_point(const multi_polygon<Y, V, A>& mp, F f)
+{
+    return (for_each_point_multi_polygon(mp, f));
+}
+
+
+
+
+template<typename L,
+        template<typename,typename> class V, template<typename> class A,
+        typename F>
+inline F for_each_segment(multi_linestring<L, V, A>& ml, F f)
+{
+    return (for_each_segment_multi_linestring(ml, f));
+}
+
+template<typename Y,
+        template<typename,typename> class V, template<typename> class A,
+        typename F>
+inline F for_each_segment(multi_polygon<Y, V, A>& mp, F f)
+{
+    return (for_each_segment_multi_polygon(mp, f));
+}
+
+
+
+
+template<typename L,
+        template<typename,typename> class V, template<typename> class A,
+        typename F>
+inline F for_each_segment(const multi_linestring<L, V, A>& ml, F f)
+{
+    return (for_each_segment_multi_linestring(ml, f));
+}
+
+template<typename Y,
+        template<typename,typename> class V, template<typename> class A,
+        typename F>
+inline F for_each_segment(const multi_polygon<Y, V, A>& mp, F f)
+{
+    return (for_each_segment_multi_polygon(mp, f));
+}
+} // namespace ggl
+
+
+#endif // GGL_MULTI_FOREACH_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/get_section.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/get_section.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,57 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_GET_SECTION_HPP
+#define GGL_MULTI_ALGORITHMS_GET_SECTION_HPP
+
+
+#include <boost/concept/requires.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/multi/core/tags.hpp>
+
+#include <ggl/algorithms/get_section.hpp>
+
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename MultiPolygon, typename Section>
+struct get_section<multi_polygon_tag, MultiPolygon, Section>
+{
+    typedef typename ggl::point_const_iterator<MultiPolygon>::type iterator_type;
+
+    static inline void apply(MultiPolygon const& multi_polygon, Section const& section,
+                iterator_type& begin, iterator_type& end)
+    {
+        BOOST_ASSERT(section.multi_index >= 0 && section.multi_index < boost::size(multi_polygon));
+
+        get_section<polygon_tag, typename boost::range_value<MultiPolygon>::type, Section>
+            ::apply(multi_polygon[section.multi_index], section, begin, end);
+
+    }
+};
+
+
+} // namespace dispatch
+#endif
+
+
+
+
+} // namespace ggl
+
+#endif // GGL_MULTI_ALGORITHMS_GET_SECTION_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/intersection.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/intersection.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,43 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_INTERSECTION_HPP
+#define GGL_MULTI_ALGORITHMS_INTERSECTION_HPP
+
+#include <vector>
+
+#include <ggl/algorithms/intersection.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+    typename MultiPolygon1, typename MultiPolygon2,
+    typename OutputIterator, typename GeometryOut
+>
+struct intersection
+    <
+        multi_polygon_tag, multi_polygon_tag, polygon_tag,
+        MultiPolygon1, MultiPolygon2,
+        OutputIterator, GeometryOut
+    >
+{
+    // todo: implement this
+};
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_INTERSECTION_HPP
+
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/length.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/length.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,32 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_LENGTH_HPP
+#define GGL_MULTI_LENGTH_HPP
+
+#include <ggl/algorithms/length.hpp>
+#include <ggl/multi/algorithms/detail/multi_sum.hpp>
+
+namespace ggl
+{
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+    template <typename MG, typename S>
+    struct length<multi_linestring_tag, MG, S>
+            : detail::multi_sum<double, MG, S,
+                    detail::length::range_length<typename boost::range_value<MG>::type, S> > {};
+
+} // namespace dispatch
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_LENGTH_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/num_points.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/num_points.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,78 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_ALGORITHMS_NUM_POINTS_HPP
+#define GGL_MULTI_ALGORITHMS_NUM_POINTS_HPP
+
+
+#include <ggl/multi/core/tags.hpp>
+#include <ggl/algorithms/num_points.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace num_points {
+
+
+template <typename MultiGeometry>
+struct multi_count
+{
+    static inline size_t apply(MultiGeometry const& geometry)
+    {
+        typedef typename boost::range_value<MultiGeometry>::type geometry_type;
+        typedef typename boost::remove_const<geometry_type>::type ncg;
+        typedef typename boost::range_const_iterator
+            <
+                MultiGeometry
+            >::type iterator_type;
+
+        size_t n = 0;
+        for (iterator_type it = boost::begin(geometry);
+            it != boost::end(geometry);
+            ++it)
+        {
+            n += dispatch::num_points<typename tag<ncg>::type,
+                ggl::is_linear<ncg>::value, ncg>::apply(*it);
+        }
+        return n;
+    }
+};
+
+
+}} // namespace detail::num_points
+#endif
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+
+template <typename Geometry>
+struct num_points<multi_point_tag, false, Geometry>
+    : detail::num_points::multi_count<Geometry> {};
+
+template <typename Geometry>
+struct num_points<multi_linestring_tag, false, Geometry>
+    : detail::num_points::multi_count<Geometry> {};
+
+template <typename Geometry>
+struct num_points<multi_polygon_tag, false, Geometry>
+    : detail::num_points::multi_count<Geometry> {};
+
+
+} // namespace dispatch
+#endif
+
+
+}
+
+
+#endif // GGL_MULTI_ALGORITHMS_NUM_POINTS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/overlay/copy_segments.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/overlay/copy_segments.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,92 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_OVERLAY_COPY_SEGMENTS_HPP
+#define GGL_MULTI_ALGORITHMS_OVERLAY_COPY_SEGMENTS_HPP
+
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/overlay/copy_segments.hpp>
+
+#include <ggl/multi/core/ring_type.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace copy_segments {
+
+
+template
+<
+    typename MultiGeometry,
+    typename SegmentIdentifier,
+    typename RangeOut,
+    typename Policy
+>
+struct copy_segments_multi
+{
+    static inline void apply(MultiGeometry const& multi_geometry,
+            SegmentIdentifier const& seg_id, int to_index,
+            RangeOut& current_output)
+    {
+
+        BOOST_ASSERT
+            (
+                seg_id.multi_index >= 0
+                && seg_id.multi_index < boost::size(multi_geometry)
+            );
+
+        // Call the single-version
+        Policy::apply(multi_geometry[seg_id.multi_index],
+                    seg_id, to_index, current_output);
+    }
+};
+
+
+}} // namespace detail::copy_segments
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+
+
+template <typename MultiPolygon, typename SegmentIdentifier, typename RangeOut>
+struct copy_segments<multi_polygon_tag, MultiPolygon, SegmentIdentifier, RangeOut>
+    : detail::copy_segments::copy_segments_multi
+        <
+            MultiPolygon,
+            SegmentIdentifier,
+            RangeOut,
+            detail::copy_segments::copy_segments_polygon
+                <
+                    typename boost::range_value<MultiPolygon>::type,
+                    SegmentIdentifier,
+                    RangeOut
+                >
+        >
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+} // namespace ggl
+
+#endif // GGL_MULTI_ALGORITHMS_OVERLAY_COPY_SEGMENTS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/overlay/get_intersection_points.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/overlay/get_intersection_points.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,64 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_GET_INTERSECTION_POINTS_HPP
+#define GGL_MULTI_ALGORITHMS_GET_INTERSECTION_POINTS_HPP
+
+#include <ggl/multi/core/is_multi.hpp>
+
+#include <ggl/multi/algorithms/distance.hpp>
+#include <ggl/multi/algorithms/get_section.hpp>
+#include <ggl/multi/algorithms/sectionalize.hpp>
+
+#include <ggl/multi/iterators/point_const_iterator.hpp>
+
+#include <ggl/algorithms/overlay/get_intersection_points.hpp>
+
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+    typename MultiTag1,
+    typename MultiTag2,
+    typename MultiGeometry1,
+    typename MultiGeometry2,
+    typename IntersectionPoints
+>
+struct get_intersection_points
+    <
+        MultiTag1, MultiTag2,
+        true, true,
+        MultiGeometry1, MultiGeometry2,
+        IntersectionPoints
+    >
+    : detail::get_intersection_points::get_ips_generic
+        <
+            MultiGeometry1,
+            MultiGeometry2,
+            IntersectionPoints
+        >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+} // namespace ggl
+
+#endif // GGL_MULTI_ALGORITHMS_GET_INTERSECTION_POINTS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/perimeter.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/perimeter.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,33 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_PERIMETER_HPP
+#define GGL_MULTI_PERIMETER_HPP
+
+#include <ggl/algorithms/perimeter.hpp>
+#include <ggl/multi/algorithms/detail/multi_sum.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+    template <typename MG, typename S>
+    struct perimeter<multi_polygon_tag, MG, S>
+            : detail::multi_sum<double, MG, S,
+                    detail::perimeter::polygon_perimeter<typename boost::range_value<MG>::type, S> > {};
+
+} // namespace dispatch
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_PERIMETER_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/sectionalize.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/sectionalize.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,86 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_SECTIONALIZE_HPP
+#define GGL_MULTI_ALGORITHMS_SECTIONALIZE_HPP
+
+#include <cstddef>
+#include <vector>
+
+#include <boost/concept/requires.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/sectionalize.hpp>
+
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace sectionalize {
+
+
+template <typename MultiGeometry, typename Sections, std::size_t DimensionCount, typename Policy>
+struct sectionalize_multi
+{
+    static inline void apply(MultiGeometry const& multi, Sections& sections)
+    {
+        int multi_index = 0;
+        for (typename boost::range_const_iterator<MultiGeometry>::type
+                    it = boost::begin(multi);
+            it != boost::end(multi);
+            ++it, ++multi_index)
+        {
+            Policy::apply(*it, sections, multi_index);
+        }
+    }
+};
+
+
+
+
+}} // namespace detail::sectionalize
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename MultiPolygon, typename Sections, std::size_t DimensionCount, std::size_t MaxCount>
+struct sectionalize<multi_polygon_tag, MultiPolygon, Sections, DimensionCount, MaxCount>
+    : detail::sectionalize::sectionalize_multi
+        <
+            MultiPolygon,
+            Sections,
+            DimensionCount,
+            detail::sectionalize::sectionalize_polygon
+                <
+                    typename boost::range_value<MultiPolygon>::type,
+                    Sections,
+                    DimensionCount,
+                    MaxCount
+                >
+        >
+
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+
+
+} // namespace ggl
+
+#endif // GGL_MULTI_ALGORITHMS_SECTIONALIZE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/simplify.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/simplify.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,69 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_SIMPLIFY_HPP
+#define GGL_MULTI_SIMPLIFY_HPP
+
+#include <vector>
+
+#include <ggl/algorithms/simplify.hpp>
+
+FIX ME it is not yet adapted to tag-dispatching
+
+namespace ggl
+{
+
+
+        template<typename ML>
+        inline void simplify_multi_linestring(const ML& ml_in, ML& ml_out, double max_distance)
+        {
+            ml_out.resize(ml_in.size());
+            typename ML::const_iterator it_in = ml_in.begin();
+            typename ML::iterator it_out = ml_out.begin();
+            for (; it_in != ml_in.end(); it_in++, it_out++)
+            {
+                simplify_linestring(*it_in, *it_out, max_distance);
+            }
+        }
+
+
+        template<typename MY>
+        inline void simplify_multi_polygon(const MY& mp_in, MY& mp_out, double max_distance)
+        {
+            mp_out.resize(mp_in.size());
+            typename MY::const_iterator it_in = mp_in.begin();
+            typename MY::iterator it_out = mp_out.begin();
+            for (; it_in != mp_in.end(); it_in++, it_out++)
+            {
+                simplify(*it_in, *it_out, max_distance);
+            }
+        }
+
+
+
+template<typename L,
+        template<typename,typename> class V, template<typename> class A>
+inline void simplify(const multi_linestring<L, V, A>& ml_in,
+    multi_linestring<L, V, A>& ml_out, double max_distance)
+{
+    simplify_multi_linestring(ml_in, ml_out, max_distance);
+}
+
+template<typename Y,
+        template<typename,typename> class V, template<typename> class A>
+inline void simplify(const multi_polygon<Y, V, A>& mp_in,
+            multi_polygon<Y, V, A>& mp_out, double max_distance)
+{
+    simplify_multi_polygon(mp_in, mp_out, max_distance);
+}
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_SIMPLIFY_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/transform.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/transform.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,87 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_TRANSFORM_HPP
+#define GGL_MULTI_ALGORITHMS_TRANSFORM_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/transform.hpp>
+
+#include <ggl/multi/core/tags.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace transform {
+
+/*!
+    \brief Is able to transform any multi-geometry, calling the single-version as policy
+*/
+template <typename Multi1, typename Multi2, typename Policy>
+struct transform_multi
+{
+    template <typename S>
+    static inline bool apply(Multi1 const& multi1, Multi2& multi2, S const& strategy)
+    {
+        multi2.resize(boost::size(multi1));
+
+        typename boost::range_const_iterator<Multi1>::type it1 
+                = boost::begin(multi1);
+        typename boost::range_iterator<Multi2>::type it2 
+                = boost::begin(multi2);
+
+        for (; it1 != boost::end(multi1); ++it1, ++it2)
+        {
+            if (! Policy::apply(*it1, *it2, strategy))
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+};
+
+
+
+
+}} // namespace detail::transform
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Multi1, typename Multi2>
+struct transform<multi_polygon_tag, multi_polygon_tag, Multi1, Multi2>
+    : detail::transform::transform_multi
+        <
+            Multi1,
+            Multi2,
+            detail::transform::transform_polygon
+                <
+                    typename boost::range_value<Multi1>::type,
+                    typename boost::range_value<Multi2>::type
+                >
+        >
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+} // namespace ggl
+
+#endif // GGL_MULTI_ALGORITHMS_TRANSFORM_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/within.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/algorithms/within.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,104 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_WITHIN_HPP
+#define GGL_MULTI_ALGORITHMS_WITHIN_HPP
+
+#include <vector>
+
+#include <ggl/algorithms/within.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace within {
+
+
+template<typename P, typename I, typename S>
+inline bool point_in_multi_polygon(const P& p, const I& m, const S& strategy)
+{
+    for (typename I::const_iterator i = m.begin(); i != m.end(); i++)
+    {
+        // Point within a multi-polygon: true if within one of the polygons
+        if (point_in_polygon(p, *i, strategy))
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+
+template<typename I, typename C>
+inline bool multi_polygon_in_circle(const I& m, const C& c)
+{
+    for (typename I::const_iterator i = m.begin(); i != m.end(); i++)
+    {
+        if (! polygon_in_circle(*i, c))
+        {
+            return false;
+        }
+    }
+    return true;
+}
+
+}} // namespace detail::within
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+/*
+template <typename M, typename B>
+struct within<multi_polygon_tag, box_tag, M, B>
+{
+    static inline bool apply(const M& m, const B& b)
+    {
+        return detail::within::multi_polygon_in_box(m, b);
+    }
+};
+*/
+
+template <typename M, typename C>
+struct within<multi_polygon_tag, nsphere_tag, M, C>
+{
+    static inline bool apply(const M& m, const C& c)
+    {
+        return detail::within::multi_polygon_in_circle(m, c);
+    }
+};
+
+template <typename P, typename M>
+struct within<point_tag, multi_polygon_tag, P, M>
+{
+    template <typename S>
+    static inline bool apply(const P& p, const M& m, const S& strategy)
+    {
+        return detail::within::point_in_multi_polygon(p, m, strategy);
+    }
+
+    static inline bool apply(const P& p, const M& m)
+    {
+        typedef typename point_type<M>::type PM;
+        typename strategy_within<
+                    typename cs_tag<P>::type, typename cs_tag<PM>::type, P, PM
+                        >::type strategy;
+        return apply(p, m, strategy);
+    }
+
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+} // namespace ggl
+
+#endif // GGL_MULTI_ALGORITHMS_WITHIN_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/core/geometry_id.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/core/geometry_id.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,51 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_CORE_GEOMETRY_ID_HPP
+#define GGL_MULTI_CORE_GEOMETRY_ID_HPP
+
+
+#include <boost/mpl/int.hpp>
+#include <boost/type_traits.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+#include <ggl/core/geometry_id.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <>
+struct geometry_id<multi_point_tag>      : boost::mpl::int_<4> {};
+
+
+template <>
+struct geometry_id<multi_linestring_tag> : boost::mpl::int_<5> {};
+
+
+template <>
+struct geometry_id<multi_polygon_tag>    : boost::mpl::int_<6> {};
+
+
+
+} // namespace core_dispatch
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_CORE_GEOMETRY_ID_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/core/is_multi.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/core/is_multi.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,49 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_CORE_IS_MULTI_HPP
+#define GGL_MULTI_CORE_IS_MULTI_HPP
+
+
+#include <boost/type_traits.hpp>
+
+
+#include <ggl/core/is_multi.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <>
+struct is_multi<multi_point_tag> : boost::true_type {};
+
+
+template <>
+struct is_multi<multi_linestring_tag> : boost::true_type {};
+
+
+template <>
+struct is_multi<multi_polygon_tag> : boost::true_type {};
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_CORE_IS_MULTI_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/core/point_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/core/point_type.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,59 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_CORE_POINT_TYPE_HPP
+#define GGL_MULTI_CORE_POINT_TYPE_HPP
+
+
+#include <boost/range/metafunctions.hpp>
+
+
+#include <ggl/core/point_type.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+
+
+namespace ggl {
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename MultiPoint>
+struct point_type<multi_point_tag, MultiPoint>
+{
+    typedef typename boost::range_value<MultiPoint>::type type;
+};
+
+
+template <typename MultiLinestring>
+struct point_type<multi_linestring_tag, MultiLinestring>
+{
+    typedef typename point_type<linestring_tag,
+        typename boost::range_value<MultiLinestring>::type>::type type;
+};
+
+
+
+template <typename MultiPolygon>
+struct point_type<multi_polygon_tag, MultiPolygon>
+{
+    typedef typename point_type<polygon_tag,
+        typename boost::range_value<MultiPolygon>::type>::type type;
+};
+
+
+
+
+}
+#endif
+
+} // namespace ggl
+
+#endif // GGL_MULTI_CORE_POINT_TYPE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/core/ring_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/core/ring_type.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,48 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_CORE_RING_TYPE_HPP
+#define GGL_MULTI_CORE_RING_TYPE_HPP
+
+
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/core/ring_type.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename MultiPolygon>
+struct ring_type<multi_polygon_tag, MultiPolygon>
+{
+    typedef typename ggl::ring_type
+        <
+            typename boost::range_value<MultiPolygon>::type
+        >::type type;
+};
+
+
+
+
+} // namespace core_dispatch
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_CORE_RING_TYPE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/core/tags.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/core/tags.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,30 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_CORE_TAGS_HPP
+#define GGL_MULTI_CORE_TAGS_HPP
+
+namespace ggl
+{
+
+/// OGC Multi point identifying tag
+struct multi_point_tag {};
+
+/// OGC Multi linestring identifying tag
+struct multi_linestring_tag {};
+
+/// OGC Multi polygon identifying tag
+struct multi_polygon_tag {};
+
+/// OGC Geometry Collection identifying tag
+struct geometry_collection_tag {};
+
+} // namespace ggl
+
+#endif // GGL_MULTI_CORE_TAGS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/core/topological_dimension.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/core/topological_dimension.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,45 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_TOPOLOGICAL_DIMENSION_HPP
+#define GGL_MULTI_TOPOLOGICAL_DIMENSION_HPP
+
+
+#include <boost/mpl/int.hpp>
+
+
+#include <ggl/core/topological_dimension.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+
+namespace ggl {
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <>
+struct top_dim<multi_point_tag> : boost::mpl::int_<0> {};
+
+
+template <>
+struct top_dim<multi_linestring_tag> : boost::mpl::int_<1> {};
+
+
+template <>
+struct top_dim<multi_polygon_tag> : boost::mpl::int_<2> {};
+
+
+} // namespace core_dispatch
+#endif
+
+} // namespace ggl
+
+
+#endif
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/geometries/multi_linestring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/geometries/multi_linestring.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,55 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_LINESTRING_HPP
+#define GGL_MULTI_LINESTRING_HPP
+
+#include <memory>
+#include <vector>
+
+#include <ggl/core/concepts/linestring_concept.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+namespace ggl
+{
+
+// Class: multi_line
+// Purpose: groups lines belonging to each other, e.g. a broken highway
+template
+<
+    typename L,
+    template<typename, typename> class V = std::vector,
+    template<typename> class A = std::allocator
+>
+struct multi_linestring : public V<L, A<L> >
+{
+    BOOST_CONCEPT_ASSERT( (concept::Linestring<L>) );
+};
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+    typename L,
+    template<typename, typename> class V,
+    template<typename> class A
+>
+struct tag< multi_linestring<L, V, A> >
+{
+    typedef multi_linestring_tag type;
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+} // namespace ggl
+
+#endif // GGL_MULTI_LINESTRING_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/geometries/multi_point.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/geometries/multi_point.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,54 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_GEOMETRIES_MULTI_POINT_HPP
+#define GGL_MULTI_GEOMETRIES_MULTI_POINT_HPP
+
+#include <memory>
+#include <vector>
+
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+namespace ggl
+{
+
+// Class: multi_point
+// Purpose: groups points belonging to each other, e.g. a constellation
+template
+<
+    typename P,
+    template<typename, typename> class V = std::vector,
+    template<typename> class A = std::allocator
+>
+struct multi_point : public V<P, A<P> >
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<P>) );
+};
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+    typename P,
+    template<typename, typename> class V,
+    template<typename> class A
+>
+struct tag< multi_point<P, V, A> >
+{
+    typedef multi_point_tag type;
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_MULTI_GEOMETRIES_MULTI_POINT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/geometries/multi_polygon.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/geometries/multi_polygon.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,55 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_GEOMETRIES_MULTI_POLYGON_HPP
+#define GGL_MULTI_GEOMETRIES_MULTI_POLYGON_HPP
+
+#include <memory>
+#include <vector>
+
+#include <ggl/multi/core/tags.hpp>
+#include <ggl/core/concepts/polygon_concept.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+namespace ggl
+{
+
+// Class: multi_polygon
+// Purpose: groups polygons belonging to each other, e.g. Hawaii
+template
+<
+    typename P,
+    template<typename, typename> class V = std::vector,
+    template<typename> class A = std::allocator
+>
+struct multi_polygon : public V<P, A<P> >
+{
+    BOOST_CONCEPT_ASSERT( (concept::Polygon<P>) );
+};
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+    typename P,
+    template<typename, typename> class V,
+    template<typename> class A
+>
+struct tag< multi_polygon<P, V, A> >
+{
+    typedef multi_polygon_tag type;
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_MULTI_GEOMETRIES_MULTI_POLYGON_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/multi/iterators/point_const_iterator.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/multi/iterators/point_const_iterator.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,50 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_ITERATORS_POINT_CONST_ITERATOR_HPP
+#define GGL_MULTI_ITERATORS_POINT_CONST_ITERATOR_HPP
+
+
+#include <boost/type_traits/remove_const.hpp>
+
+
+#include <ggl/iterators/point_const_iterator.hpp>
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename MultiPolygon>
+struct point_const_iterator<multi_polygon_tag, MultiPolygon>
+{
+    typedef typename boost::range_value<MultiPolygon>::type polygon_type;
+    typedef typename boost::range_const_iterator
+        <
+            typename ring_type<polygon_type>::type
+        >::type type;
+};
+
+
+
+
+} // namespace dispatch
+#endif
+
+
+
+}
+
+
+#endif // GGL_MULTI_ITERATORS_POINT_CONST_ITERATOR_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/policies/relate/de9im.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/policies/relate/de9im.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,184 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRY_POLICIES_RELATE_DE9IM_HPP
+#define GGL_GEOMETRY_POLICIES_RELATE_DE9IM_HPP
+
+
+#include <ggl/strategies/intersection_result.hpp>
+#include <ggl/util/math.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+
+
+namespace ggl
+{
+
+namespace policies { namespace relate {
+
+
+template <typename S1, typename S2>
+struct segments_de9im
+{
+    typedef de9im_segment return_type;
+    typedef S1 segment_type1;
+    typedef S2 segment_type2;
+    typedef typename select_coordinate_type<S1, S2>::type coordinate_type;
+
+    static inline return_type rays_intersect(bool on_segment,
+                    double ra, double rb,
+                    coordinate_type const& dx1, coordinate_type const& dy1,
+                    coordinate_type const& dx2, coordinate_type const& dy2,
+                    coordinate_type const& wx, coordinate_type const& wy,
+                    S1 const& s1, S2 const& s2)
+    {
+        if(on_segment)
+        {
+            // 0 <= ra <= 1 and 0 <= rb <= 1
+            // Now check if one of them is 0 or 1, these are "touch" cases
+            bool a = math::equals(ra, 0.0) || math::equals(ra, 1.0);
+            bool b = math::equals(rb, 0.0) || math::equals(rb, 1.0);
+            if (a && b)
+            {
+                // Touch boundary/boundary: i-i == -1, i-b == -1, b-b == 0
+                // Opposite: if both are equal they touch in opposite direction
+                return de9im_segment(ra,rb,
+                        -1, -1, 1,
+                        -1,  0, 0,
+                         1,  0, 2, false, math::equals(ra,rb));
+            }
+            else if (a || b)
+            {
+                // Touch boundary/interior: i-i == -1, i-b == -1 or 0, b-b == -1
+                int A = a ? 0 : -1;
+                int B = b ? 0 : -1;
+                return de9im_segment(ra,rb,
+                        -1,  B, 1,
+                         A, -1, 0,
+                         1,  0, 2);
+            }
+
+            // Intersects: i-i == 0, i-b == -1, i-e == 1
+            return de9im_segment(ra,rb,
+                     0, -1, 1,
+                    -1, -1, 0,
+                     1,  0, 2);
+        }
+
+        // Not on segment, disjoint
+        return de9im_segment(ra,rb,
+                -1, -1, 1,
+                -1, -1, 0,
+                 1,  0, 2);
+    }
+
+    static inline return_type collinear_touch(coordinate_type const& x,
+                coordinate_type const& y, bool opposite, char)
+    {
+        return de9im_segment(0,0,
+                -1, -1, 1,
+                -1,  0, 0,
+                 1,  0, 2,
+                true, opposite);
+    }
+
+    template <typename S>
+    static inline return_type collinear_interior_boundary_intersect(S const& s,
+                bool a_within_b, bool opposite)
+    {
+        return a_within_b
+            ? de9im_segment(0,0,
+                 1, -1, -1,
+                 0,  0, -1,
+                 1,  0, 2,
+                true, opposite)
+            : de9im_segment(0,0,
+                 1,  0, 1,
+                -1,  0, 0,
+                -1, -1, 2,
+                true, opposite);
+    }
+
+
+
+    static inline return_type collinear_a_in_b(S1 const& s, bool opposite)
+    {
+        return de9im_segment(0,0,
+                1, -1, -1,
+                0, -1, -1,
+                1,  0,  2,
+                true, opposite);
+    }
+    static inline return_type collinear_b_in_a(const S2& s, bool opposite)
+    {
+        return de9im_segment(0,0,
+                 1,  0,  1,
+                -1, -1,  0,
+                -1, -1,  2,
+                true, opposite);
+    }
+
+    static inline return_type collinear_overlaps(
+                    coordinate_type const& x1, coordinate_type const& y1,
+                    coordinate_type const& x2, coordinate_type const& y2, bool opposite)
+    {
+        return de9im_segment(0,0,
+                1,  0, 1,
+                0, -1, 0,
+                1,  0, 2,
+                true, opposite);
+    }
+
+    static inline return_type segment_equal(S1 const& s, bool opposite)
+    {
+        return de9im_segment(0,0,
+                 1, -1, -1,
+                -1,  0, -1,
+                -1, -1,  2,
+                 true, opposite);
+    }
+
+    static inline return_type degenerate(S1 const& segment, bool a_degenerate)
+    {
+            return a_degenerate
+                ? de9im_segment(0,0,
+                     0, -1, -1,
+                    -1, -1, -1,
+                     1,  0,  2,
+                     false, false, false, true)
+                : de9im_segment(0,0,
+                     0, -1,  1,
+                    -1, -1,  0,
+                    -1, -1,  2,
+                     false, false, false, true);
+    }
+
+    static inline return_type collinear_disjoint()
+    {
+        return de9im_segment(0,0,
+                -1, -1, 1,
+                -1, -1, 0,
+                 1,  0, 2,
+                true);
+    }
+
+
+    static inline return_type parallel()
+    {
+        return de9im_segment(0,0,
+                -1, -1, 1,
+                -1, -1, 0,
+                 1,  0, 2, false, false, true);
+    }
+};
+
+
+}} // namespace policies::relate
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRY_POLICIES_RELATE_DE9IM_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/policies/relate/direction.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/policies/relate/direction.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,299 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRY_POLICIES_RELATE_DIRECTION_HPP
+#define GGL_GEOMETRY_POLICIES_RELATE_DIRECTION_HPP
+
+#include <boost/concept_check.hpp>
+
+#include <ggl/util/math.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+
+
+namespace ggl
+{
+
+
+namespace policies { namespace relate {
+
+struct direction_type
+{
+    inline direction_type(char h,
+                double a = 0, double b = 0,
+                int ha = 0, int hb = 0,
+                int da = 0, int db = 0,
+                bool op = false)
+        : how(h)
+        , opposite(op)
+        , ra(a)
+        , rb(b)
+        , how_a(ha)
+        , how_b(hb)
+        , dir_a(da)
+        , dir_b(db)
+    {
+    }
+
+    inline direction_type(char h, bool op, int ha = 0, int hb = 0)
+        : how(h)
+        , opposite(op)
+        , ra(0)
+        , rb(0)
+        , how_a(ha)
+        , how_b(hb)
+        , dir_a(0)
+        , dir_b(0)
+    {
+    }
+
+
+    // "How" is the intersection formed?
+    char how;
+
+    // Is it opposite (for collinear/equal cases)
+    bool opposite;
+
+    // "Distance information", information on how far lies IP from a/b in ratio [0..1]
+    double ra, rb;
+
+    // Information on how A arrives at intersection, how B arrives at intersection
+    // 1: arrives at intersection
+    // -1: starts from intersection
+    int how_a;
+    int how_b;
+
+    // Direction: how is A positioned from B
+    // 1: points left, seen from IP
+    // -1: points right, seen from IP
+    // In case of intersection: B's TO direction
+    // In case that B's TO direction is at A: B's from direction
+    // In collinear cases: it is 0
+    int dir_a; // Direction of A-s TO from IP
+    int dir_b; // Direction of B-s TO from IP
+};
+
+
+template <typename S1, typename S2>
+struct segments_direction
+{
+    typedef direction_type return_type;
+    typedef S1 segment_type1;
+    typedef S2 segment_type2;
+    typedef typename select_coordinate_type<S1, S2>::type coordinate_type;
+
+    static inline return_type rays_intersect(bool on_segment,
+                    double ra, double rb,
+                    coordinate_type const& dx1, coordinate_type const& dy1,
+                    coordinate_type const& dx2, coordinate_type const& dy2,
+                    coordinate_type const& wx, coordinate_type const& wy,
+                    S1 const& s1, S2 const& s2)
+    {
+        boost::ignore_unused_variable_warning(dx2);
+        boost::ignore_unused_variable_warning(dy2);
+        boost::ignore_unused_variable_warning(wx);
+        boost::ignore_unused_variable_warning(wy);
+
+        if(on_segment)
+        {
+            // 0 <= ra <= 1 and 0 <= rb <= 1
+            // Check the configuration
+            bool ra0 = math::equals(ra, 0.0);
+            bool ra1 = math::equals(ra, 1.0);
+            bool rb0 = math::equals(rb, 0.0);
+            bool rb1 = math::equals(rb, 1.0);
+
+            return
+                // opposite and same starting point (FROM)
+                ra0 && rb0 ? calculate_side<1>(ra, rb, dx1, dy1, s1, s2, 'f', -1, -1)
+
+                // opposite and point to each other (TO)
+                : ra1 && rb1 ? calculate_side<0>(ra, rb, dx1, dy1, s1, s2, 't', 1, 1)
+
+                // not opposite, forming an angle, first a then b,
+                // directed either both left, or both right
+                // Check side of B2 from A. This is not calculated before
+                : ra1 && rb0 ? angle<1>(ra, rb, dx1, dy1, s1, s2, 'a', 1, -1)
+
+                // not opposite, forming a angle, first b then a,
+                // directed either both left, or both right
+                : ra0 && rb1 ? angle<0>(ra, rb, dx1, dy1, s1, s2, 'a', -1, 1)
+
+                // b starts from interior of a
+                : rb0 ? starts_from_middle(ra, rb, dx1, dy1, s1, s2, 'B', 0, -1)
+
+                // a starts from interior of b (#39)
+                : ra0 ? starts_from_middle(ra, rb, dx1, dy1, s1, s2, 'A', -1, 0)
+
+                // b ends at interior of a, calculate direction of A from IP
+                : rb1 ? b_ends_at_middle(ra, rb, dx2, dy2, s1, s2)
+
+                // a ends at interior of b
+                : ra1 ? a_ends_at_middle(ra, rb, dx1, dy1, s1, s2)
+
+                // normal intersection
+                : calculate_side<1>(ra, rb, dx1, dy1, s1, s2, 'i', -1, -1)
+                ;
+        }
+
+        // Not on segment, disjoint
+        return return_type('d');
+    }
+
+    static inline return_type collinear_touch(coordinate_type const& , coordinate_type const& , bool opposite, char how)
+    {
+        // Though this is 'collinear', we handle it as To/From/Angle because it is the same.
+        // It only does NOT have a direction.
+        int const arrive = how == 'T' ? 1 : -1;
+        return
+            ! opposite
+            ? return_type('a', 0, 0, how == 'A' ? 1 : -1, how == 'B' ? 1 : -1)
+            : return_type(how == 'T' ? 't' : 'f', 0, 0, arrive, arrive, 0, 0, true);
+    }
+
+    template <typename S>
+    static inline return_type collinear_interior_boundary_intersect(S const& , bool, bool opposite)
+    {
+        return return_type('c', opposite);
+    }
+
+    static inline return_type collinear_a_in_b(S1 const& , bool opposite)
+    {
+        return return_type('c', opposite);
+    }
+    static inline return_type collinear_b_in_a(S2 const& , bool opposite)
+    {
+        return return_type('c', opposite);
+    }
+
+    static inline return_type collinear_overlaps(
+                    coordinate_type const& , coordinate_type const& ,
+                    coordinate_type const& , coordinate_type const& , bool opposite)
+    {
+        return return_type('c', opposite);
+    }
+
+    static inline return_type segment_equal(S1 const& , bool opposite)
+    {
+        return return_type('e', opposite);
+    }
+
+    static inline return_type degenerate(S1 const& , bool)
+    {
+        return return_type('0');
+    }
+
+    static inline return_type collinear_disjoint()
+    {
+        return return_type('d');
+    }
+
+
+    static inline return_type parallel()
+    {
+        return return_type('p');
+    }
+
+private :
+
+
+    template <std::size_t I>
+    static inline return_type calculate_side(double ra, double rb,
+                coordinate_type const& dx1, coordinate_type const& dy1,
+                S1 const& s1, S2 const& s2,
+                char how, int how_a, int how_b)
+    {
+        coordinate_type dpx = get<I, 0>(s2) - get<0, 0>(s1);
+        coordinate_type dpy = get<I, 1>(s2) - get<0, 1>(s1);
+
+        // This is a "side calculation" as in the strategies, but here two terms are precalculated
+        // We might merge this with side, offering a pre-calculated term
+        // Waiting for implementing spherical...
+
+        return dx1 * dpy - dy1 * dpx > 0
+            ? return_type(how, ra, rb, how_a, how_b, -1, 1)
+            : return_type(how, ra, rb, how_a, how_b, 1, -1);
+    }
+
+    template <std::size_t I>
+    static inline return_type angle(double ra, double rb,
+                coordinate_type const& dx1, coordinate_type const& dy1,
+                S1 const& s1, S2 const& s2,
+                char how, int how_a, int how_b)
+    {
+        coordinate_type dpx = get<I, 0>(s2) - get<0, 0>(s1);
+        coordinate_type dpy = get<I, 1>(s2) - get<0, 1>(s1);
+
+         return dx1 * dpy - dy1 * dpx > 0
+            ? return_type(how, ra, rb, how_a, how_b, 1, 1)
+            : return_type(how, ra, rb, how_a, how_b, -1, -1);
+    }
+
+
+    static inline return_type starts_from_middle(double ra, double rb,
+                coordinate_type const& dx1, coordinate_type const& dy1,
+                S1 const& s1, S2 const& s2,
+                char which,
+                int how_a, int how_b)
+    {
+        // Calculate ARROW of b segment w.r.t. s1
+        coordinate_type dpx = get<1, 0>(s2) - get<0, 0>(s1);
+        coordinate_type dpy = get<1, 1>(s2) - get<0, 1>(s1);
+
+        int dir = dx1 * dpy - dy1 * dpx > 0 ? 1 : -1;
+
+        // From other perspective, then reverse
+        bool const is_a = which == 'A';
+        if (is_a)
+        {
+            dir = -dir;
+        }
+
+        return return_type('s', ra, rb,
+            how_a,
+            how_b,
+            is_a ? dir : -dir,
+            ! is_a ? dir : -dir);
+    }
+
+
+
+    // To be harmonized
+    static inline return_type a_ends_at_middle(double ra, double rb,
+                coordinate_type const& dx, coordinate_type const& dy,
+                S1 const& s1, S2 const& s2)
+    {
+        coordinate_type dpx = get<1, 0>(s2) - get<0, 0>(s1);
+        coordinate_type dpy = get<1, 1>(s2) - get<0, 1>(s1);
+
+        // Ending at the middle, one ARRIVES, the other one is NEUTRAL
+        // (because it both "arrives"  and "departs"  there
+        return dx * dpy - dy * dpx > 0
+            ? return_type('m', ra, rb, 1, 0, 1, 1)
+            : return_type('m', ra, rb, 1, 0, -1, -1);
+    }
+
+
+    static inline return_type b_ends_at_middle(double ra, double rb,
+                coordinate_type const& dx, coordinate_type const& dy,
+                S1 const& s1, S2 const& s2)
+    {
+        coordinate_type dpx = get<1, 0>(s1) - get<0, 0>(s2);
+        coordinate_type dpy = get<1, 1>(s1) - get<0, 1>(s2);
+
+        return dx * dpy - dy * dpx > 0
+            ? return_type('m', ra, rb, 0, 1, 1, 1)
+            : return_type('m', ra, rb, 0, 1, -1, -1);
+    }
+
+};
+
+}} // namespace policies::relate
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRY_POLICIES_RELATE_DIRECTION_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/policies/relate/intersection_points.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/policies/relate/intersection_points.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,143 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRY_POLICIES_RELATE_INTERSECTION_POINTS_HPP
+#define GGL_GEOMETRY_POLICIES_RELATE_INTERSECTION_POINTS_HPP
+
+#include <boost/concept_check.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+
+
+namespace ggl
+{
+
+namespace policies { namespace relate {
+
+
+template <typename S1, typename S2, typename ReturnType>
+struct segments_intersection_points
+{
+    typedef ReturnType return_type;
+    typedef S1 segment_type1;
+    typedef S2 segment_type2;
+    typedef typename select_coordinate_type<S1, S2>::type coordinate_type;
+
+    static inline return_type rays_intersect(bool on_segment,
+                    double ra, double rb,
+                    coordinate_type const& dx1, coordinate_type const& dy1,
+                    coordinate_type const& dx2, coordinate_type const& dy2,
+                    coordinate_type const& wx, coordinate_type const& wy,
+                    S1 const& s1, S2 const& s2)
+    {
+        boost::ignore_unused_variable_warning(rb);
+        boost::ignore_unused_variable_warning(dx2);
+        boost::ignore_unused_variable_warning(dy2);
+        boost::ignore_unused_variable_warning(wx);
+        boost::ignore_unused_variable_warning(wy);
+        boost::ignore_unused_variable_warning(s2);
+
+        return_type result;
+
+        if (on_segment)
+        {
+            result.count = 1;
+            set<0>(result.intersections[0],
+                boost::numeric_cast<coordinate_type>(get<0, 0>(s1) + ra * dx1));
+            set<1>(result.intersections[0],
+                boost::numeric_cast<coordinate_type>(get<0, 1>(s1) + ra * dy1));
+        }
+        return result;
+    }
+
+    static inline return_type collinear_touch(coordinate_type const& x,
+                coordinate_type const& y, bool, char)
+    {
+        return_type result;
+        result.count = 1;
+        set<0>(result.intersections[0], x);
+        set<1>(result.intersections[0], y);
+        return result;
+    }
+
+    template <typename S>
+    static inline return_type collinear_inside(S const& s)
+    {
+        return_type result;
+        result.count = 2;
+        set<0>(result.intersections[0], get<0, 0>(s));
+        set<1>(result.intersections[0], get<0, 1>(s));
+        set<0>(result.intersections[1], get<1, 0>(s));
+        set<1>(result.intersections[1], get<1, 1>(s));
+        return result;
+    }
+
+    template <typename S>
+    static inline return_type collinear_interior_boundary_intersect(S const& s, bool, bool)
+    {
+        return collinear_inside(s);
+    }
+
+    static inline return_type collinear_a_in_b(S1 const& s, bool)
+    {
+        return collinear_inside(s);
+    }
+    static inline return_type collinear_b_in_a(S2 const& s, bool)
+    {
+        return collinear_inside(s);
+    }
+
+    static inline return_type collinear_overlaps(
+                coordinate_type const& x1, coordinate_type const& y1,
+                coordinate_type const& x2, coordinate_type const& y2, bool)
+    {
+        return_type result;
+        result.count = 2;
+        set<0>(result.intersections[0], x1);
+        set<1>(result.intersections[0], y1);
+        set<0>(result.intersections[1], x2);
+        set<1>(result.intersections[1], y2);
+        return result;
+    }
+
+    static inline return_type segment_equal(S1 const& s, bool)
+    {
+        return_type result;
+        result.count = 2;
+        set<0>(result.intersections[0], get<0, 0>(s));
+        set<1>(result.intersections[0], get<0, 1>(s));
+        set<0>(result.intersections[1], get<1, 0>(s));
+        set<1>(result.intersections[1], get<1, 1>(s));
+        return result;
+    }
+
+    static inline return_type collinear_disjoint()
+    {
+        return return_type();
+    }
+    static inline return_type parallel()
+    {
+        return return_type();
+    }
+    static inline return_type degenerate(S1 const& s, bool)
+    {
+        return_type result;
+        result.count = 1;
+        set<0>(result.intersections[0], get<0, 0>(s));
+        set<1>(result.intersections[0], get<0, 1>(s));
+        return result;
+    }
+};
+
+
+}} // namespace policies::relate
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRY_POLICIES_RELATE_INTERSECTION_POINTS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/policies/relate/tupled.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/policies/relate/tupled.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,154 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRY_POLICIES_RELATE_TUPLED_HPP
+#define GGL_GEOMETRY_POLICIES_RELATE_TUPLED_HPP
+
+#include <boost/tuple/tuple.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+
+namespace ggl
+{
+
+namespace policies { namespace relate {
+
+
+// "tupled" to return intersection results together.
+// Now with two, with some meta-programming and derivations it can also be three (or more)
+template <typename Policy1, typename Policy2>
+struct segments_tupled
+{
+    typedef boost::tuple
+        <
+            typename Policy1::return_type,
+            typename Policy2::return_type
+        > return_type;
+
+    // Take segments of first policy, they should be equal
+    typedef typename Policy1::segment_type1 segment_type1;
+    typedef typename Policy1::segment_type2 segment_type2;
+
+    typedef typename select_coordinate_type
+        <
+            segment_type1,
+            segment_type2
+        >::type coordinate_type;
+
+
+    static inline return_type rays_intersect(bool on_segment,
+                    double ra, double rb,
+                    coordinate_type const& dx1, coordinate_type const& dy1,
+                    coordinate_type const& dx2, coordinate_type const& dy2,
+                    coordinate_type const& wx, coordinate_type const& wy,
+                    segment_type1 const& s1, segment_type2 const& s2)
+    {
+        return boost::make_tuple
+            (
+                Policy1::rays_intersect(on_segment, ra, rb, dx1, dy1, dx2, dy2, wx, wy, s1, s2),
+                Policy2::rays_intersect(on_segment, ra, rb, dx1, dy1, dx2, dy2, wx, wy, s1, s2)
+            );
+    }
+
+    static inline return_type collinear_touch(coordinate_type const& x,
+                coordinate_type const& y, bool opposite, char how)
+    {
+        return boost::make_tuple
+            (
+                Policy1::collinear_touch(x, y, opposite, how),
+                Policy2::collinear_touch(x, y, opposite, how)
+            );
+    }
+
+    template <typename S>
+    static inline return_type collinear_interior_boundary_intersect(S const& segment,
+                bool a_within_b, bool opposite)
+    {
+        return boost::make_tuple
+            (
+                Policy1::collinear_interior_boundary_intersect(segment, a_within_b, opposite),
+                Policy2::collinear_interior_boundary_intersect(segment, a_within_b, opposite)
+            );
+    }
+
+    static inline return_type collinear_a_in_b(segment_type1 const& segment,
+                bool opposite)
+    {
+        return boost::make_tuple
+            (
+                Policy1::collinear_a_in_b(segment, opposite),
+                Policy2::collinear_a_in_b(segment, opposite)
+            );
+    }
+    static inline return_type collinear_b_in_a(segment_type2 const& segment,
+                    bool opposite)
+    {
+        return boost::make_tuple
+            (
+                Policy1::collinear_b_in_a(segment, opposite),
+                Policy2::collinear_b_in_a(segment, opposite)
+            );
+    }
+
+
+    static inline return_type collinear_overlaps(
+                    coordinate_type const& x1, coordinate_type const& y1,
+                    coordinate_type const& x2, coordinate_type const& y2,
+                    bool opposite)
+    {
+        return boost::make_tuple
+            (
+                Policy1::collinear_overlaps(x1, y1, x2, y2, opposite),
+                Policy2::collinear_overlaps(x1, y1, x2, y2, opposite)
+            );
+    }
+
+    static inline return_type segment_equal(segment_type1 const& s,
+                bool opposite)
+    {
+        return boost::make_tuple
+            (
+                Policy1::segment_equal(s, opposite),
+                Policy2::segment_equal(s, opposite)
+            );
+    }
+
+    static inline return_type degenerate(segment_type1 const& segment,
+                bool a_degenerate)
+    {
+        return boost::make_tuple
+            (
+                Policy1::degenerate(segment, a_degenerate),
+                Policy2::degenerate(segment, a_degenerate)
+            );
+    }
+
+    static inline return_type collinear_disjoint()
+    {
+        return boost::make_tuple
+            (
+                Policy1::collinear_disjoint(),
+                Policy2::collinear_disjoint()
+            );
+    }
+
+
+    static inline return_type parallel()
+    {
+        return boost::make_tuple
+            (
+                Policy1::parallel(),
+                Policy2::parallel()
+            );
+    }
+};
+
+}} // namespace policies::relate
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRY_POLICIES_RELATE_TUPLED_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/agn_convex_hull.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/agn_convex_hull.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,278 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_AGNOSTIC_CONVEX_HULL_HPP
+#define GGL_STRATEGIES_AGNOSTIC_CONVEX_HULL_HPP
+
+#ifdef _MSC_VER
+#pragma warning( disable : 4101 )
+#endif
+
+#include <cstddef>
+#include <algorithm>
+#include <vector>
+
+#include <boost/range/functions.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/strategies/strategy_traits.hpp>
+
+// TODO: Temporary, comparing tests, this can be removed in the end
+#if defined(GGL_USE_SMOOTH_SORT)
+#  include "SmoothSort.hpp"
+#elif defined(GGL_USE_MERGE_SORT)
+#  include "MergeSort.hpp"
+#else
+#endif
+
+namespace ggl
+{
+
+namespace strategy { namespace convex_hull {
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename Range, typename RangeIterator, typename Strategy>
+static inline void get_extremes(const Range& range,
+            RangeIterator& min_it, RangeIterator& max_it,
+            const Strategy& strategy)
+{
+    min_it = boost::begin(range);
+    max_it = boost::begin(range);
+
+    for (RangeIterator it = boost::begin(range) + 1; it != boost::end(range); ++it)
+    {
+        if (strategy.smaller(*it, *min_it))
+        {
+            min_it = it;
+        }
+
+        if (strategy.larger(*it, *max_it))
+        {
+            max_it = it;
+        }
+    }
+}
+
+template <typename R>
+static inline void sort(R& range)
+{
+    #if defined(USE_SMOOTH_SORT)
+    smoothsort::sort(boost::begin(range), boost::end(range));
+    #elif defined(USE_MERGE_SORT)
+    comparing::merge_sort<thread_count>(boost::begin(range), boost::end(range), std::less<P>());
+    #else
+    std::sort(boost::begin(range), boost::end(range));
+    #endif
+}
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+// Completely reworked version from source at:
+// http://www.ddj.com/architect/201806315
+// also available at http://marknelson.us/2007/08/22/convex
+template <typename P>
+class graham
+{
+private:
+
+    typedef typename cs_tag<P>::type cs_tag;
+    typedef typename std::vector<P> container;
+    typedef typename std::vector<P>::const_iterator iterator;
+    typedef typename std::vector<P>::const_reverse_iterator rev_iterator;
+
+    container m_lower_hull;
+    container m_upper_hull;
+    container m_copied_input;
+
+
+public:
+
+    // Default constructor, ranges can be added using "add_range" but note they'll be copied
+    inline graham()
+    {
+    }
+
+    // Constructor with a range
+    template <typename Range>
+    inline graham(const Range& range)
+    {
+        handle_range(range);
+    }
+
+
+    template <typename OutputIterator>
+    inline void get(OutputIterator out)
+    {
+        for (iterator it = m_upper_hull.begin(); it != m_upper_hull.end(); ++it, ++out)
+        {
+            *out = *it;
+        }
+
+        // STL Port does not accept iterating from rbegin+1 to rend
+        std::size_t size = m_lower_hull.size();
+        if (size > 0)
+        {
+            rev_iterator it = m_lower_hull.rbegin() + 1;
+            for (std::size_t i = 1; i < size; ++i, ++it, ++out)
+            {
+                *out = *it;
+            }
+        }
+    }
+
+
+    // Note /
+    // TODO:
+    // Consider if it is better to create an iterator over a multi, which is then used here,
+    // instead of copying the range
+    // It makes it slightly more complicated but avoids the copy, which is attractive because
+    // multi-polygons (where it is used for) can be large.
+    template <typename Range>
+    inline void add_range(const Range& range)
+    {
+        std::copy(boost::begin(range), boost::end(range), std::back_inserter(m_copied_input));
+    }
+
+    inline void handle_input()
+    {
+        handle_range(m_copied_input);
+    }
+
+
+private:
+
+    template <typename Range>
+    inline void handle_range(const Range& range)
+    {
+        typedef typename boost::range_const_iterator<Range>::type range_iterator;
+
+        // Polygons with three corners, or closed with 4 points, are always convex
+        if (boost::size(range) <= 3)
+        {
+            for (range_iterator it = boost::begin(range);
+                        it != boost::end(range);
+                        ++it)
+            {
+                m_upper_hull.push_back(*it);
+            }
+            return;
+        }
+
+        // Get min/max (in most cases left / right) points
+        range_iterator left_it, right_it;
+        typename strategy_compare<cs_tag, P, 0>::type comparing;
+        detail::get_extremes(range, left_it, right_it, comparing);
+
+        // Bounding left/right points
+        container lower_points, upper_points;
+
+        assign_range(range, left_it, right_it, lower_points, upper_points);
+
+        detail::sort(lower_points);
+        detail::sort(upper_points);
+
+        build_half_hull<1>(lower_points, m_lower_hull, *left_it, *right_it);
+        build_half_hull<-1>(upper_points, m_upper_hull, *left_it, *right_it);
+    }
+
+
+
+    template <typename RangeIterator, typename Range>
+    inline void assign_range(const Range& range,
+            const RangeIterator& left_it,
+            const RangeIterator& right_it,
+            container& lower_points,
+            container& upper_points)
+    {
+        typename strategy_side<cs_tag, P>::type side;
+
+        // Put points in one of the two output sequences
+        for (RangeIterator it = boost::begin(range);
+            it != boost::end(range);
+            ++it)
+        {
+            if (it != left_it && it != right_it)
+            {
+                int dir = side.side(*left_it, *right_it, *it);
+                if ( dir < 0 )
+                {
+                    upper_points.push_back(*it);
+                }
+                else
+                {
+                    lower_points.push_back(*it);
+                }
+            }
+        }
+    }
+
+
+    template <int Factor>
+    inline void build_half_hull(const container& input, container& output,
+            const P& left, const P& right)
+    {
+        output.push_back(left);
+        for(iterator it = input.begin(); it != input.end(); ++it)
+        {
+            add_to_hull<Factor>(*it, output);
+        }
+        add_to_hull<Factor>(right, output);
+    }
+
+    template <int Factor>
+    inline void add_to_hull(const P& p, container& output)
+    {
+        typename strategy_side<cs_tag, P>::type side;
+
+        output.push_back(p);
+        register std::size_t output_size = output.size();
+        while (output_size >= 3)
+        {
+            rev_iterator rit = output.rbegin();
+            const P& last = *rit++;
+            const P& last2 = *rit++;
+
+            if (Factor * side.side(*rit, last, last2) <= 0)
+            {
+                // Remove last two points from stack, and add last again
+                // This is much faster then erasing the one but last.
+                output.pop_back();
+                output.pop_back();
+                output.push_back(last);
+                output_size--;
+            }
+            else
+            {
+                return;
+            }
+        }
+    }
+
+
+};
+
+}} // namespace strategy::convex_hull
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <typename P>
+struct strategy_convex_hull<cartesian_tag, P>
+{
+    typedef strategy::convex_hull::graham<P> type;
+};
+#endif
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGY_AGNOSTIC_CONVEX_HULL_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/agn_simplify.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/agn_simplify.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,196 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGY_AGNOSTIC_SIMPLIFY_HPP
+#define GGL_STRATEGY_AGNOSTIC_SIMPLIFY_HPP
+
+#include <boost/range/functions.hpp>
+
+#include <ggl/core/cs.hpp>
+
+
+//#define GL_DEBUG_SIMPLIFY
+
+#ifdef GL_DEBUG_SIMPLIFY
+#include <ggl/extensions/gis/io/wkt/write_wkt.hpp>
+#include <ggl/extensions/gis/io/wkt/stream_wkt.hpp>
+#include <iostream>
+#endif
+
+
+namespace ggl
+{
+namespace strategy
+{
+    namespace simplify
+    {
+        #ifndef DOXYGEN_NO_DETAIL
+        namespace detail
+        {
+
+            /*!
+                \brief Small wrapper around a point, with an extra member "included"
+                \details
+                - We could implement a complete point as well but that is not necessary
+                - We could derive from ggl::point but we need the original later on, including extra members;
+                    besides that it is not necessary to copy points during the algorithm
+                \tparam the enclosed point type
+            */
+            template<typename P>
+            struct douglas_peucker_point
+            {
+                const P& p;
+                bool included;
+
+                inline douglas_peucker_point(const P& ap)
+                    : p(ap)
+                    , included(false)
+                {}
+
+                inline douglas_peucker_point<P> operator=(const douglas_peucker_point<P>& other)
+                {
+                    return douglas_peucker_point<P>(*this);
+                }
+            };
+        }
+        #endif // DOXYGEN_NO_DETAIL
+
+
+        /*!
+            \brief Implements the simplify algorithm.
+            \ingroup simplify
+            \details The douglas_peucker strategy simplifies a linestring, ring or vector of points
+            using the well-known Douglas-Peucker algorithm. For the algorithm, see for example:
+            \see http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
+            \see http://www2.dcs.hull.ac.uk/CISRG/projects/Royal-Inst/demos/dp.html
+            \tparam R boost range
+            \tparam O_IT output iterator
+            \tparam PSDS point-segment distance strategy to be used
+            \note This strategy uses itself a point-segment-distance strategy which can be specified
+            \author Barend and Maarten, 1995/1996
+            \author Barend, revised for Generic Geometry Library, 2008
+        */
+        template<typename R, typename O_IT, typename PSDS>
+        class douglas_peucker
+        {
+            typedef typename point_type<R>::type P;
+            typedef detail::douglas_peucker_point<P> DP;
+            typedef typename std::vector<DP>::iterator DIT;
+
+            typedef typename PSDS::return_type RET;
+
+            inline void consider(DIT begin, DIT end, const RET& max_dist, int& n,
+                            const PSDS& ps_distance_strategy) const
+            {
+                size_t size = end - begin;
+                // size must be at least 3 here: we want to consider a candidate point between begin and end
+                if (size <= 2)
+                {
+#ifdef GL_DEBUG_SIMPLIFY
+                    if (begin != end)
+                    {
+                        std::cout << "ignore between " << begin->p << " and " << (end - 1)->p << " size=" << size << std::endl;
+                    }
+                    std::cout << "return because size=" << size << std::endl;
+#endif
+                    return;
+                }
+
+                DIT last = end - 1;
+
+#ifdef GL_DEBUG_SIMPLIFY
+                std::cout << "find between " << begin->p << " and " << last->p << " size=" << size << std::endl;
+#endif
+
+
+                // Find most distance point, compare to the current segment
+                ggl::segment<const P> s(begin->p, last->p);
+                RET md(-1.0); // any value < 0
+                DIT candidate;
+                for(DIT it = begin + 1; it != last; it++)
+                {
+                    RET dist = ps_distance_strategy(it->p, s);
+
+#ifdef GL_DEBUG_SIMPLIFY
+                    std::cout << "consider " << it->p << " at " << dist.value() << (dist.value() > max_dist.value() ? " maybe" : " no") << std::endl;
+#endif
+                    if (dist > md)
+                    {
+                        md = dist;
+                        candidate = it;
+                    }
+                }
+
+                // If a point is found, set the include flag and handle segments in between recursively
+                if (md > max_dist)
+                {
+#ifdef GL_DEBUG_SIMPLIFY
+                    std::cout << "use " << candidate->p << std::endl;
+#endif
+
+                    candidate->included = true;
+                    n++;
+
+                    consider(begin, candidate + 1, max_dist, n, ps_distance_strategy);
+                    consider(candidate, end, max_dist, n, ps_distance_strategy);
+                }
+            }
+
+
+        public :
+
+            typedef PSDS distance_strategy_type;
+
+            /*!
+                \brief Call simplification on an iterator pair
+            */
+            inline void simplify(const R& range, O_IT out, double max_distance) const
+            {
+                PSDS strategy;
+                // Init the output, a vector of references to all points
+
+                // Note Geometry Algorithms suggest here
+                // http://geometryalgorithms.com/Archive/algorithm_0205/algorithm_0205.htm
+                // to "STAGE 1: Vertex Reduction within max_distance of prior vertex cluster"
+                // However, that is not correct: a vertex within the specified distance might be
+                // excluded here, but might be a better candidate for final inclusion than the point before.
+
+                std::vector<DP> ref_candidates(boost::begin(range), boost::end(range));
+
+                // Include first and last point of line, they are always part of the line
+                int n = 2;
+                ref_candidates.front().included = true;
+                ref_candidates.back().included = true;
+
+                // Get points, recursively, including them if they are further away than the specified distance
+                typedef typename PSDS::return_type RET;
+
+                consider(boost::begin(ref_candidates), boost::end(ref_candidates),
+                    make_distance_result<RET>(max_distance), n, strategy);
+
+                // Copy included elements to the output  (might be changed using copy_if)
+                for(typename std::vector<DP>::const_iterator it = boost::begin(ref_candidates);
+                    it != boost::end(ref_candidates); it++)
+                {
+                    if (it->included)
+                    {
+                        *out = it->p;
+                        out++;
+                    }
+                }
+            }
+
+        };
+
+    }
+}
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGY_AGNOSTIC_SIMPLIFY_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/agn_within.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/agnostic/agn_within.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,162 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGY_AGNOSTIC_WITHIN_HPP
+#define GGL_STRATEGY_AGNOSTIC_WITHIN_HPP
+
+
+
+#include <ggl/geometries/segment.hpp>
+
+#include <ggl/strategies/strategy_traits.hpp>
+
+
+
+namespace ggl
+{
+namespace strategy
+{
+    namespace within
+    {
+
+        /*!
+            \brief Within detection using winding rule
+            \tparam P point type of point to examine
+            \tparam PS point type of segments, defaults to P
+            \author Barend Gehrels
+            \note The implementation is inspired by terralib http://www.terralib.org (LGPL)
+            \note but totally revised afterwards, especially for cases on segments
+            \note More efficient (less comparisons and no divison) than the cross count algorithm
+            \note Only dependant on "side", -> agnostic, suitable for latlong
+         */
+        template<typename P, typename PS = P>
+        class winding
+        {
+            private :
+                typedef typename coordinate_type<P>::type PT;
+                typedef typename coordinate_type<PS>::type ST;
+
+                /*! subclass to keep state */
+                struct windings
+                {
+                    int count;
+                    bool touches;
+                    const P& p;
+                    inline explicit windings(const P& ap)
+                        : count(0)
+                        , touches(false)
+                        , p(ap)
+                    {}
+                    inline bool within() const
+                    {
+                        return ! touches && count != 0;
+                    }
+                };
+
+                template <size_t D>
+                static inline int check_touch(const segment<const PS>& s, windings& state)
+                {
+                    const PT& p = get<D>(state.p);
+                    const ST& s1 = get<0, D>(s);
+                    const ST& s2 = get<1, D>(s);
+                    if ((s1 <= p && s2 >= p) || (s2 <= p && s1 >= p))
+                    {
+                        state.touches = true;
+                    }
+                    return 0;
+                }
+
+
+                template <size_t D>
+                static inline int check_segment(const segment<const PS>& s, windings& state)
+                {
+                    const PT& p = get<D>(state.p);
+                    const ST& s1 = get<0, D>(s);
+                    const ST& s2 = get<1, D>(s);
+
+                    // Check if one of segment endpoints is at same level of point
+                    bool eq1 = math::equals(s1, p);
+                    bool eq2 = math::equals(s2, p);
+
+                    if (eq1 && eq2)
+                    {
+                        // Both equal p -> segment is horizontal (or vertical for D=0)
+                        // The only thing which has to be done is check if point is ON segment
+                        return check_touch<1 - D>(s, state);
+                    }
+
+                    return
+                          eq1 ? (s2 > p ?  1 : -1)  // P on level s1, UP/DOWN depending on s2
+                        : eq2 ? (s1 > p ? -1 :  1)  // idem
+                        : s1 < p && s2 > p ?  2     // P between s1 -> s2 --> UP
+                        : s2 < p && s1 > p ? -2     // P between s2 -> s1 --> DOWN
+                        : 0;
+                }
+
+
+            public :
+
+                typedef windings state_type;
+
+                inline bool operator()(const segment<const PS>& s, state_type& state) const
+                {
+                    int cnt = check_segment<1>(s, state);
+                    if (cnt != 0)
+                    {
+                        typedef typename strategy_side<typename cs_tag<P>::type, P, PS>::type SS;
+
+                        typename select_coordinate_type<P, PS>::type side = SS::side(s, state.p);
+
+                        if (math::equals(side, 0))
+                        {
+                            // Point is lying on segment
+                            state.touches = true;
+                            state.count = 0;
+                            return false;
+                        }
+
+                        // Side is NEG for right, POS for left.
+                        // CNT is -2 for down, 2 for up (or -1/1)
+                        // Side positive thus means UP and LEFTSIDE or DOWN and RIGHTSIDE
+                        // See accompagnying figure (TODO)
+                        int sd = (side > 0 ? 1 : -1) * cnt;
+                        if (sd > 0)
+                        {
+                            state.count += cnt;
+                        }
+
+                    }
+                    return ! state.touches;
+                }
+
+        };
+
+    } // namespace within
+
+} // namespace strategy
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <typename P, typename PS>
+struct strategy_within<cartesian_tag, cartesian_tag, P, PS>
+{
+    typedef strategy::within::winding<P, PS> type;
+};
+
+template <typename P, typename PS>
+struct strategy_within<geographic_tag, geographic_tag, P, PS>
+{
+    typedef strategy::within::winding<P, PS> type;
+};
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGY_AGNOSTIC_WITHIN_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_area.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_area.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,102 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGY_CARTESIAN_AREA_HPP
+#define GGL_STRATEGY_CARTESIAN_AREA_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+#include <ggl/geometries/point_xy.hpp>
+#include <ggl/geometries/segment.hpp>
+
+
+namespace ggl
+{
+namespace strategy
+{
+    namespace area
+    {
+
+        /*!
+            \brief Strategy functor for area calculation on point_xy points
+            \details Calculates area using well-known triangulation algorithm
+            \tparam PS point type of segments
+            \par Concepts for PS:
+            - specialized point_traits class
+        */
+        template<typename PS, typename CalculationType = void>
+        class by_triangles
+        {
+            public :
+                // If user specified a calculation type, use that type,
+                //   whatever it is and whatever the point-type is.
+                // Else, use the pointtype, but at least double
+                typedef typename
+                    boost::mpl::if_c
+                    <
+                        boost::is_void<CalculationType>::type::value,
+                        typename select_most_precise
+                        <
+                            typename coordinate_type<PS>::type,
+                            double
+                        >::type,
+                        CalculationType
+                    >::type return_type;
+
+
+            private :
+
+                struct summation
+                {
+                    return_type sum;
+
+                    inline summation() : sum(return_type())
+                    {
+                        // Currently only 2D areas are supported
+                        assert_dimension<PS, 2>();
+                    }
+                    inline return_type area() const
+                    {
+                        return_type result = sum;
+                        result *= 0.5;
+                        return result;
+                    }
+                };
+
+            public :
+                typedef summation state_type;
+
+                inline bool operator()(segment<const PS> const& s,
+                            state_type& state) const
+                {
+                    // SUM += x2 * y1 - x1 * y2;
+                    state.sum += get<1, 0>(s) * get<0, 1>(s)
+                                - get<0, 0>(s) * get<1, 1>(s);
+                    return true;
+                }
+
+        };
+
+    } // namespace area
+} // namespace strategy
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <typename P>
+struct strategy_area<cartesian_tag, P>
+{
+    typedef strategy::area::by_triangles<P> type;
+};
+#endif
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGY_CARTESIAN_AREA_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_centroid.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_centroid.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,292 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGY_CARTESIAN_CENTROID_HPP
+#define GGL_STRATEGY_CARTESIAN_CENTROID_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/type_traits.hpp>
+
+#include <ggl/geometries/point_xy.hpp>
+#include <ggl/geometries/segment.hpp>
+
+#include <ggl/algorithms/assign.hpp>
+
+#include <ggl/util/select_coordinate_type.hpp>
+#include <ggl/util/copy.hpp>
+
+
+namespace ggl
+{
+
+namespace strategy
+{
+    namespace centroid
+    {
+        /*!
+            \brief Centroid calculation
+            \details Geolib original version,
+            \par Template parameters and concepts: see bashein_detmer
+            \author Barend and Maarten, 1995/1996
+            \author Revised for templatized library, Barend Gehrels, 2007
+            \note The results are slightly different from Bashein/Detmer, so probably slightly wrong.
+        */
+
+        template<typename PC, typename PS = PC>
+        class geolib1995
+        {
+            private  :
+                typedef typename select_most_precise
+                    <
+                        typename select_coordinate_type<PC, PS>::type,
+                        double
+                    >::type T;
+
+                /*! subclass to keep state */
+                struct sums
+                {
+                     PC sum_ms, sum_m;
+
+                    sums()
+                    {
+                        assign_point(sum_m, T());
+                        assign_point(sum_ms, T());
+                    }
+                    void centroid(PC& point)
+                    {
+                        point = sum_ms;
+
+                        if (get<0>(sum_m) != 0 && get<1>(sum_m) != 0)
+                        {
+                            multiply_value(point, 0.5);
+                            divide_point(point, sum_m);
+                        }
+                        else
+                        {
+                            // exception?
+                        }
+                    }
+                };
+
+            public :
+                typedef sums state_type;
+                inline bool operator()(const segment<const PS>& s, state_type& state) const
+                {
+                    /* Algorithm:
+                    For each segment:
+                    begin
+                        dx = x2 - x1;
+                        dy = y2 - y1;
+                        sx = x2 + x1;
+                        sy = y2 + y1;
+                        mx = dx * sy;
+                        my = sx * dy;
+
+                        sum_mx += mx;
+                        sum_my += my;
+                        sum_msx += mx * sx;
+                        sum_msy += my * sy;
+                    end;
+                    return POINT(0.5 * sum_msx / sum_mx, 0.5 * sum_msy / sum_my);
+                    */
+
+                    PS diff = s.second, sum = s.second;
+                    subtract_point(diff, s.first);
+                    add_point(sum, s.first);
+
+                    // We might create an arithmatic operation for this.
+                    PS m;
+                    get<0>(m) = get<0>(diff) * get<1>(sum);
+                    get<1>(m) = get<0>(sum) * get<1>(diff);
+
+                    add_point(state.sum_m, m);
+                    multiply_point(m, sum);
+                    add_point(state.sum_ms, m);
+
+                    return true;
+                }
+
+        };
+
+
+        /*!
+            \brief Centroid calculation using algorith Bashein / Detmer
+            \details Calculates centroid using triangulation method published by Bashein / Detmer
+            \tparam PC point type of centroid to calculate
+            \tparam PS point type of segments, defaults to PC
+            \par Concepts for PC and PS:
+            - specialized point_traits class
+            \author Adapted from  "Centroid of a Polygon" by Gerard Bashein and Paul R. Detmer<em>,
+            in "Graphics Gems IV", Academic Press, 1994</em>
+            \par Research notes
+            The algorithm gives the same results as Oracle and PostGIS but differs from MySQL
+            (tried 5.0.21 / 5.0.45 / 5.0.51a / 5.1.23).
+
+            Without holes:
+            - this:       POINT(4.06923363095238 1.65055803571429)
+            - geolib:     POINT(4.07254 1.66819)
+            - MySQL:      POINT(3.6636363636364  1.6272727272727)'
+            - PostGIS:    POINT(4.06923363095238 1.65055803571429)
+            - Oracle:           4.06923363095238 1.65055803571429
+            - SQL Server: POINT(4.06923362245959 1.65055804168294)
+
+            Statements:
+            - \b MySQL/PostGIS: select AsText(Centroid(GeomFromText('POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2
+                            ,3.7 1.6,3.4 2,4.1 3,5.3 2.6,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3))')))
+            - \b Oracle: select sdo_geom.sdo_centroid(sdo_geometry(2003, null, null,
+                    sdo_elem_info_array(1, 1003, 1), sdo_ordinate_array(2,1.3,2.4,1.7,2.8,1.8
+                    ,3.4,1.2,3.7,1.6,3.4,2,4.1,3,5.3,2.6,5.4,1.2,4.9,0.8,2.9,0.7,2,1.3))
+                    , mdsys.sdo_dim_array(mdsys.sdo_dim_element('x',0,10,.00000005)
+                    ,mdsys.sdo_dim_element('y',0,10,.00000005)))
+                    from dual
+            - \b SQL Server 2008: select geometry::STGeomFromText('POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2
+                            ,3.7 1.6,3.4 2,4.1 3,5.3 2.6,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3))',0)
+                            .STCentroid()
+                            .STAsText()
+
+            With holes:
+            - this:       POINT(4.04663 1.6349)
+            - geolib:     POINT(4.04675 1.65735)
+            - MySQL:      POINT(3.6090580503834 1.607573932092)
+            - PostGIS:    POINT(4.0466265060241 1.63489959839357)
+            - Oracle:           4.0466265060241 1.63489959839357
+            - SQL Server: POINT(4.0466264962959677 1.6348996057331333)
+
+            Statements:
+            - \b MySQL/PostGIS: select AsText(Centroid(GeomFromText('POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2
+                    ,3.7 1.6,3.4 2,4.1 3,5.3 2.6,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3)
+                    ,(4 2,4.2 1.4,4.8 1.9,4.4 2.2,4 2))')));
+            - \b Oracle: select sdo_geom.sdo_centroid(sdo_geometry(2003, null, null
+                    , sdo_elem_info_array(1, 1003, 1, 25, 2003, 1)
+                    , sdo_ordinate_array(2,1.3,2.4,1.7,2.8,1.8,3.4,1.2,3.7,1.6,3.4,2,4.1,3,5.3
+                    ,2.6,5.4,1.2,4.9,0.8,2.9,0.7,2,1.3,4,2, 4.2,1.4, 4.8,1.9, 4.4,2.2, 4,2))
+                    , mdsys.sdo_dim_array(mdsys.sdo_dim_element('x',0,10,.00000005)
+                    ,mdsys.sdo_dim_element('y',0,10,.00000005)))
+                    from dual
+         */
+        template
+        <
+            typename CentroidPointType,
+            typename SegmentPointType = CentroidPointType,
+            typename CalculationType = void
+        >
+        class bashein_detmer
+        {
+            private :
+                // If user specified a calculation type, use that type,
+                //   whatever it is and whatever the point-type(s) are.
+                // Else, use the most appropriate coordinate type
+                //    of the two points, but at least double
+                typedef typename
+                    boost::mpl::if_c
+                    <
+                        boost::is_void<CalculationType>::type::value,
+                        typename select_most_precise
+                        <
+                            typename select_coordinate_type
+                                <
+                                    CentroidPointType,
+                                    SegmentPointType
+                                >::type,
+                            double
+                        >::type,
+                        CalculationType
+                    >::type calc_type;
+
+                /*! subclass to keep state */
+                struct sums
+                {
+                    calc_type sum_a2;
+                    calc_type sum_x;
+                    calc_type sum_y;
+                    inline sums()
+                        : sum_a2(calc_type())
+                        , sum_x(calc_type())
+                        , sum_y(calc_type())
+                    {
+                        typedef calc_type ct;
+                        //std::cout << "-> calctype: " << typeid(ct).name()
+                        //    << " size: " << sizeof(ct)
+                        //    << " init: " << sum_a2
+                        //    << std::endl;
+                    }
+
+                    inline void centroid(CentroidPointType& point)
+                    {
+                        if (sum_a2 != 0)
+                        {
+                            calc_type const v3 = 3;
+                            calc_type const a3 = v3 * sum_a2;
+
+                            typedef typename ggl::coordinate_type
+                                <
+                                    CentroidPointType
+                                >::type coordinate_type;
+
+                            set<0>(point,
+                                boost::numeric_cast<coordinate_type>(sum_x / a3));
+                            set<1>(point,
+                                boost::numeric_cast<coordinate_type>(sum_y / a3));
+                        }
+                        else
+                        {
+                            // exception?
+                        }
+                    }
+
+                };
+
+            public :
+                typedef sums state_type;
+
+                inline bool operator()(segment<const SegmentPointType> const& s, state_type& state) const
+                {
+                    /* Algorithm:
+                    For each segment:
+                    begin
+                        ai = x1 * y2 - x2 * y1;
+                        sum_a2 += ai;
+                        sum_x += ai * (x1 + x2);
+                        sum_y += ai * (y1 + y2);
+                    end
+                    return POINT(sum_x / (3 * sum_a2), sum_y / (3 * sum_a2) )
+                    */
+
+                    // Get coordinates and promote them to calc_type
+                    calc_type const x1 = boost::numeric_cast<calc_type>(get<0, 0>(s));
+                    calc_type const y1 = boost::numeric_cast<calc_type>(get<0, 1>(s));
+                    calc_type const x2 = boost::numeric_cast<calc_type>(get<1, 0>(s));
+                    calc_type const y2 = boost::numeric_cast<calc_type>(get<1, 1>(s));
+                    calc_type const ai = x1 * y2 - x2 * y1;
+                    state.sum_a2 += ai;
+                    state.sum_x += ai * (x1 + x2);
+                    state.sum_y += ai * (y1 + y2);
+
+                    return true;
+                }
+
+        };
+    } // namespace centroid
+
+} // namespace strategy
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <typename P, typename PS>
+struct strategy_centroid<cartesian_tag, P, PS>
+{
+    typedef strategy::centroid::bashein_detmer<P, PS> type;
+};
+#endif
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGY_CARTESIAN_CENTROID_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_compare.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_compare.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,66 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGY_CARTESIAN_COMPARE_HPP
+#define GGL_STRATEGY_CARTESIAN_COMPARE_HPP
+
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/access.hpp>
+
+
+#include <ggl/strategies/strategy_traits.hpp>
+
+
+namespace ggl
+{
+namespace strategy
+{
+    namespace compare
+    {
+
+
+        /*!
+            \brief Compare (in one direction) strategy for cartesian coordinates
+            \ingroup util
+            \tparam P point-type
+            \tparam D dimension
+        */
+        template <typename P, size_t D>
+        struct euclidian
+        {
+            static inline bool smaller(const P& p1, const P& p2)
+            {
+                return get<D>(p1) < get<D>(p2);
+            }
+
+            static inline bool larger(const P& p1, const P& p2)
+            {
+                return get<D>(p1) > get<D>(p2);
+            }
+
+        };
+    } // namespace compare
+} // namespace strategy
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+template <typename P, size_t D>
+struct strategy_compare<cartesian_tag, P, D>
+{
+    typedef strategy::compare::euclidian<P, D> type;
+};
+
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGY_CARTESIAN_COMPARE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_distance.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_distance.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,246 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGY_CARTESIAN_DISTANCE_HPP
+#define GGL_STRATEGY_CARTESIAN_DISTANCE_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/point_type.hpp>
+
+#include <ggl/arithmetic/arithmetic.hpp>
+#include <ggl/arithmetic/dot_product.hpp>
+
+#include <ggl/strategies/strategy_traits.hpp>
+#include <ggl/strategies/distance_result.hpp>
+
+#include <ggl/util/select_coordinate_type.hpp>
+#include <ggl/util/copy.hpp>
+
+
+// Helper geometry
+#include <ggl/geometries/segment.hpp>
+
+namespace ggl {
+
+namespace strategy { namespace distance {
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename P1, typename P2, size_t I, typename T>
+struct compute_pythagoras
+{
+    static inline T apply(P1 const& p1, P2 const& p2)
+    {
+        T const c1 = boost::numeric_cast<T>(get<I-1>(p2));
+        T const c2 = boost::numeric_cast<T>(get<I-1>(p1));
+        T const d = c1 - c2;
+        return d * d + compute_pythagoras<P1, P2, I-1, T>::apply(p1, p2);
+    }
+};
+
+template <typename P1, typename P2, typename T>
+struct compute_pythagoras<P1, P2, 0, T>
+{
+    static inline T apply(P1 const&, P2 const&)
+    {
+        return boost::numeric_cast<T>(0);
+    }
+};
+
+}
+#endif
+
+/*!
+    \brief Strategy for distance point to point: pythagoras
+    \ingroup distance
+    \tparam P1 first point type
+    \tparam P2 optional, second point type, defaults to first point type
+    \par Concepts for P1 and P2:
+    - specialized point_traits class
+*/
+template
+<
+    typename P1,
+    typename P2 = P1,
+    typename CalculationType = void
+>
+struct pythagoras
+{
+    typedef typename
+        boost::mpl::if_c
+        <
+            boost::is_void<CalculationType>::type::value,
+            typename select_coordinate_type
+                <
+                    P1,
+                    P2
+                >::type,
+            CalculationType
+        >::type calculation_type;
+
+    typedef cartesian_distance<calculation_type> return_type;
+
+
+    inline return_type operator()(P1 const& p1, P2 const& p2) const
+    {
+
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P1>) );
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P2>) );
+
+        // Calculate distance using Pythagoras
+        // (Leave comment above for Doxygen)
+
+        assert_dimension_equal<P1, P2>();
+
+        return return_type(detail::compute_pythagoras
+            <
+                P1, P2,
+                dimension<P1>::value,
+                calculation_type
+            >::apply(p1, p2));
+    }
+};
+
+
+/*!
+    \brief Strategy for distance point to segment
+    \ingroup distance
+    \details Calculates distance using projected-point method, and (optionally) Pythagoras
+    \author Adapted from: http://geometryalgorithms.com/Archive/algorithm_0102/algorithm_0102.htm
+    \tparam P point type
+    \tparam SEG segment type
+    \tparam S strategy, optional, defaults to pythagoras
+    \par Concepts for S:
+    - cartesian_distance operator(P,P)
+*/
+template
+<
+    typename P,
+    typename Segment,
+    typename Strategy = pythagoras<P, typename point_type<Segment>::type>
+>
+struct xy_point_segment
+{
+    typedef typename select_coordinate_type<P, Segment>::type coordinate_type;
+    typedef cartesian_distance<coordinate_type> return_type;
+    typedef Strategy distance_strategy_type; // OBSOLETE!
+    typedef Strategy point_strategy_type;
+
+
+    inline return_type operator()(P const& p, Segment const& s) const
+    {
+        assert_dimension_equal<P, Segment>();
+
+        /* Algorithm
+        POINT v(x2 - x1, y2 - y1);
+        POINT w(px - x1, py - y1);
+        c1 = w . v
+        c2 = v . v
+        b = c1 / c2
+        RETURN POINT(x1 + b * vx, y1 + b * vy);
+        */
+
+        typedef typename boost::remove_const
+        <
+            typename point_type<Segment>::type
+        >::type segment_point_type;
+
+        segment_point_type v, w;
+
+        // TODO
+        // ASSUMPTION: segment
+        // SOLVE THIS USING OTHER FUNCTIONS using get<,>
+        copy_coordinates(s.second, v);
+        copy_coordinates(p, w);
+        subtract_point(v, s.first);
+        subtract_point(w, s.first);
+
+        Strategy strategy;
+
+        coordinate_type c1 = dot_product(w, v);
+        if (c1 <= 0)
+        {
+            return strategy(p, s.first);
+        }
+        coordinate_type c2 = dot_product(v, v);
+        if (c2 <= c1)
+        {
+            return strategy(p, s.second);
+        }
+
+        // Even in case of char's, we have to turn to a point<double/float>
+        // because of the division.
+        coordinate_type b = c1 / c2;
+
+        // Note that distances with integer coordinates do NOT work because
+        // - the project point is integer
+        // - if we solve that, the used distance_strategy cannot handle double points
+        segment_point_type projected;
+        copy_coordinates(s.first, projected);
+        multiply_value(v, b);
+        add_point(projected, v);
+
+        return strategy(p, projected);
+
+    }
+};
+
+}} // namespace strategy::distance
+
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <typename P1, typename P2>
+struct strategy_distance<cartesian_tag, cartesian_tag, P1, P2>
+{
+    typedef strategy::distance::pythagoras<P1, P2> type;
+};
+
+template <typename Point, typename Segment>
+struct strategy_distance_segment<cartesian_tag, cartesian_tag, Point, Segment>
+{
+    typedef typename point_type<Segment>::type segment_point_type;
+
+    typedef strategy::distance::xy_point_segment
+    <
+        Point,
+        Segment,
+        typename strategy_distance
+        <
+            cartesian_tag, cartesian_tag, Point, segment_point_type
+        >::type
+    > type;
+};
+#endif
+
+
+template <typename P1, typename P2>
+struct strategy_tag<strategy::distance::pythagoras<P1, P2> >
+{
+    typedef strategy_tag_distance_point_point type;
+};
+
+template <typename Point, typename Segment, typename PPStrategy>
+struct strategy_tag<strategy::distance::xy_point_segment<Point, Segment, PPStrategy> >
+{
+    typedef strategy_tag_distance_point_segment type;
+};
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGY_CARTESIAN_DISTANCE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_envelope.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_envelope.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,66 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGY_CARTESIAN_ENVELOPE_HPP
+#define GGL_STRATEGY_CARTESIAN_ENVELOPE_HPP
+
+
+
+#include <ggl/geometries/point_xy.hpp>
+#include <ggl/geometries/segment.hpp>
+
+#include <ggl/algorithms/combine.hpp>
+
+
+namespace ggl
+{
+namespace strategy
+{
+    namespace envelope
+    {
+        // envelope calculation strategy for xy-points
+        template <typename P, typename B>
+        struct combine_xy
+        {
+            struct state
+            {
+                B& m_box;
+                state(B& box) : m_box(box)
+                {
+                    assign_inverse(m_box);
+                }
+            };
+
+            typedef state state_type;
+
+            void operator()(const P& p, state_type& s) const
+            {
+                ggl::combine(s.m_box, p);
+            }
+        };
+    } // namespace envelope
+
+} // namespace strategy
+
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <typename P, typename B>
+struct strategy_envelope<cartesian_tag, cartesian_tag, P, B>
+{
+    typedef strategy::envelope::combine_xy<P, B> type;
+};
+
+
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGY_CARTESIAN_ENVELOPE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_intersect.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_intersect.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,352 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGY_CARTESIAN_INTERSECTION_HPP
+#define GGL_STRATEGY_CARTESIAN_INTERSECTION_HPP
+
+#include <algorithm>
+
+#include <ggl/core/exception.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/core/concepts/segment_concept.hpp>
+
+#include <ggl/util/select_coordinate_type.hpp>
+
+
+namespace ggl
+{
+
+
+class relate_cartesian_segments_exception : public ggl::exception
+{
+public:
+
+    relate_cartesian_segments_exception()  {}
+
+    virtual char const* what() const throw()
+    {
+        return "GGL: Internal error, unexpected case in relate_segment";
+    }
+};
+
+
+namespace strategy { namespace intersection {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename S, size_t D>
+struct segment_interval
+{
+    template <typename T>
+    static inline void arrange(S const& s, T& s_1, T& s_2, bool& swapped)
+    {
+        s_1 = get<0, D>(s);
+        s_2 = get<1, D>(s);
+        if (s_1 > s_2)
+        {
+            std::swap(s_1, s_2);
+            swapped = true;
+        }
+    }
+};
+
+}
+#endif
+
+
+/*!
+    \see http://mathworld.wolfram.com/Line-LineIntersection.html
+ */
+template <typename F>
+struct relate_cartesian_segments
+{
+    typedef typename F::return_type RETURN_TYPE;
+    typedef typename F::segment_type1 S1;
+    typedef typename F::segment_type2 S2;
+
+    typedef typename point_type<S1>::type P;
+    BOOST_CONCEPT_ASSERT( (concept::Point<P>) );
+
+    BOOST_CONCEPT_ASSERT( (concept::ConstSegment<S1>) );
+    BOOST_CONCEPT_ASSERT( (concept::ConstSegment<S2>) );
+    typedef typename select_coordinate_type<S1, S2>::type T;
+
+    /// Relate segments a and b
+    static inline RETURN_TYPE relate(S1 const& a, S2 const& b)
+    {
+        T dx_a = get<1, 0>(a) - get<0, 0>(a); // distance in x-dir
+        T dx_b = get<1, 0>(b) - get<0, 0>(b);
+        T dy_a = get<1, 1>(a) - get<0, 1>(a); // distance in y-dir
+        T dy_b = get<1, 1>(b) - get<0, 1>(b);
+        return relate(a, b, dx_a, dy_a, dx_b, dy_b);
+    }
+
+
+    /// Relate segments a and b using precalculated differences. This can save two or four substractions in many cases
+    static inline RETURN_TYPE relate(S1 const& a, S2 const& b,
+            T const& dx_a, T const& dy_a, T const& dx_b, T const& dy_b)
+    {
+        T wx = get<0, 0>(a) - get<0, 0>(b);
+        T wy = get<0, 1>(a) - get<0, 1>(b);
+
+        // Calculate determinants - Cramers rule
+        T d = (dy_b * dx_a) - (dx_b * dy_a);
+        T da = (dx_b * wy) - (dy_b * wx);
+        T db = (dx_a * wy) - (dy_a * wx);
+
+        if(! math::equals(d, 0))
+        {
+            // Determinant d is nonzero. Rays do intersect. This is the normal case.
+            // ra/rb: ratio 0-1 where intersection divides A/B
+
+            // Maybe:
+            // The ra/rb calculation can probably also be avoided, only necessary to calculate the points themselves
+            // On segment: 0 <= r <= 1
+            //      where: r==0 and r==1 are special cases
+            // --> r=0 if and only if da==0 (d != 0) [this is also checked below]
+            // --> r=1 da==d
+            // --> da/d > 0 if da==positive and d==positive OR da==neg and d==neg
+            // --> da/d < 1 if (both positive) da < d or (negative) da > d, e.g. -2 > -4
+            // --> it would save a division but makes it complexer
+
+            double ra = double(da) / double(d);
+            double rb = double(db) / double(d);
+
+            return F::rays_intersect(ra >= 0 && ra <= 1 && rb >= 0 && rb <= 1, ra, rb,
+                dx_a, dy_a, dx_b, dy_b, wx, wy, a, b);
+        }
+
+        if(math::equals(da, 0) && math::equals(db, 0))
+        {
+            // Both da & db are zero. Segments are collinear. We'll find out how.
+            return relate_collinear(a, b, dx_a, dy_a, dx_b, dy_b);
+        }
+
+        // Segments are parallel (might still be opposite but this is probably never interesting)
+        return F::parallel();
+    }
+
+private :
+
+
+    /// Relate segments known collinear
+    static inline RETURN_TYPE relate_collinear(S1 const& a, S2 const& b,
+            T const& dx_a, T const& dy_a,
+            T const& dx_b, T const& dy_b)
+    {
+        // All ca. 200 lines are about collinear rays
+        // The intersections, if any, are always boundary points of the segments. No need to calculate anything.
+        // However we want to find out HOW they intersect, there are many cases.
+        // Most sources only provide the intersection (above) or that there is a collinearity (but not the points)
+        // or some spare sources give the intersection points (calculated) but not how they align.
+        // This source tries to give everything and still be efficient.
+        // It is therefore (and because of the extensive clarification comments) rather long...
+
+        // \see http://mpa.itc.it/radim/g50history/CMP/4.2.1-CERL-beta-libes/file475.txt
+        // \see http://docs.codehaus.org/display/GEOTDOC/Point+Set+Theory+and+the+DE-9IM+Matrix
+        // \see http://mathworld.wolfram.com/Line-LineIntersection.html
+
+        // Because of collinearity the case is now one-dimensional and can be checked using intervals
+        // We arrange either horizontally or vertically
+        // We get then two intervals:
+        // a_1-------------a_2 where a_1 < a_2
+        // b_1-------------b_2 where b_1 < b_2
+        // In all figures below a_1/a_2 denotes arranged intervals, a1-a2 or a2-a1 are still unarranged
+        T a_1, a_2, b_1, b_2;
+        bool a_swapped = false, b_swapped = false;
+        if (math::equals(dx_b, 0))
+        {
+            // Vertical -> Check y-direction
+            detail::segment_interval<S1, 1>::arrange(a, a_1, a_2, a_swapped);
+            detail::segment_interval<S1, 1>::arrange(b, b_1, b_2, b_swapped);
+        }
+        else
+        {
+            // Check x-direction
+            detail::segment_interval<S1, 0>::arrange(a, a_1, a_2, a_swapped);
+            detail::segment_interval<S1, 0>::arrange(b, b_1, b_2, b_swapped);
+        }
+
+        // First handle "disjoint", probably common case.
+        // 2 cases: a_1----------a_2    b_1-------b_2 or B left of A
+        if (a_2 < b_1 || a_1 > b_2)
+        {
+            return F::collinear_disjoint();
+        }
+
+        // Then handle "equal", in polygon neighbourhood comparisons also a common case
+
+        // Check if segments are equal...
+        bool a1_eq_b1 = math::equals(get<0, 0>(a), get<0, 0>(b))
+                    && math::equals(get<0, 1>(a), get<0, 1>(b));
+        bool a2_eq_b2 = math::equals(get<1, 0>(a), get<1, 0>(b))
+                    && math::equals(get<1, 1>(a), get<1, 1>(b));
+        if (a1_eq_b1 && a2_eq_b2)
+        {
+            return F::segment_equal(a, false);
+        }
+
+        // ... or opposite equal
+        bool a1_eq_b2 = math::equals(get<0, 0>(a), get<1, 0>(b))
+                    && math::equals(get<0, 1>(a), get<1, 1>(b));
+        bool a2_eq_b1 = math::equals(get<1, 0>(a), get<0, 0>(b))
+                    && math::equals(get<1, 1>(a), get<0, 1>(b));
+        if (a1_eq_b2 && a2_eq_b1)
+        {
+            return F::segment_equal(a, true);
+        }
+
+
+        // Degenerate cases: segments of single point, lying on other segment, non disjoint
+        if (math::equals(dx_a, 0) && math::equals(dy_a, 0))
+        {
+            return F::degenerate(a, true);
+        }
+        if (math::equals(dx_b, 0) && math::equals(dy_b, 0))
+        {
+            return F::degenerate(b, false);
+        }
+
+
+        // The rest below will return one or two intersections.
+        // The delegated class can decide which is the intersection point, or two, build the Intersection Matrix (IM)
+        // For IM it is important to know which relates to which. So this information is given,
+        // without performance penalties to intersection calculation
+
+        bool has_common_points = a1_eq_b1 || a1_eq_b2 || a2_eq_b1 || a2_eq_b2;
+
+
+        // "Touch" -> one intersection point -> one but not two common points
+        // -------->             A (or B)
+        //         <----------   B (or A)
+        //        a_2==b_1         (b_2==a_1 or a_2==b1)
+
+        // The check a_2/b_1 is necessary because it excludes cases like
+        // ------->
+        //     --->
+        // ... which are handled lateron
+
+        // Corresponds to 4 cases, of which the equal points are determined above
+        // 1: a1---->a2 b1--->b2   ("a" first)
+        // 2: a2<----a1 b2<---b1   ("b" first)
+        // 3: a1---->a2 b2<---b1   ("t": to)
+        // 4: a2<----a1 b1--->b2   ("f": from)
+        // Where the arranged forms have two forms:
+        //    a_1-----a_2/b_1-------b_2 or reverse (B left of A)
+        if (has_common_points && (math::equals(a_2, b_1) || math::equals(b_2, a_1)))
+        {
+            if (a2_eq_b1) return F::collinear_touch(get<1, 0>(a), get<1, 1>(a), false, 'A');
+            if (a2_eq_b2) return F::collinear_touch(get<1, 0>(a), get<1, 1>(a), true, 'T');
+            if (a1_eq_b2) return F::collinear_touch(get<0, 0>(a), get<0, 1>(a), false, 'B');
+            if (a1_eq_b1) return F::collinear_touch(get<0, 0>(a), get<0, 1>(a), true, 'F');
+        }
+
+
+        // "Touch/within" -> there are common points and also an intersection of interiors:
+        // Corresponds to many cases:
+        // Case 1: a1------->a2  Case 5:      a1-->a2  Case 9:  a1--->a2
+        //             b1--->b2          b1------->b2           b1---------b2
+        // Case 2: a2<-------a1
+        //             b1----b2  Et cetera
+        // Case 3: a1------->a2
+        //             b2<---b1
+        // Case 4: a2<-------a1
+        //             b2<---b1
+
+        // For case 1-4: a_1 < (b_1 or b_2) < a_2, two intersections are equal to segment B
+        // For case 5-8: b_1 < (a_1 or a_2) < b_2, two intersections are equal to segment A
+        if (has_common_points)
+        {
+            bool a_in_b =  (b_1 < a_1 && a_1 < b_2) || (b_1 < a_2 && a_2 < b_2);
+            if (a2_eq_b2) return F::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, false);
+            if (a1_eq_b2) return F::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, true);
+            if (a2_eq_b1) return F::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, true);
+            if (a1_eq_b1) return F::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, false);
+        }
+
+        bool opposite = a_swapped ^ b_swapped;
+
+
+        // "Inside", a completely within b or b completely within a
+        // 2 cases:
+        // case 1:
+        //        a_1---a_2        -> take A's points as intersection points
+        //   b_1------------b_2
+        // case 2:
+        //   a_1------------a_2
+        //       b_1---b_2         -> take B's points
+        if (a_1 > b_1 && a_2 < b_2)
+        {
+            // A within B
+            return F::collinear_a_in_b(a, opposite);
+        }
+        if (b_1 > a_1 && b_2 < a_2)
+        {
+            // B within A
+            return F::collinear_b_in_a(b, opposite);
+        }
+
+
+        // Now that all cases with equal,touch,inside,disjoint,degenerate are handled the only thing left is an overlap
+        // Case 1: a1--------->a2         a_1---------a_2
+        //                 b1----->b2             b_1------b_2
+        // Case 2: a2<---------a1         a_1---------a_2          a_swapped
+        //                 b1----->b2             b_1------b_2
+        // Case 3: a1--------->a2         a_1---------a_2
+        //                 b2<-----b1             b_1------b_2     b_swapped
+        // Case 4: a2<-------->a1         a_1---------a_2          a_swapped
+        //                 b2<-----b1             b_1------b_2     b_swapped
+
+        // Case 5:     a1--------->a2          a_1---------a_2
+        //         b1----->b2             b1--------b2
+        // Case 6:     a2<---------a1
+        //         b1----->b2
+        // Case 7:     a1--------->a2
+        //         b2<-----b1
+        // Case 8:     a2<-------->a1
+        //         b2<-----b1
+
+        if (a_1 < b_1 && b_1 < a_2)
+        {
+            // Case 4,2,3,1
+            return
+                  a_swapped && b_swapped   ? F::collinear_overlaps(get<0, 0>(a), get<0, 1>(a), get<1, 0>(b), get<1, 1>(b), opposite)
+                : a_swapped                ? F::collinear_overlaps(get<0, 0>(a), get<0, 1>(a), get<0, 0>(b), get<0, 1>(b), opposite)
+                : b_swapped                ? F::collinear_overlaps(get<1, 0>(a), get<1, 1>(a), get<1, 0>(b), get<1, 1>(b), opposite)
+                :                            F::collinear_overlaps(get<1, 0>(a), get<1, 1>(a), get<0, 0>(b), get<0, 1>(b), opposite)
+                ;
+        }
+        if (b_1 < a_1 && a_1 < b_2)
+        {
+            // Case 8, 6, 7, 5
+            return
+                  a_swapped && b_swapped   ? F::collinear_overlaps(get<1, 0>(a), get<1, 1>(a), get<0, 0>(b), get<0, 1>(b), opposite)
+                : a_swapped                ? F::collinear_overlaps(get<1, 0>(a), get<1, 1>(a), get<1, 0>(b), get<1, 1>(b), opposite)
+                : b_swapped                ? F::collinear_overlaps(get<0, 0>(a), get<0, 1>(a), get<0, 0>(b), get<0, 1>(b), opposite)
+                :                            F::collinear_overlaps(get<0, 0>(a), get<0, 1>(a), get<1, 0>(b), get<1, 1>(b), opposite)
+                ;
+        }
+
+        // Nothing should goes through. If any we have made an error
+        // TODO: proper exception
+        throw relate_cartesian_segments_exception();
+    }
+};
+
+
+}} // namespace strategy::intersection
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGY_CARTESIAN_INTERSECTION_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_side.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_side.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,71 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGY_CARTESIAN_SIDE_HPP
+#define GGL_STRATEGY_CARTESIAN_SIDE_HPP
+
+
+
+#include <ggl/geometries/point_xy.hpp>
+#include <ggl/geometries/segment.hpp>
+
+#include <ggl/util/select_coordinate_type.hpp>
+
+
+
+namespace ggl
+{
+namespace strategy
+{
+    namespace side
+    {
+
+        template <typename P, typename PS>
+        struct xy_side
+        {
+
+            // Check at which side of a segment a point lies:
+            // left of segment (> 0), right of segment (< 0), on segment (0)
+            // In fact this is twice the area of a triangle
+            static inline typename select_coordinate_type<P, PS>::type
+                side(const segment<const PS>& s, const P& p)
+            {
+                typedef typename select_coordinate_type<P, PS>::type T;
+
+                // Todo: might be changed to subtract_point
+                T dx = get<1, 0>(s) - get<0, 0>(s);
+                T dy = get<1, 1>(s) - get<0, 1>(s);
+                T dpx = get<0>(p) - get<0, 0>(s);
+                T dpy = get<1>(p) - get<0, 1>(s);
+                return dx * dpy - dy * dpx;
+            }
+
+
+            static inline int side(const P& p0, const P& p1, const P& p2)
+            {
+                typename coordinate_type<P>::type s = side(segment<const P>(p0, p1), p2);
+                return s > 0 ? 1 : s < 0 ? -1 : 0;
+            }
+        };
+
+    } // namespace side
+} // namespace strategy
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <typename P, typename PS>
+struct strategy_side<cartesian_tag, P, PS>
+{
+    typedef strategy::side::xy_side<P, PS> type;
+};
+#endif
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGY_CARTESIAN_SIDE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_within.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/cartesian/cart_within.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,100 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGY_CARTESIAN_WITHIN_HPP
+#define GGL_STRATEGY_CARTESIAN_WITHIN_HPP
+
+
+
+#include <ggl/geometries/segment.hpp>
+
+
+
+namespace ggl
+{
+namespace strategy
+{
+    namespace within
+    {
+        /*!
+            \brief Within detection using cross counting
+
+            \author adapted from Randolph Franklin algorithm
+            \author Barend and Maarten, 1995
+            \author Revised for templatized library, Barend Gehrels, 2007
+            \return true if point is in ring, works for closed rings in both directions
+            \note Does NOT work correctly for point ON border
+         */
+
+        template<typename P, typename PS = P>
+        struct franklin
+        {
+            private :
+                /*! subclass to keep state */
+                struct crossings
+                {
+                    P p;
+                    bool crosses;
+                    explicit crossings(const P& ap)
+                        : p(ap)
+                        , crosses(false)
+                    {}
+                    bool within() const
+                    {
+                        return crosses;
+                    }
+                };
+
+            public :
+
+                typedef crossings state_type;
+
+                inline bool operator()(const segment<const PS>& s, state_type& state) const
+                {
+                    /* Algorithm:
+                    if (
+                        ( (y2 <= py && py < y1)
+                            || (y1 <= py && py < y2) )
+                        && (px < (x1 - x2)
+                                * (py - y2)
+                                    / (y1 - y2) + x2)
+                        )
+                            crosses = ! crosses
+                    */
+
+
+                    if (
+                        ((get<1, 1>(s) <= get<1>(state.p) && get<1>(state.p) < get<0, 1>(s))
+                            || (get<0, 1>(s) <= get<1>(state.p) && get<1>(state.p) < get<1, 1>(s)))
+                        && (get<0>(state.p) < (get<0, 0>(s) - get<1, 0>(s))
+                            * (get<1>(state.p) - get<1, 1>(s))
+                                    / (get<0, 1>(s) - get<1, 1>(s)) + get<1, 0>(s))
+                        )
+                    {
+                        state.crosses = ! state.crosses;
+                    }
+                    return true;
+                }
+        };
+
+
+
+    } // namespace within
+
+
+
+} // namespace strategy
+
+
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGY_CARTESIAN_WITHIN_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/distance_result.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/distance_result.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,265 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRY_STRATEGIES_DISTANCE_RESULT_HPP
+#define GGL_GEOMETRY_STRATEGIES_DISTANCE_RESULT_HPP
+
+#include <utility>
+#include <cmath>
+#include <limits>
+#include <iostream>
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+namespace ggl {
+
+/*!
+    \brief Encapsulate the results of distance calculation
+    \ingroup distance
+    \details Distance calculation for xy points or xyz points is done by taking the square
+    root. However, for distance comparison drawing the square root is not necessary.
+    Therefore the distance strategies are allowed to return the squares of the distance.
+    This structure contains the distance, and a boolean to indicate if it is squared.
+    It has an automatic conversion to a double value, which does the square root if necessary.
+    \note Thanks to Phil Endecott for his suggestion to change the pair to the double-convertable
+    http://article.gmane.org/gmane.comp.lib.boost.devel/172709/match=greatcircle_distance
+    \note It might be templatized with a T
+*/
+template<typename T = double>
+struct cartesian_distance
+{
+    private :
+        T m_squared_distance;
+
+        // Because result is square-rooted, for integer, the cast should
+        // go to double and NOT to T
+        typedef typename
+            boost::mpl::if_c
+            <
+                boost::is_integral<T>::type::value,
+                double,
+                T
+            >::type cast_type;
+
+
+
+
+    public :
+
+
+        /// Constructor with a value
+        explicit cartesian_distance(T const& v) : m_squared_distance(v) {}
+
+        /// Automatic conversion to double or higher precision,
+        /// taking squareroot if necessary
+        inline operator cast_type() const
+        {
+#if defined(NUMERIC_ADAPTOR_INCLUDED)
+            return boost::sqrt(m_squared_distance);
+#else
+            return std::sqrt((long double)m_squared_distance);
+#endif
+        }
+
+        // Compare squared values
+        inline bool operator<(cartesian_distance<T> const& other) const
+        {
+            return this->m_squared_distance < other.m_squared_distance;
+        }
+        inline bool operator>(cartesian_distance<T> const& other) const
+        {
+            return this->m_squared_distance > other.m_squared_distance;
+        }
+        inline bool operator==(cartesian_distance<T> const& other) const
+        {
+            return this->m_squared_distance == other.m_squared_distance;
+        }
+
+        // Compare just with a corresponding POD value
+        // Note: this is NOT possible because of the cast to double,
+        // it makes it for the compiler ambiguous which to take
+        /*
+        inline bool operator<(T const& value) const
+        {
+            return this->m_squared_distance < (value * value);
+        }
+        inline bool operator>(T const& value) const
+        {
+            return this->m_squared_distance > (value * value);
+        }
+        inline bool operator==(T const& value) const
+        {
+            return this->m_squared_distance == (value * value);
+        }
+        */
+
+        // Utility method to compare without SQRT, but not with method above because for epsilon that
+        // makes no sense...
+        inline bool very_small() const
+        {
+            return m_squared_distance <= std::numeric_limits<T>::epsilon();
+        }
+
+        /// The "squared_value" method returns the internal squared value
+        inline T squared_value() const
+        {
+            return m_squared_distance;
+        }
+
+        /// Make streamable to enable std::cout << ggl::distance( )
+        template <typename CH, typename TR>
+        inline friend std::basic_ostream<CH, TR>& operator<<(std::basic_ostream<CH, TR>& os,
+                        cartesian_distance<T> const& d)
+        {
+            // Avoid "ambiguous function call" for MSVC
+            cast_type const sq = d.m_squared_distance;
+
+            os <<
+#if defined(NUMERIC_ADAPTOR_INCLUDED)
+                boost::sqrt(sq);
+#else
+                std::sqrt(sq);
+#endif
+            return os;
+        }
+
+};
+
+
+
+/*
+
+    From Phil Endecott, on the list:
+
+    You can go further.  If I'm searching through a long list of points to
+    find the closest to P then I'll avoid the squaring (and conversion to
+    double if my co-ordinates are integers) whenever possible.  You can
+    achieve this with a more complex distance proxy:
+
+    class distance_proxy {
+       double dx;
+       double dy;
+       distance_proxy(double dx_, double dy_): dx(dx_), dy(dy_) {}
+       friend pythag_distance(point,point);
+    public:
+       operator double() { return sqrt(dx*dx+dy*dy); }
+       bool operator>(double d) {
+         return dx>d
+             || dy>d
+             || (dx*dx+dy*dy > d*d);
+       }
+    };
+
+    So this is convertible to double, but can be compared to a distance
+    without any need for sqrt() and only multiplication in some cases.
+    Further refinement is possible.
+
+
+    Barend:
+    feasable, needs to be templatized by the number of dimensions. For distance it
+    results in a nice "delayed calculation".
+    For searching you might take another approach, first calculate dx, if OK then dy,
+    if OK then the sqrs. So as above but than distance does not need to be calculated.
+    So it is in fact another strategy.
+
+
+*/
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+    namespace distance
+    {
+        template <typename R, typename T>
+        struct distance_result_maker
+        {
+        };
+
+        template <typename R, typename T>
+        struct distance_result_maker<ggl::cartesian_distance<R>, T>
+        {
+            static inline ggl::cartesian_distance<R> apply(T const& value)
+            {
+                return cartesian_distance<R>(value * value);
+            }
+        };
+
+        template <typename T>
+        struct distance_result_maker<double, T>
+        {
+            static inline double apply(T const& value)
+            {
+                return value;
+            }
+        };
+
+
+        template <typename T>
+        struct close_to_zero
+        {
+            static inline bool apply(T const& value)
+            {
+                return value <= std::numeric_limits<T>::epsilon();
+            }
+        };
+
+
+        template <typename T>
+        struct close_to_zero<ggl::cartesian_distance<T> >
+        {
+            static inline bool apply(ggl::cartesian_distance<T> const& value)
+            {
+                return value.very_small();
+            }
+        };
+
+
+    }
+}
+#endif
+
+
+/*!
+    \brief Object generator to create instance which can be compared
+    \ingroup distance
+    \details If distance results have to be compared to a certain value it makes sense to use
+    this function to generate a distance result of a certain value, and compare the distance
+    result with this instance. SQRT calculations are then avoided
+    \tparam R distance result type
+    \tparam T arithmetic type, e.g. double
+    \param value the distance to compare with
+    \return the distance result
+*/
+template <typename R, typename T>
+inline R make_distance_result(T const& value)
+{
+    return detail::distance::distance_result_maker<R, T>::apply(value);
+}
+
+
+/*!
+    \brief Utility function to check if a distance is very small
+    \ingroup distance
+    \details Depending on the "distance result" type it checks if it is smaller than epsilon,
+    or (for Cartesian distances) if the square is smaller than epsilon
+    \tparam R the distance result type, either arithmetic or cartesian distance
+    \param value the distance result to check
+*/
+template <typename T>
+inline bool close_to_zero(T const& value)
+{
+    return detail::distance::close_to_zero<T>::apply(value);
+}
+
+} // namespace ggl
+
+
+#endif // GGL_GEOMETRY_STRATEGIES_DISTANCE_RESULT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/intersection_result.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/intersection_result.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,167 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_INTERSECTION_RESULT_HPP
+#define GGL_INTERSECTION_RESULT_HPP
+
+#if defined(HAVE_MATRIX_AS_STRING)
+#include <string>
+#endif
+
+namespace ggl
+{
+
+/*!
+    \brief Dimensionally Extended 9 Intersection Matrix
+    \details
+    \ingroup overlay
+    \see http://gis.hsr.ch/wiki/images/3/3d/9dem_springer.pdf
+*/
+struct de9im
+{
+    int ii, ib, ie,
+        bi, bb, be,
+        ei, eb, ee;
+
+    inline de9im()
+        : ii(-1), ib(-1), ie(-1)
+        , bi(-1), bb(-1), be(-1)
+        , ei(-1), eb(-1), ee(-1)
+    {
+    }
+
+    inline de9im(int ii0, int ib0, int ie0,
+        int bi0, int bb0, int be0,
+        int ei0, int eb0, int ee0)
+        : ii(ii0), ib(ib0), ie(ie0)
+        , bi(bi0), bb(bb0), be(be0)
+        , ei(ei0), eb(eb0), ee(ee0)
+    {}
+
+    inline bool equals() const
+    {
+        return ii >= 0 && ie < 0 && be < 0 && ei < 0 && eb < 0;
+    }
+
+    inline bool disjoint() const
+    {
+        return ii < 0 && ib < 0 && bi < 0 && bb < 0;
+    }
+
+    inline bool intersects() const
+    {
+        return ii >= 0 || bb >= 0 || bi >= 0 || ib >= 0;
+    }
+
+    inline bool touches() const
+    {
+        return ii < 0 && (bb >= 0 || bi >= 0 || ib >= 0);
+    }
+
+    inline bool crosses() const
+    {
+        return (ii >= 0 && ie >= 0) || (ii == 0);
+    }
+
+    inline bool overlaps() const
+    {
+        return ii >= 0 && ie >= 0 && ei >= 0;
+    }
+
+    inline bool within() const
+    {
+        return ii >= 0 && ie < 0 && be < 0;
+    }
+
+    inline bool contains() const
+    {
+        return ii >= 0 && ei < 0 && eb < 0;
+    }
+
+
+    static inline char as_char(int v)
+    {
+        return v >= 0 && v < 10 ? ('0' + char(v)) : '-';
+    }
+
+#if defined(HAVE_MATRIX_AS_STRING)
+    inline std::string matrix_as_string(std::string const& tab, std::string const& nl) const
+    {
+        std::string ret;
+        ret.reserve(9 + tab.length() * 3 + nl.length() * 3);
+        ret += tab; ret += as_char(ii); ret += as_char(ib); ret += as_char(ie); ret += nl;
+        ret += tab; ret += as_char(bi); ret += as_char(bb); ret += as_char(be); ret += nl;
+        ret += tab; ret += as_char(ei); ret += as_char(eb); ret += as_char(ee);
+        return ret;
+    }
+
+    inline std::string matrix_as_string() const
+    {
+        return matrix_as_string("", "");
+    }
+#endif
+
+};
+
+struct de9im_segment : public de9im
+{
+    bool collinear; // true if segments are aligned (for equal,overlap,touch)
+    bool opposite; // true if direction is reversed (for equal,overlap,touch)
+    bool parallel;  // true if disjoint but parallel
+    bool degenerate; // true for segment(s) of zero length
+
+    double ra, rb; // temp
+
+    inline de9im_segment()
+        : de9im()
+        , collinear(false)
+        , opposite(false)
+        , parallel(false)
+        , degenerate(false)
+    {}
+
+    inline de9im_segment(double a, double b,
+        int ii0, int ib0, int ie0,
+        int bi0, int bb0, int be0,
+        int ei0, int eb0, int ee0,
+        bool c = false, bool o = false, bool p = false, bool d = false)
+        : de9im(ii0, ib0, ie0, bi0, bb0, be0, ei0, eb0, ee0)
+        , collinear(c)
+        , opposite(o)
+        , parallel(p)
+        , degenerate(d)
+        , ra(a), rb(b)
+    {}
+
+
+#if defined(HAVE_MATRIX_AS_STRING)
+    inline std::string as_string() const
+    {
+        std::string ret = matrix_as_string();
+        ret += collinear ? "c" : "-";
+        ret += opposite ? "o" : "-";
+        return ret;
+    }
+#endif
+};
+
+template <typename P>
+struct segment_intersection_points
+{
+    int count;
+    P intersections[2];
+
+    segment_intersection_points()
+        : count(0)
+    {}
+};
+
+} // namespace ggl
+
+
+#endif // GGL_INTERSECTION_RESULT_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/haversine.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/haversine.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,257 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGY_SPHERICAL_DISTANCE_HPP
+#define GGL_STRATEGY_SPHERICAL_DISTANCE_HPP
+
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/core/access.hpp>
+#include <ggl/core/radian_access.hpp>
+
+
+#include <ggl/strategies/strategy_traits.hpp>
+
+#include <ggl/strategies/distance_result.hpp>
+
+#include <ggl/util/get_cs_as_radian.hpp>
+
+
+
+namespace ggl
+{
+namespace strategy
+{
+
+    namespace distance
+    {
+
+        /*!
+            \brief Distance calculation for spherical coordinates on a perfect sphere using haversine
+            \ingroup distance
+            \tparam P1 first point type
+            \tparam P2 optional second point type
+            \author Adapted from: http://williams.best.vwh.net/avform.htm
+            \see http://en.wikipedia.org/wiki/Great-circle_distance
+            \note It says: <em>The great circle distance d between two points with coordinates {lat1,lon1} and {lat2,lon2} is given by:
+                        d=acos(sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos(lon1-lon2))
+                    A mathematically equivalent formula, which is less subject to rounding error for short distances is:
+                        d=2*asin(sqrt((sin((lat1-lat2)/2))^2 + cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))</em>
+        */
+        template <typename P1, typename P2 = P1>
+        class haversine
+        {
+            public :
+                //typedef spherical_distance return_type;
+                typedef double return_type;
+
+                inline haversine(double r = constants::average_earth_radius)
+                    : m_radius(r)
+                {}
+
+                inline return_type operator()(const P1& p1, const P2& p2) const
+                {
+                    return calc(get_as_radian<0>(p1), get_as_radian<1>(p1),
+                                    get_as_radian<0>(p2), get_as_radian<1>(p2));
+                }
+
+            private :
+                double m_radius;
+                typedef typename coordinate_type<P1>::type T1;
+                typedef typename coordinate_type<P2>::type T2;
+
+                inline return_type calc(const T1& lon1, const T1& lat1, const T2& lon2, const T2& lat2) const
+                {
+                    double a = math::hav(lat2 - lat1) + cos(lat1) * cos(lat2) * math::hav(lon2 - lon1);
+                    double c = 2.0 * asin(sqrt(a));
+                    return return_type(m_radius * c);
+                }
+        };
+
+
+
+        /*!
+            \brief Strategy functor for distance point to segment calculation
+            \ingroup distance
+            \details Class which calculates the distance of a point to a segment, using latlong points
+            \tparam P point type
+            \tparam S segment type
+        */
+        template <typename P, typename S>
+        class ll_point_segment
+        {
+            public :
+                typedef double return_type;
+
+                inline ll_point_segment(double r = constants::average_earth_radius) : m_radius(r)
+                {}
+
+                inline return_type operator()(P const& p, S const& s) const
+                {
+                    PR pr, ps1, ps2;
+
+                    // Select transformation strategy and transform to radians (if necessary)
+                    typename strategy_transform<
+                                typename cs_tag<P>::type,
+                                typename cs_tag<PR>::type,
+                                typename coordinate_system<P>::type,
+                                typename coordinate_system<PR>::type,
+                                dimension<P>::value,
+                                dimension<PR>::value,
+                                P, PR>::type transform_strategy;
+
+
+                    // TODO
+                    // ASSUMPTION: segment
+                    // SOLVE THIS USING OTHER FUNCTIONS using get<,>
+                    transform_strategy(p, pr);
+                    transform_strategy(s.first, ps1);
+                    transform_strategy(s.second, ps2);
+                    return calc(pr, ps1, ps2);
+                }
+
+            private :
+                typedef point
+                    <
+                        typename coordinate_type<P>::type,
+                        ggl::dimension<P>::type::value,
+                        typename ggl::detail::get_cs_as_radian
+                            <
+                                typename coordinate_system<P>::type
+                            >::type
+                    > PR;
+                double m_radius;
+
+                /// Calculate course (bearing) between two points. Might be moved to a "course formula" ...
+                inline double course(PR const& p1, PR const& p2) const
+                {
+                    /***
+                        Course between points
+
+                        We obtain the initial course, tc1, (at point 1) from point 1 to point 2 by the following. The formula fails if the initial point is a pole. We can special case this with:
+
+                        IF (cos(lat1) < EPS)   // EPS a small number ~ machine precision
+                          IF (lat1 > 0): tc1= pi        //  starting from N pole
+                          ELSE: tc1= 2*pi         //  starting from S pole
+                          ENDIF
+                        ENDIF
+
+                        For starting points other than the poles:
+                        IF sin(lon2-lon1)<0: tc1=acos((sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1)))
+                        ELSE: tc1=2*pi-acos((sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1)))
+                        ENDIF
+
+                        An alternative formula, not requiring the pre-computation of d, the distance between the points, is:
+                           tc1=mod(atan2(sin(lon1-lon2)*cos(lat2),
+                                   cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon1-lon2))
+                                   , 2*pi)
+                     ***/
+                    double dlon = get<0>(p2) - get<0>(p1);
+                    double cos_p2lat = cos(get<1>(p2));
+                    return atan2(sin(dlon) * cos_p2lat,
+                        cos(get<1>(p1)) * sin(get<1>(p2))
+                        - sin(get<1>(p1)) * cos_p2lat * cos(dlon));
+                }
+
+                inline return_type calc(PR const& p, PR const& sp1, PR const& sp2) const
+                {
+                    /***
+                    Cross track error:
+                    Suppose you are proceeding on a great circle route from A to B (course =crs_AB) and end up at D, perhaps off course.
+                    (We presume that A is ot a pole!) You can calculate the course from A to D (crs_AD) and the distance from A to D (dist_AD)
+                    using the formulae above. In shifteds of these the cross track error, XTD, (distance off course) is given by
+
+                               XTD =asin(sin(dist_AD)*sin(crs_AD-crs_AB))
+
+                    (positive XTD means right of course, negative means left)
+                    (If the point A is the N. or S. Pole replace crs_AD-crs_AB with
+                    lon_D-lon_B or lon_B-lon_D, respectively.)
+                     ***/
+
+                    // Calculate distances, in radians, on the unit sphere
+                    // It seems not useful to let this strategy be templatized, it should be in radians and on the unit sphere
+                    strategy::distance::haversine<PR, PR> strategy(1.0);
+                    double d1 = strategy(sp1, p);
+
+                    // Actually, calculation of d2 not necessary if we know that the projected point is on the great circle...
+                    double d2 = strategy(sp2, p);
+
+                    // Source: http://williams.best.vwh.net/avform.htm
+
+                    double crs_AD = course(sp1, p);
+                    double crs_AB = course(sp1, sp2);
+                    double XTD = fabs(asin(sin(d1) * sin(crs_AD - crs_AB)));
+
+                    // Return shortest distance, either to projected point on segment sp1-sp2, or to sp1, or to sp2
+                    return return_type(m_radius * (std::min)((std::min)(d1, d2), XTD));
+                }
+        };
+
+
+
+
+
+    } // namespace distance
+
+
+
+
+} // namespace strategy
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <typename P1, typename P2>
+struct strategy_distance<spherical_tag, spherical_tag, P1, P2>
+{
+    typedef strategy::distance::haversine<P1, P2> type;
+};
+
+
+template <typename Point, typename Segment>
+struct strategy_distance_segment<spherical_tag, spherical_tag, Point, Segment>
+{
+    typedef strategy::distance::ll_point_segment<Point, Segment> type;
+};
+
+
+// Use this point-segment for geographic as well. TODO: change this, extension!
+template <typename Point, typename Segment>
+struct strategy_distance_segment<geographic_tag, geographic_tag, Point, Segment>
+{
+    typedef strategy::distance::ll_point_segment<Point, Segment> type;
+};
+
+
+
+
+template <typename P1, typename P2>
+struct strategy_tag<strategy::distance::haversine<P1, P2> >
+{
+    typedef strategy_tag_distance_point_point type;
+};
+
+template <typename Point, typename Segment>
+struct strategy_tag<strategy::distance::ll_point_segment<Point, Segment> >
+{
+    typedef strategy_tag_distance_point_segment type;
+};
+
+
+
+#endif
+
+
+
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGY_SPHERICAL_DISTANCE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/sph_area.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/sph_area.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,167 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRY_STRATEGIES_SPHERICAL_SPH_AREA_HPP
+#define GGL_GEOMETRY_STRATEGIES_SPHERICAL_SPH_AREA_HPP
+
+#include <ggl/geometries/segment.hpp>
+#include <ggl/strategies/spherical/haversine.hpp>
+#include <ggl/strategies/strategy_transform.hpp>
+
+#include <ggl/util/get_cs_as_radian.hpp>
+
+namespace ggl
+{
+namespace strategy
+{
+    namespace area
+    {
+
+
+
+        /*!
+            \brief Area calculation by spherical excess
+            \tparam P type of points of rings/polygons
+            \author Barend Gehrels. Adapted from:
+            - http://www.soe.ucsc.edu/~pang/160/f98/Gems/GemsIV/sph_poly.c
+            - http://williams.best.vwh.net/avform.htm
+            \note The version in Gems didn't account for polygons crossing the 180 meridian.
+            \note This version works for convex and non-convex polygons, for 180 meridian
+            crossing polygons and for polygons with holes. However, some cases (especially
+            180 meridian cases) must still be checked.
+            \note The version which sums angles, which is often seen, doesn't handle non-convex
+            polygons correctly.
+            \note The version which sums longitudes, see
+            http://trs-new.jpl.nasa.gov/dspace/bitstream/2014/40409/1/07-03.pdf, is simple
+            and works well in most cases but not in 180 meridian crossing cases. This probably
+            could be solved.
+        */
+        template<typename P>
+        class by_spherical_excess
+        {
+            private :
+                struct excess_sum
+                {
+                    double m_sum;
+                    double m_radius;
+
+                    // TODO: make this 1.0 & implement other construct to let user specify
+                    inline excess_sum(double radius = constants::average_earth_radius)
+                        : m_sum(0)
+                        , m_radius(radius)
+                    {}
+                    inline double area() const
+                    {
+                        return - m_sum * m_radius * m_radius;
+                            //constants::average_earth_radius * constants::average_earth_radius;
+                    }
+                };
+
+                // Distances are calculated on unit sphere here
+                strategy::distance::haversine<P, P> m_unit_sphere;
+                double m_radius;
+
+            public :
+                typedef double return_type;
+                typedef excess_sum state_type;
+
+                by_spherical_excess(double radius = 1.0)
+                    : m_unit_sphere(1)
+                    , m_radius(radius)
+                {}
+
+                inline bool operator()(segment<const P> const& segment, state_type& state) const
+                {
+                    if (get<0>(segment.first) != get<0>(segment.second))
+                    {
+                        typedef point
+                            <
+                                typename coordinate_type<P>::type,
+                                2,
+                                typename ggl::detail::get_cs_as_radian
+                                    <
+                                        typename coordinate_system<P>::type
+                                    >::type
+                            > PR;
+                        PR p1, p2;
+
+                        // Select transformation strategy and transform to radians (if necessary)
+                        typename strategy_transform<
+                                    typename cs_tag<P>::type,
+                                    typename cs_tag<PR>::type,
+                                    typename coordinate_system<P>::type,
+                                    typename coordinate_system<PR>::type,
+                                    dimension<P>::value,
+                                    dimension<PR>::value,
+                                    P, PR>::type transform_strategy;
+
+                        transform_strategy(segment.first, p1);
+                        transform_strategy(segment.second, p2);
+
+                        // Distance p1 p2
+                        double a = m_unit_sphere(segment.first, segment.second);
+                        // Sides on unit sphere to south pole
+                        double b = 0.5 * math::pi - ggl::get<1>(p2);
+                        double c = 0.5 * math::pi - ggl::get<1>(p1);
+                        // Semi parameter
+                        double s = 0.5 * (a + b + c);
+
+                        // E: spherical excess, using l'Huiller's formula
+                        // [tg(e / 4)]2   =   tg[s / 2]  tg[(s-a) / 2]  tg[(s-b) / 2]  tg[(s-c) / 2]
+                        double E = 4.0 * atan(sqrt(fabs(tan(s / 2)
+                                * tan((s - a) / 2)
+                                * tan((s - b) / 2)
+                                * tan((s - c) / 2))));
+
+                        E = fabs(E);
+
+                        // In right direction: positive, add area. In left direction: negative, subtract area.
+                        // Longitude comparisons are not so obvious. If one is negative, other is positive,
+                        // we have to take the date into account.
+                        // TODO: check this / enhance this, should be more robust. See also the "grow" for ll
+                        // TODO: use minmax or "smaller"/"compare" strategy for this
+                        double lon1 = ggl::get<0>(p1) < 0
+                            ? ggl::get<0>(p1) + math::two_pi
+                            : ggl::get<0>(p1);
+                        double lon2 = ggl::get<0>(p2) < 0
+                            ? ggl::get<0>(p2) + math::two_pi
+                            : ggl::get<0>(p2);
+
+                        if (lon2 < lon1)
+                        {
+                            E= -E;
+                        }
+
+                        state.m_sum += E;
+                    }
+                    return true;
+                }
+        };
+
+    } // namespace area
+
+} // namespace strategy
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <typename LL>
+struct strategy_area<spherical_tag, LL>
+{
+    typedef strategy::area::by_spherical_excess<LL> type;
+};
+
+template <typename LL>
+struct strategy_area<geographic_tag, LL>
+{
+    typedef strategy::area::by_spherical_excess<LL> type;
+};
+#endif
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRY_STRATEGIES_SPHERICAL_SPH_AREA_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/sph_envelope.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/spherical/sph_envelope.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,176 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRY_STRATEGIES_SPHERICAL_SPH_ENVELOPE_HPP
+#define GGL_GEOMETRY_STRATEGIES_SPHERICAL_SPH_ENVELOPE_HPP
+
+#include <boost/numeric/conversion/bounds.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+// NOTE: maybe evaluate/rework this using new "compare" strategy
+// - implement "compare" for latlong (e.g. return true if distance-difference < 90 deg, so 170 < -170 but 90 > -180)
+
+#include <ggl/strategies/spherical/haversine.hpp>
+
+namespace ggl
+{
+namespace strategy
+{
+    namespace envelope
+    {
+        // envelope calculation strategy for latlong-points
+        namespace shift
+        {
+            template <typename D>
+            struct shifted
+            {
+            };
+
+            template<>
+            struct shifted<radian>
+            {
+                inline static double shift() { return math::two_pi; }
+            };
+            template<>
+            struct shifted<degree>
+            {
+                inline static double shift() { return 360.0; }
+            };
+
+        }
+
+        /*!
+            \par Algorithm:
+            The envelope of latlong-points cannot be implemented as for xy-points. Suppose the
+            envelope of the Aleutian Islands must be calculated. The span from 170E to 170W, from -170 to 170.
+            Of course the real envelope is not -170..170 but 170..-170.
+            On the other hand, there might be geometries that indeed span from -170 to 170. If there are
+            two points, it is not known. If there are points in between, we probably should take the shorter
+            range. So we do that for the moment.
+            We shift coordinates and do as if we live in a world with longitude coordinates from 0 - 360,
+            where 0 is still at Greenwich. Longitude ranges are then calculated twice: one for real world,
+            one for the shifted world.
+            The shortest range is taken for the bounding box. This might have coordinates > 180
+        */
+
+        template <typename P, typename B>
+        struct grow_ll
+        {
+
+            struct state
+            {
+                typedef typename coordinate_type<B>::type T;
+                bool has_west;
+                T min_lat, max_lat;
+                T min_lon1, min_lon2, max_lon1, max_lon2;
+                B& mbr;
+
+                state(B& b)
+                    : mbr(b)
+                    , has_west(false)
+                    , min_lat(boost::numeric::bounds<T>::highest())
+                    , min_lon1(boost::numeric::bounds<T>::highest())
+                    , min_lon2(boost::numeric::bounds<T>::highest())
+                    , max_lat(boost::numeric::bounds<T>::lowest())
+                    , max_lon1(boost::numeric::bounds<T>::lowest())
+                    , max_lon2(boost::numeric::bounds<T>::lowest())
+                {}
+
+                template <typename T>
+                void take_minmax(const T& value, T& min_value, T& max_value)
+                {
+                    if (value < min_value)
+                    {
+                        min_value = value;
+                    }
+                    if (value > max_value)
+                    {
+                        max_value = value;
+                    }
+                }
+
+                void grow(const P& p)
+                {
+                    // For latitude, we can take the min/max
+                    take_minmax(get<1>(p), min_lat, max_lat);
+
+
+                    // For longitude, we do the same...
+                    take_minmax(get<0>(p), min_lon1, max_lon1);
+
+                    // But we also add 360 (2pi) if it is negative
+                    T value = get<0>(p);
+                    while(value < 0)
+                    {
+                        has_west = true;
+                        value += shift::shifted<typename coordinate_system<P>::type::units>::shift();
+                    }
+                    while (value > math::two_pi)
+                    {
+                        value -= shift::shifted<typename coordinate_system<P>::type::units>::shift();
+                    }
+                    take_minmax(value, min_lon2, max_lon2);
+                }
+
+                ~state()
+                //void envelope(box<PB>& mbr)
+                {
+                    // For latitude it is easy
+                    set<min_corner, 1>(mbr, min_lat);
+                    set<max_corner, 1>(mbr, max_lat);
+
+                    if (! has_west)
+                    {
+                        set<min_corner, 0>(mbr, min_lon1);
+                        set<max_corner, 0>(mbr, max_lon1);
+                    }
+                    else
+                    {
+                        // Get both ranges
+                        T diff1 = max_lon1 - min_lon1;
+                        T diff2 = max_lon2 - min_lon2;
+
+                        //std::cout << "range 1: " << min_lon1 * math::r2d << ".." << max_lon1 * math::r2d << std::endl;
+                        //std::cout << "range 2: " << min_lon2 * math::r2d << ".." << max_lon2 * math::r2d << std::endl;
+
+                        if (diff1 <= diff2)
+                        {
+                            set<min_corner, 0>(mbr, min_lon1);
+                            set<max_corner, 0>(mbr, max_lon1);
+                        }
+                        else
+                        {
+                            set<min_corner, 0>(mbr, min_lon2);
+                            set<max_corner, 0>(mbr, max_lon2);
+                        }
+                    }
+                }
+            };
+
+            typedef state state_type;
+
+            void operator()(const P& p, state_type& s) const
+            {
+                s.grow(p);
+            }
+        };
+    } // namespace envelope
+} // namespace strategy
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <typename P, typename B>
+struct strategy_envelope<geographic_tag, geographic_tag, P, B>
+{
+    typedef strategy::envelope::grow_ll<P, B>  type;
+};
+#endif
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRY_STRATEGIES_SPHERICAL_SPH_ENVELOPE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/strategies.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/strategies.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,38 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_HPP
+#define GGL_STRATEGIES_HPP
+
+
+#include <ggl/strategies/strategy_traits.hpp>
+
+#include <ggl/strategies/cartesian/cart_area.hpp>
+#include <ggl/strategies/cartesian/cart_centroid.hpp>
+#include <ggl/strategies/cartesian/cart_compare.hpp>
+#include <ggl/strategies/cartesian/cart_distance.hpp>
+#include <ggl/strategies/cartesian/cart_envelope.hpp>
+#include <ggl/strategies/cartesian/cart_side.hpp>
+#include <ggl/strategies/cartesian/cart_within.hpp>
+
+#include <ggl/strategies/spherical/sph_area.hpp>
+#include <ggl/strategies/spherical/haversine.hpp>
+#include <ggl/strategies/spherical/sph_envelope.hpp>
+
+#include <ggl/strategies/agnostic/agn_convex_hull.hpp>
+#include <ggl/strategies/agnostic/agn_simplify.hpp>
+#include <ggl/strategies/agnostic/agn_within.hpp>
+
+#include <ggl/strategies/strategy_transform.hpp>
+
+#include <ggl/strategies/transform/matrix_transformers.hpp>
+#include <ggl/strategies/transform/map_transformer.hpp>
+#include <ggl/strategies/transform/inverse_transformer.hpp>
+
+
+#endif // GGL_STRATEGIES_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/strategy_traits.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/strategy_traits.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,231 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_STRATEGY_TRAITS_HPP
+#define GGL_STRATEGIES_STRATEGY_TRAITS_HPP
+
+#include <ggl/core/cs.hpp>
+#include <ggl/strategies/distance_result.hpp>
+
+// File containing strategy traits classes, to be specialized in other files
+// (This file might be splitted resulting into several small files)
+
+namespace ggl
+{
+
+namespace strategy
+{
+    /*!
+        \brief Indicate compiler/library user that strategy is not implemented.
+        \details The strategy_traits class define strategies for point types or for point type
+        combinations. If there is no implementation for that specific point type, or point type
+        combination, the calculation cannot be done. To indicate this, this not_implemented
+        class is used as a typedef stub.
+
+    */
+    struct not_implemented {};
+}
+
+
+/*!
+    \brief Traits class binding an area strategy to a coordinate system
+    \ingroup area
+    \tparam T tag of coordinate system
+    \tparam P point-type
+*/
+template <typename T, typename P>
+struct strategy_area
+{
+    typedef strategy::not_implemented type;
+};
+
+/*!
+    \brief Traits class binding a distance strategy to a (possibly two) coordinate system(s)
+    \ingroup distance
+    \tparam T1 tag of coordinate system of first point type
+    \tparam T2 tag of coordinate system of second point type
+    \tparam P1 first point-type
+    \tparam P2 second point-type
+*/
+template <typename T1, typename T2, typename P1, typename P2>
+struct strategy_distance
+{
+    typedef strategy::not_implemented type;
+};
+
+/*!
+    \brief Traits class binding a distance-to-segment strategy to a (possibly two) coordinate system(s)
+    \ingroup distance
+    \tparam CsTag1 tag of coordinate system of point type
+    \tparam CsTag2 tag of coordinate system of segment type, usually same as CsTag1
+    \tparam Point point-type
+    \tparam Segment segment-type
+*/
+template <typename CsTag1, typename CsTag2, typename Point, typename Segment>
+struct strategy_distance_segment
+{
+    typedef strategy::not_implemented type;
+};
+
+
+/*!
+    \brief Traits class binding a centroid calculation strategy to a coordinate system
+    \ingroup centroid
+    \tparam T tag of coordinate system
+    \tparam P point-type
+    \tparam PS segment point-type
+*/
+template <typename T, typename P, typename PS>
+struct strategy_centroid
+{
+    typedef strategy::not_implemented type;
+};
+
+
+/*!
+    \brief Traits class binding envelope strategy to a coordinate system
+    \ingroup envelope
+    \tparam TP tag of coordinate system of point
+    \tparam TB tag of coordinate system of box, usually same as TP
+    \tparam P point-type
+    \tparam B box-type
+*/
+template <typename TP, typename TB, typename P, typename B>
+struct strategy_envelope
+{
+    typedef strategy::not_implemented type;
+};
+
+
+/*!
+    \brief Traits class binding a convex hull calculation strategy to a coordinate system
+    \ingroup convex_hull
+    \tparam T tag of coordinate system
+    \tparam P point-type of input points
+*/
+template <typename T, typename P>
+struct strategy_convex_hull
+{
+    typedef strategy::not_implemented type;
+};
+
+
+/*!
+    \brief Traits class binding a within determination strategy to a coordinate system
+    \ingroup within
+    \tparam TP tag of coordinate system of point-type
+    \tparam TS tag of coordinate system of segment-type
+    \tparam P point-type of input points
+    \tparam PS point-type of input segment-points
+*/
+template <typename TP, typename TS, typename P, typename PS>
+struct strategy_within
+{
+    typedef strategy::not_implemented type;
+};
+
+
+/*!
+    \brief Traits class binding a side determination strategy to a coordinate system
+    \ingroup util
+    \tparam T tag of coordinate system of point-type
+    \tparam P point-type of input points
+    \tparam PS point-type of input points
+*/
+template <typename T, typename P, typename PS = P>
+struct strategy_side
+{
+    typedef strategy::not_implemented type;
+};
+
+
+
+/*!
+    \brief Traits class binding a comparing strategy to a coordinate system
+    \ingroup util
+    \tparam T tag of coordinate system of point-type
+    \tparam P point-type
+    \tparam D dimension to compare
+*/
+template <typename T, typename P, size_t D>
+struct strategy_compare
+{
+    typedef strategy::not_implemented type;
+};
+
+
+/*!
+    \brief Traits class binding a transformation strategy to a coordinate system
+    \ingroup transform
+    \details Can be specialized
+    - per coordinate system family (tag)
+    - per coordinate system (or groups of them)
+    - per dimension
+    - per point type
+    \tparam CS_TAG 1,2 coordinate system tags
+    \tparam CS 1,2 coordinate system
+    \tparam D 1, 2 dimension
+    \tparam P 1, 2 point type
+ */
+template <typename CS_TAG1, typename CS_TAG2,
+            typename CS1, typename CS2,
+            size_t D1, size_t D2,
+            typename P1, typename P2>
+struct strategy_transform
+{
+    typedef strategy::not_implemented type;
+};
+
+
+/*!
+    \brief Traits class binding a parsing strategy to a coordinate system
+    \ingroup parse
+    \tparam T tag of coordinate system of point-type
+    \tparam CS coordinate system
+*/
+template <typename T, typename CS>
+struct strategy_parse
+{
+    typedef strategy::not_implemented type;
+};
+
+
+
+
+/*!
+    \brief Shortcut to define return type of distance strategy
+    \ingroup distance
+    \tparam G1 first geometry
+    \tparam G2 second geometry
+ */
+template <typename G1, typename G2 = G1>
+struct distance_result
+{
+    typedef typename point_type<G1>::type P1;
+    typedef typename point_type<G2>::type P2;
+    typedef typename strategy_distance<
+                typename cs_tag<P1>::type,
+                typename cs_tag<P2>::type, P1, P2>::type S;
+    typedef typename S::return_type type;
+};
+
+
+
+struct strategy_tag_unknown {};
+struct strategy_tag_distance_point_point {};
+struct strategy_tag_distance_point_segment {};
+
+template <typename T>
+struct strategy_tag
+{
+    typedef strategy_tag_unknown type;
+};
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_STRATEGY_TRAITS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/strategy_transform.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/strategy_transform.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,358 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGY_TRANSFORM_HPP
+#define GGL_STRATEGY_TRANSFORM_HPP
+
+#include <cstddef>
+#include <cmath>
+#include <functional>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <ggl/arithmetic/arithmetic.hpp>
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/util/copy.hpp>
+#include <ggl/util/math.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+
+namespace ggl
+{
+
+namespace strategy { namespace transform {
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template
+<
+    typename Src, typename Dst,
+    std::size_t D, std::size_t N,
+    template <typename> class F
+>
+struct transform_coordinates
+{
+    static inline void transform(const Src& source, Dst& dest, double value)
+    {
+        typedef typename select_coordinate_type<Src, Dst>::type coordinate_type;
+
+        F<coordinate_type> function;
+        set<D>(dest, boost::numeric_cast<coordinate_type>(function(get<D>(source), value)));
+        transform_coordinates<Src, Dst, D + 1, N, F>::transform(source, dest, value);
+    }
+};
+
+template
+<
+    typename Src, typename Dst,
+    std::size_t N,
+    template <typename> class F
+>
+struct transform_coordinates<Src, Dst, N, N, F>
+{
+    static inline void transform(const Src& source, Dst& dest, double value)
+    {
+    }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief Transformation strategy to copy one point to another using assignment operator
+    \ingroup transform
+    \tparam P point type
+ */
+template <typename P>
+struct copy_direct
+{
+    inline bool operator()(const P& p1, P& p2) const
+    {
+        p2 = p1;
+        return true;
+    }
+};
+
+/*!
+    \brief Transformation strategy to do copy a point, copying per coordinate.
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+ */
+template <typename P1, typename P2>
+struct copy_per_coordinate
+{
+    inline bool operator()(P1 const& p1, P2& p2) const
+    {
+        // Defensive check, dimensions are equal, selected by specialization
+        assert_dimension_equal<P1, P2>();
+
+        copy_coordinates(p1, p2);
+        return true;
+    }
+};
+
+
+/*!
+    \brief Transformation strategy to go from degree to radian and back
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+    \tparam F additional functor to divide or multiply with d2r
+ */
+template <typename P1, typename P2, template <typename> class F>
+struct degree_radian_vv
+{
+    inline bool operator()(P1 const& p1, P2& p2) const
+    {
+        // Spherical coordinates always have 2 coordinates measured in angles
+        // The optional third one is distance/height, provided in another strategy
+        // Polar coordinates having one angle, will be also in another strategy
+        assert_dimension<P1, 2>();
+        assert_dimension<P2, 2>();
+
+        detail::transform_coordinates<P1, P2, 0, 2, F>::transform(p1, p2, math::d2r);
+        return true;
+    }
+};
+
+template <typename P1, typename P2, template <typename> class F>
+struct degree_radian_vv_3
+{
+    inline bool operator()(P1 const& p1, P2& p2) const
+    {
+        assert_dimension<P1, 3>();
+        assert_dimension<P2, 3>();
+
+        detail::transform_coordinates<P1, P2, 0, 2, F>::transform(p1, p2, math::d2r);
+        // Copy height or other third dimension
+        set<2>(p2, get<2>(p1));
+        return true;
+    }
+};
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+    /// Helper function for conversion, phi/theta are in radians
+    template <typename P>
+    inline void spherical_to_cartesian(double phi, double theta, double r, P& p)
+    {
+        assert_dimension<P, 3>();
+
+        // http://en.wikipedia.org/wiki/List_of_canonical_coordinate_transformations#From_spherical_coordinates
+        // Phi = first, theta is second, r is third, see documentation on cs::spherical
+        double const sin_theta = std::sin(theta);
+        set<0>(p, r * sin_theta * std::cos(phi));
+        set<1>(p, r * sin_theta * std::sin(phi));
+        set<2>(p, r * std::cos(theta));
+    }
+
+    /// Helper function for conversion
+    template <typename P>
+    inline bool cartesian_to_spherical2(double x, double y, double z, P& p)
+    {
+        assert_dimension<P, 2>();
+
+        // http://en.wikipedia.org/wiki/List_of_canonical_coordinate_transformations#From_Cartesian_coordinates
+
+        // TODO: MAYBE ONLY IF TO BE CHECKED?
+        double const r = std::sqrt(x * x + y * y + z * z);
+
+        // Unit sphere, r should be 1
+        typedef typename coordinate_type<P>::type coordinate_type;
+        if (std::abs(r - 1.0) > std::numeric_limits<coordinate_type>::epsilon())
+        {
+            return false;
+        }
+        // end todo
+
+        set_from_radian<0>(p, std::atan2(y, x));
+        set_from_radian<1>(p, std::acos(z));
+        return true;
+    }
+
+    template <typename P>
+    inline bool cartesian_to_spherical3(double x, double y, double z, P& p)
+    {
+        assert_dimension<P, 3>();
+
+        // http://en.wikipedia.org/wiki/List_of_canonical_coordinate_transformations#From_Cartesian_coordinates
+        double const r = std::sqrt(x * x + y * y + z * z);
+        set<2>(p, r);
+        set_from_radian<0>(p, std::atan2(y, x));
+        if (r > 0.0)
+        {
+            set_from_radian<1>(p, std::acos(z / r));
+            return true;
+        }
+        return false;
+    }
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief Transformation strategy for 2D spherical (phi,theta) to 3D cartesian (x,y,z)
+    \details on Unit sphere
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+ */
+template <typename P1, typename P2>
+struct from_spherical_2_to_cartesian_3
+{
+    inline bool operator()(P1 const& p1, P2& p2) const
+    {
+        assert_dimension<P1, 2>();
+        detail::spherical_to_cartesian(get_as_radian<0>(p1), get_as_radian<1>(p1), 1.0, p2);
+        return true;
+    }
+};
+
+/*!
+    \brief Transformation strategy for 3D spherical (phi,theta,r) to 3D cartesian (x,y,z)
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+ */
+template <typename P1, typename P2>
+struct from_spherical_3_to_cartesian_3
+{
+    inline bool operator()(P1 const& p1, P2& p2) const
+    {
+        assert_dimension<P1, 3>();
+        detail::spherical_to_cartesian(
+                    get_as_radian<0>(p1), get_as_radian<1>(p1), get<2>(p1), p2);
+        return true;
+    }
+};
+
+/*!
+    \brief Transformation strategy for 3D cartesian (x,y,z) to 2D spherical (phi,theta)
+    \details on Unit sphere
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+    \note If x,y,z point is not lying on unit sphere, transformation will return false
+ */
+template <typename P1, typename P2>
+struct from_cartesian_3_to_spherical_2
+{
+    inline bool operator()(P1 const& p1, P2& p2) const
+    {
+        assert_dimension<P1, 3>();
+        return detail::cartesian_to_spherical2(get<0>(p1), get<1>(p1), get<2>(p1), p2);
+    }
+};
+
+
+/*!
+    \brief Transformation strategy for 3D cartesian (x,y,z) to 3D spherical (phi,theta,r)
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+ */
+template <typename P1, typename P2>
+struct from_cartesian_3_to_spherical_3
+{
+    inline bool operator()(P1 const& p1, P2& p2) const
+    {
+        assert_dimension<P1, 3>();
+        return detail::cartesian_to_spherical3(get<0>(p1), get<1>(p1), get<2>(p1), p2);
+    }
+};
+
+}} // namespace strategy::transform
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+/// Specialization for same coordinate system family, same system, same dimension, same point type, can be copied
+template <typename CoordSysTag, typename CoordSys, std::size_t D, typename P>
+struct strategy_transform<CoordSysTag, CoordSysTag, CoordSys, CoordSys, D, D, P, P>
+{
+    typedef strategy::transform::copy_direct<P> type;
+};
+
+/// Specialization for same coordinate system family and system, same dimension, different point type, copy per coordinate
+template <typename CoordSysTag, typename CoordSys, std::size_t D, typename P1, typename P2>
+struct strategy_transform<CoordSysTag, CoordSysTag, CoordSys, CoordSys, D, D, P1, P2>
+{
+    typedef strategy::transform::copy_per_coordinate<P1, P2> type;
+};
+
+/// Specialization to convert from degree to radian for any coordinate system / point type combination
+template <typename CoordSysTag, template<typename> class CoordSys, typename P1, typename P2>
+struct strategy_transform<CoordSysTag, CoordSysTag, CoordSys<degree>, CoordSys<radian>, 2, 2, P1, P2>
+{
+    typedef strategy::transform::degree_radian_vv<P1, P2, std::multiplies> type;
+};
+
+/// Specialization to convert from radian to degree for any coordinate system / point type combination
+template <typename CoordSysTag, template<typename> class CoordSys, typename P1, typename P2>
+struct strategy_transform<CoordSysTag, CoordSysTag, CoordSys<radian>, CoordSys<degree>, 2, 2, P1, P2>
+{
+    typedef strategy::transform::degree_radian_vv<P1, P2, std::divides> type;
+};
+
+
+/// Specialization degree->radian in 3D
+template <typename CoordSysTag, template<typename> class CoordSys, typename P1, typename P2>
+struct strategy_transform<CoordSysTag, CoordSysTag, CoordSys<degree>, CoordSys<radian>, 3, 3, P1, P2>
+{
+    typedef strategy::transform::degree_radian_vv_3<P1, P2, std::multiplies> type;
+};
+
+/// Specialization radian->degree in 3D
+template <typename CoordSysTag, template<typename> class CoordSys, typename P1, typename P2>
+struct strategy_transform<CoordSysTag, CoordSysTag, CoordSys<radian>, CoordSys<degree>, 3, 3, P1, P2>
+{
+    typedef strategy::transform::degree_radian_vv_3<P1, P2, std::divides> type;
+};
+
+/// Specialization to convert from unit sphere(phi,theta) to XYZ
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct strategy_transform<spherical_tag, cartesian_tag, CoordSys1, CoordSys2, 2, 3, P1, P2>
+{
+    typedef strategy::transform::from_spherical_2_to_cartesian_3<P1, P2> type;
+};
+
+/// Specialization to convert from sphere(phi,theta,r) to XYZ
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct strategy_transform<spherical_tag, cartesian_tag, CoordSys1, CoordSys2, 3, 3, P1, P2>
+{
+    typedef strategy::transform::from_spherical_3_to_cartesian_3<P1, P2> type;
+};
+
+/// Specialization to convert from XYZ to unit sphere(phi,theta)
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct strategy_transform<cartesian_tag, spherical_tag, CoordSys1, CoordSys2, 3, 2, P1, P2>
+{
+    typedef strategy::transform::from_cartesian_3_to_spherical_2<P1, P2> type;
+};
+
+/// Specialization to convert from XYZ to sphere(phi,theta,r)
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct strategy_transform<cartesian_tag, spherical_tag, CoordSys1, CoordSys2, 3, 3, P1, P2>
+{
+    typedef strategy::transform::from_cartesian_3_to_spherical_3<P1, P2> type;
+};
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_STRATEGY_TRANSFORM_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/transform/inverse_transformer.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/transform/inverse_transformer.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,65 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_TRANSFORM_INVERSE_TRANSFORMER_HPP
+#define GGL_STRATEGIES_TRANSFORM_INVERSE_TRANSFORMER_HPP
+
+#include <boost/numeric/ublas/lu.hpp>
+#include <boost/numeric/ublas/io.hpp>
+#include <ggl/strategies/transform/matrix_transformers.hpp>
+
+namespace ggl
+{
+
+namespace strategy { namespace transform {
+
+/*!
+    \brief Transformation strategy to do an inverse ransformation in Cartesian system
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+ */
+template <typename P1, typename P2>
+struct inverse_transformer 
+    : ublas_transformer<P1, P2, dimension<P1>::type::value, dimension<P2>::type::value>
+{
+    typedef typename select_coordinate_type<P1, P2>::type T;
+
+    template <typename MatrixType>
+    inline inverse_transformer(const MatrixType& input)
+    {
+        typedef boost::numeric::ublas::matrix<double> matrix_type;
+        // create a working copy of the input
+        matrix_type copy(input.matrix());
+
+        // create a permutation matrix for the LU-factorization
+        typedef boost::numeric::ublas::permutation_matrix<> permutation_matrix;
+        permutation_matrix pm(copy.size1());
+
+        // perform LU-factorization
+        int res = boost::numeric::ublas::lu_factorize<matrix_type>(copy, pm);
+        if( res == 0 )
+        {
+            // create identity matrix
+            this->m_matrix.assign(boost::numeric::ublas::identity_matrix<T>(copy.size1()));
+
+            // backsubstitute to get the inverse
+            boost::numeric::ublas::lu_substitute(copy, pm, this->m_matrix);
+        }
+    }
+
+
+};
+
+
+}} // namespace strategy::transform
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_TRANSFORM_INVERSE_TRANSFORMER_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/transform/map_transformer.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/transform/map_transformer.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,145 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_TRANSFORM_MAP_TRANSFORMER_HPP
+#define GGL_STRATEGIES_TRANSFORM_MAP_TRANSFORMER_HPP
+
+
+#include <ggl/strategies/transform/matrix_transformers.hpp>
+
+
+namespace ggl
+{
+
+namespace strategy { namespace transform {
+
+/*!
+    \brief Transformation strategy to do map from one to another Cartesian system
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+    \tparam Mirror if true map is mirrored upside-down (in most cases pixels
+        are from top to bottom, while map is from bottom to top)
+ */
+template 
+<
+    typename P1, typename P2, 
+    bool Mirror, bool SameScale = true,
+    std::size_t Dimension1 = dimension<P1>::type::value,
+    std::size_t Dimension2 = dimension<P2>::type::value
+>
+struct map_transformer 
+    : ublas_transformer<P1, P2, Dimension1, Dimension2>
+{
+    typedef typename select_coordinate_type<P1, P2>::type T;
+    typedef boost::numeric::ublas::matrix<T> M;
+
+    template <typename B, typename D>
+    explicit inline map_transformer(B const& box, D const& width, D const& height)
+    {
+        set_transformation(
+                get<min_corner, 0>(box), get<min_corner, 1>(box),
+                get<max_corner, 0>(box), get<max_corner, 1>(box),
+                width, height);
+    }
+
+    template <typename W, typename D>
+    explicit inline map_transformer(W const& wx1, W const& wy1, W const& wx2, W const& wy2,
+                        D const& width, D const& height)
+    {
+        set_transformation(wx1, wy1, wx2, wy2, width, height);
+    }
+
+
+    private :
+        void set_transformation_point(double wx, double wy, double px, double py, double scalex, double scaley)
+        {
+
+            // Translate to a coordinate system centered on world coordinates (-wx, -wy)
+            M t1(3,3);
+            t1(0,0) = 1;   t1(0,1) = 0;   t1(0,2) = -wx;
+            t1(1,0) = 0;   t1(1,1) = 1;   t1(1,2) = -wy;
+            t1(2,0) = 0;   t1(2,1) = 0;   t1(2,2) = 1;
+
+            // Scale the map
+            M s(3,3);
+            s(0,0) = scalex;   s(0,1) = 0;   s(0,2) = 0;
+            s(1,0) = 0;    s(1,1) = scaley;  s(1,2) = 0;
+            s(2,0) = 0;    s(2,1) = 0;      s(2,2) = 1;
+
+            // Translate to a coordinate system centered on the specified pixels (+px, +py)
+            M t2(3, 3);
+            t2(0,0) = 1;   t2(0,1) = 0;   t2(0,2) = px;
+            t2(1,0) = 0;   t2(1,1) = 1;   t2(1,2) = py;
+            t2(2,0) = 0;   t2(2,1) = 0;   t2(2,2) = 1;
+
+            // Calculate combination matrix in two steps
+            this->m_matrix = boost::numeric::ublas::prod(s, t1);
+            this->m_matrix = boost::numeric::ublas::prod(t2, this->m_matrix);
+        }
+
+
+        template <typename W, typename D>
+        void set_transformation(W const& wx1, W const& wy1, W const& wx2, W const& wy2,
+                        D const& width, D const& height)
+        {
+            D px1 = 0;
+            D py1 = 0;
+            D px2 = width;
+            D py2 = height;
+
+
+            // Calculate appropriate scale, take min because whole box must fit
+            // Scale is in PIXELS/MAPUNITS (meters)
+            double sx = (px2 - px1) / (wx2 - wx1);
+            double sy = (py2 - py1) / (wy2 - wy1);
+
+            if (SameScale)
+            {
+                double scale = (std::min)(sx, sy);
+                sx = scale;
+                sy = scale;
+            }
+
+            // Calculate centerpoints
+            double wmx = (wx1 + wx2) / 2.0;
+            double wmy = (wy1 + wy2) / 2.0;
+            double pmx = (px1 + px2) / 2.0;
+            double pmy = (py1 + py2) / 2.0;
+
+            set_transformation_point(wmx, wmy, pmx, pmy, sx, sy);
+
+            if (Mirror)
+            {
+                // Mirror in y-direction
+                M m(3,3);
+                m(0,0) = 1;   m(0,1) = 0;   m(0,2) = 0;
+                m(1,0) = 0;   m(1,1) = -1;  m(1,2) = 0;
+                m(2,0) = 0;   m(2,1) = 0;   m(2,2) = 1;
+
+                // Translate in y-direction such that it fits again
+                M y(3, 3);
+                y(0,0) = 1;   y(0,1) = 0;   y(0,2) = 0;
+                y(1,0) = 0;   y(1,1) = 1;   y(1,2) = height;
+                y(2,0) = 0;   y(2,1) = 0;   y(2,2) = 1;
+
+                // Calculate combination matrix in two steps
+                this->m_matrix = boost::numeric::ublas::prod(m, this->m_matrix);
+                this->m_matrix = boost::numeric::ublas::prod(y, this->m_matrix);
+            }
+        }
+};
+
+}} // namespace strategy::transform
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_TRANSFORM_MAP_TRANSFORMER_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/strategies/transform/matrix_transformers.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/strategies/transform/matrix_transformers.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,357 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_MATRIX_TRANSFORMERS_HPP
+#define GGL_STRATEGIES_MATRIX_TRANSFORMERS_HPP
+
+
+// Remove the ublas checking, otherwise the inverse might fail (while nothing seems to be wrong)
+#define BOOST_UBLAS_TYPE_CHECK 0
+
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+
+#include <ggl/core/coordinate_dimension.hpp>
+
+
+namespace ggl
+{
+
+
+namespace strategy { namespace transform {
+
+
+/*!
+    \brief Transformation strategy to do an affine matrix transformation in Cartesian system
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+    \tparam Dimension1 number of dimensions to transform from first point, optional
+    \tparam Dimension1 number of dimensions to transform to second point, optional
+ */
+template
+<
+    typename P1, typename P2,
+    std::size_t Dimension1,
+    std::size_t Dimension2
+>
+class ublas_transformer
+{
+};
+
+template <typename P1, typename P2>
+class ublas_transformer<P1, P2, 2, 2>
+{
+protected :
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+    typedef coordinate_type ct; // Abbreviation
+    typedef boost::numeric::ublas::matrix<coordinate_type> matrix_type;
+    matrix_type m_matrix;
+
+public :
+    inline ublas_transformer(
+                ct const& m_0_0, ct const& m_0_1, ct const& m_0_2,
+                ct const& m_1_0, ct const& m_1_1, ct const& m_1_2,
+                ct const& m_2_0, ct const& m_2_1, ct const& m_2_2)
+        : m_matrix(3, 3)
+    {
+        m_matrix(0,0) = m_0_0;   m_matrix(0,1) = m_0_1;   m_matrix(0,2) = m_0_2;
+        m_matrix(1,0) = m_1_0;   m_matrix(1,1) = m_1_1;   m_matrix(1,2) = m_1_2;
+        m_matrix(2,0) = m_2_0;   m_matrix(2,1) = m_2_1;   m_matrix(2,2) = m_2_2;
+    }
+
+    inline ublas_transformer()
+        : m_matrix(3, 3)
+    {
+    }
+
+
+    inline bool operator()(const P1& p1, P2& p2) const
+    {
+        assert_dimension_greater_equal<P1, 2>();
+        assert_dimension_greater_equal<P2, 2>();
+
+        const coordinate_type& c1 = get<0>(p1);
+        const coordinate_type& c2 = get<1>(p1);
+
+        typedef typename ggl::coordinate_type<P2>::type ct2;
+
+        set<0>(p2, boost::numeric_cast<ct2>(c1 * m_matrix(0,0)
+                + c2 * m_matrix(0,1) + m_matrix(0,2)));
+        set<1>(p2, boost::numeric_cast<ct2>(c1 * m_matrix(1,0)
+                + c2 * m_matrix(1,1) + m_matrix(1,2)));
+
+        return true;
+    }
+
+    const matrix_type& matrix() const { return m_matrix; }
+};
+
+// It IS possible to go from 3 to 2 coordinates
+template <typename P1, typename P2>
+struct ublas_transformer<P1, P2, 3, 2>
+    : public ublas_transformer<P1, P2, 2, 2>
+{
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+    typedef coordinate_type ct; // Abbreviation
+
+    inline ublas_transformer(
+                ct const& m_0_0, ct const& m_0_1, ct const& m_0_2,
+                ct const& m_1_0, ct const& m_1_1, ct const& m_1_2,
+                ct const& m_2_0, ct const& m_2_1, ct const& m_2_2)
+        : ublas_transformer<P1, P2, 2, 2>(
+                    m_0_0, m_0_1, m_0_2,
+                    m_1_0, m_1_1, m_1_2,
+                    m_2_0, m_2_1, m_2_2)
+    {}
+
+    inline ublas_transformer()
+        : ublas_transformer<P1, P2, 2, 2>()
+    {}
+};
+
+
+template <typename P1, typename P2>
+class ublas_transformer<P1, P2, 3, 3>
+{
+protected :
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+    typedef coordinate_type ct; // Abbreviation
+    typedef boost::numeric::ublas::matrix<coordinate_type> matrix_type;
+    matrix_type m_matrix;
+
+    inline ublas_transformer(
+                ct const& m_0_0, ct const& m_0_1, ct const& m_0_2, ct const& m_0_3,
+                ct const& m_1_0, ct const& m_1_1, ct const& m_1_2, ct const& m_1_3,
+                ct const& m_2_0, ct const& m_2_1, ct const& m_2_2, ct const& m_2_3,
+                ct const& m_3_0, ct const& m_3_1, ct const& m_3_2, ct const& m_3_3
+                )
+        : m_matrix(4, 4)
+    {
+        m_matrix(0,0) = m_0_0; m_matrix(0,1) = m_0_1; m_matrix(0,2) = m_0_2; m_matrix(0,3) = m_0_3;
+        m_matrix(1,0) = m_1_0; m_matrix(1,1) = m_1_1; m_matrix(1,2) = m_1_2; m_matrix(1,3) = m_1_3;
+        m_matrix(2,0) = m_2_0; m_matrix(2,1) = m_2_1; m_matrix(2,2) = m_2_2; m_matrix(2,3) = m_2_3;
+        m_matrix(3,0) = m_3_0; m_matrix(3,1) = m_3_1; m_matrix(3,2) = m_3_2; m_matrix(3,3) = m_3_3;
+    }
+
+    inline ublas_transformer()
+        : m_matrix(4, 4)
+    {
+    }
+
+
+public :
+
+    inline bool operator()(const P1& p1, P2& p2) const
+    {
+        const coordinate_type& c1 = get<0>(p1);
+        const coordinate_type& c2 = get<1>(p1);
+        const coordinate_type& c3 = get<2>(p1);
+
+        typedef typename ggl::coordinate_type<P2>::type ct2;
+
+        set<0>(p2, boost::numeric_cast<ct2>(c1 * m_matrix(0,0)
+                + c2 * m_matrix(0,1) + c3 * m_matrix(0,2) + m_matrix(0,3)));
+        set<1>(p2, boost::numeric_cast<ct2>(c1 * m_matrix(1,0)
+                + c2 * m_matrix(1,1) + c3 * m_matrix(1,2) + m_matrix(1,3)));
+        set<2>(p2, boost::numeric_cast<ct2>(c1 * m_matrix(2,0)
+                + c2 * m_matrix(2,1) + c3 * m_matrix(2,2) + m_matrix(2,3)));
+
+        return true;
+    }
+
+    const matrix_type& matrix() const { return m_matrix; }
+};
+
+
+
+
+/*!
+    \brief Transformation strategy to translate in Cartesian system
+    \ingroup transform
+    \see http://www.devmaster.net/wiki/Transformation_matrices
+    \tparam P1 first point type
+    \tparam P2 second point type
+    \tparam Dimension1 number of dimensions to transform from first point, optional
+    \tparam Dimension1 number of dimensions to transform to second point, optional
+ */
+template
+<
+    typename P1, typename P2,
+    std::size_t Dimension1 = ggl::dimension<P1>::type::value,
+    std::size_t Dimension2 = ggl::dimension<P2>::type::value
+>
+struct translate_transformer {};
+
+
+template <typename P1, typename P2>
+struct translate_transformer<P1, P2, 2, 2>
+        : ublas_transformer<P1, P2, 2, 2>
+{
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+    // To have translate transformers compatible for 2/3 dimensions, the
+    // constructor takes an optional third argument doing nothing.
+    inline translate_transformer(coordinate_type const& translate_x,
+                coordinate_type const& translate_y,
+                coordinate_type const& dummy = 0)
+        : ublas_transformer<P1, P2, 2, 2>(
+                1, 0, translate_x,
+                0, 1, translate_y,
+                0, 0, 1)
+    {}
+
+};
+
+template <typename P1, typename P2>
+struct translate_transformer<P1, P2, 3, 3> : ublas_transformer<P1, P2, 3, 3>
+{
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+    inline translate_transformer(coordinate_type const& translate_x,
+                coordinate_type const& translate_y,
+                coordinate_type const& translate_z)
+        : ublas_transformer<P1, P2, 3, 3>(
+                1, 0, 0, translate_x,
+                0, 1, 0, translate_y,
+                0, 0, 1, translate_z,
+                0, 0, 0, 1)
+    {}
+
+};
+
+
+/*!
+    \brief Transformation strategy to scale in Cartesian system
+    \ingroup transform
+    \see http://www.devmaster.net/wiki/Transformation_matrices
+    \tparam P1 first point type
+    \tparam P2 second point type
+    \tparam Dimension1 number of dimensions to transform from first point, optional
+    \tparam Dimension1 number of dimensions to transform to second point, optional
+*/
+template
+<
+    typename P1, typename P2,
+    std::size_t Dimension1 = ggl::dimension<P1>::type::value,
+    std::size_t Dimension2 = ggl::dimension<P2>::type::value
+>
+struct scale_transformer {};
+
+
+template <typename P1, typename P2>
+struct scale_transformer<P1, P2, 2, 2> : ublas_transformer<P1, P2, 2, 2>
+{
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+    inline scale_transformer(coordinate_type const& scale_x,
+                coordinate_type const& scale_y,
+                coordinate_type const& dummy = 0)
+        : ublas_transformer<P1, P2, 2, 2>(
+                scale_x, 0,       0,
+                0,       scale_y, 0,
+                0,       0,       1)
+    {}
+};
+
+
+template <typename P1, typename P2>
+struct scale_transformer<P1, P2, 3, 3> : ublas_transformer<P1, P2, 3, 3>
+{
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+    inline scale_transformer(coordinate_type const& scale_x,
+                coordinate_type const& scale_y,
+                coordinate_type const& scale_z)
+        : ublas_transformer<P1, P2, 3, 3>(
+                scale_x, 0,       0,       0,
+                0,       scale_y, 0,       0,
+                0,       0,       scale_z, 0,
+                0,       0,       0,       1)
+    {}
+};
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail {
+
+template <typename DegreeOrRadian>
+struct as_radian {};
+
+template <>
+struct as_radian<radian>
+{
+    static inline double get(double const& value)
+    {
+        return value;
+    }
+};
+
+template <>
+struct as_radian<degree>
+{
+    static inline double get(double const& value)
+    {
+        return value * math::d2r;
+    }
+
+};
+
+
+template
+<
+    typename P1, typename P2,
+    std::size_t Dimension1 = ggl::dimension<P1>::type::value,
+    std::size_t Dimension2 = ggl::dimension<P2>::type::value
+>
+struct rad_rotate_transformer
+    : ublas_transformer<P1, P2, Dimension1, Dimension2>
+{
+    inline rad_rotate_transformer(double const& angle)
+        : ublas_transformer<P1, P2, Dimension1, Dimension2>(
+                 cos(angle), sin(angle), 0,
+                -sin(angle), cos(angle), 0,
+                 0,          0,          1)
+    {}
+};
+
+}
+#endif
+
+
+/*!
+    \brief Transformation strategy to rotate in Cartesian system
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+    \tparam DegreeOrRadian degree/or/radian, type of rotation angle specification
+    \note Not yet in 3D, the 3D version requires special things to allow for
+      rotation around X, Y, Z or arbitrary axis
+    \see http://www.devmaster.net/wiki/Transformation_matrices
+    \note The 3D version will not compile
+ */
+template <typename P1, typename P2, typename DegreeOrRadian>
+struct rotate_transformer : detail::rad_rotate_transformer<P1, P2>
+{
+    inline rotate_transformer(double const& angle)
+        : detail::rad_rotate_transformer
+            <
+                P1, P2
+            >(detail::as_radian<DegreeOrRadian>::get(angle))
+    {}
+
+};
+
+
+}} // namespace strategy::transform
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_MATRIX_TRANSFORMERS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/util/as_range.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/as_range.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,95 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_AS_RANGE_HPP
+#define GGL_UTIL_AS_RANGE_HPP
+
+#include <boost/type_traits.hpp>
+
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+namespace ggl {
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename GeometryTag, typename Geometry>
+struct as_range_type
+{
+    typedef Geometry type;
+};
+
+template <typename Geometry>
+struct as_range_type<polygon_tag, Geometry>
+{
+    typedef typename ring_type<Geometry>::type type;
+};
+
+
+
+template <typename GeometryTag, typename Geometry, typename Range>
+struct as_range
+{
+    static inline Range const& get(Geometry const& input)
+    {
+        return input;
+    }
+};
+
+template <typename Geometry, typename Range>
+struct as_range<polygon_tag, Geometry, Range>
+{
+    static inline Range const& get(Geometry const& input)
+    {
+        return exterior_ring(input);
+    }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Meta-function utility returning either type itself, or outer ring
+    \details Utility to handle polygon's outer ring as a range
+\ingroup utility
+*/
+template <typename Geometry>
+struct as_range_type
+{
+    typedef typename dispatch::as_range_type
+        <
+            typename tag<Geometry>::type,
+            Geometry
+        >::type type;
+};
+
+/*!
+\brief Function getting either the range (ring, linestring) itself
+or the outer ring
+    \details Utility to handle polygon's outer ring as a range
+\ingroup utility
+*/
+template <typename Range, typename Geometry>
+inline Range const& as_range(Geometry const& input)
+{
+    return dispatch::as_range
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            Range
+        >::get(input);
+}
+
+} // namespace ggl
+
+#endif // GGL_UTIL_AS_RANGE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/util/assign_box_corner.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/assign_box_corner.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,59 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_ASSIGN_BOX_CORNER_HPP
+#define GGL_UTIL_ASSIGN_BOX_CORNER_HPP
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <ggl/core/coordinate_dimension.hpp>
+
+// TODO: merge with "assign"
+
+namespace ggl
+{
+
+/*!
+    \brief Assign one point of a 2D box
+    \ingroup assign
+    \todo will be merged with assign
+*/
+template <std::size_t C1, std::size_t C2, typename B, typename P>
+inline void assign_box_corner(B const& box, P& point)
+{
+    // Be sure both are 2-Dimensional
+    assert_dimension<B, 2>();
+    assert_dimension<P, 2>();
+
+    // Copy coordinates
+    typedef typename coordinate_type<P>::type coordinate_type;
+
+    set<0>(point, boost::numeric_cast<coordinate_type>(get<C1, 0>(box)));
+    set<1>(point, boost::numeric_cast<coordinate_type>(get<C2, 1>(box)));
+}
+
+/*!
+    \brief Assign the 4 points of a 2D box
+    \ingroup assign
+    \todo will be merged with assign
+    \note The order can be crucial. Most logical is LOWER, UPPER and sub-order LEFT, RIGHT
+*/
+template <typename B, typename P>
+inline void assign_box_corners(B const& box, P& lower_left, P& lower_right, P& upper_left, P& upper_right)
+{
+    assign_box_corner<min_corner, min_corner>(box, lower_left);
+    assign_box_corner<max_corner, min_corner>(box, lower_right);
+    assign_box_corner<min_corner, max_corner>(box, upper_left);
+    assign_box_corner<max_corner, max_corner>(box, upper_right);
+}
+
+} // namespace
+
+#endif // GGL_UTIL_ASSIGN_BOX_CORNER_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/util/copy.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/copy.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,76 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_COPY_HPP
+#define GGL_UTIL_COPY_HPP
+
+#include <cstddef>
+
+#include <boost/concept/requires.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/concept_check.hpp>
+
+#include <ggl/core/concepts/point_concept.hpp>
+
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace copy {
+
+template <typename Src, typename Dst, std::size_t D, std::size_t N>
+struct copy_coordinates
+{
+    static inline void copy(const Src& source, Dst& dest)
+    {
+        typedef typename coordinate_type<Dst>::type coordinate_type;
+
+        set<D>(dest, boost::numeric_cast<coordinate_type>(get<D>(source)));
+        copy_coordinates<Src, Dst, D + 1, N>::copy(source, dest);
+    }
+};
+
+template <typename Src, typename Dst, std::size_t N>
+struct copy_coordinates<Src, Dst, N, N>
+{
+    static inline void copy(const Src& source, Dst& dest)
+    {
+        boost::ignore_unused_variable_warning(source);
+        boost::ignore_unused_variable_warning(dest);
+    }
+};
+
+}} // namespace detail::copy
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief Copies coordinates from source to destination point
+    \ingroup assign
+    \details The function copy_coordinates copies coordinates from one point to another point.
+    Source point and destination point might be of different types.
+    \param source Source point
+    \param dest Destination point
+    \note If destination type differs from source type, they must have the same coordinate count
+ */
+template <typename Src, typename Dst>
+inline void copy_coordinates(const Src& source, Dst& dest)
+{
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Src>) );
+    BOOST_CONCEPT_ASSERT( (concept::Point<Dst>) );
+
+
+    //assert_dimension_equal<Dst, Src>();
+    detail::copy::copy_coordinates<Src, Dst, 0, dimension<Src>::value>::copy(source, dest);
+}
+
+} // namespace ggl
+
+#endif // GGL_UTIL_COPY_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/util/for_each_coordinate.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/for_each_coordinate.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,64 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_FOR_EACH_COORDINATE_HPP
+#define GGL_UTIL_FOR_EACH_COORDINATE_HPP
+
+#include <boost/concept/requires.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename Point, int Dimension, int DimensionCount>
+struct coordinates_scanner
+{
+    template <typename Op>
+    static inline void apply(Point& point, Op operation)
+    {
+        operation.template apply<Point, Dimension>(point);
+        coordinates_scanner
+            <
+                Point,
+                Dimension+1,
+                DimensionCount
+            >::apply(point, operation);
+    }
+};
+
+template <typename Point, int DimensionCount>
+struct coordinates_scanner<Point, DimensionCount, DimensionCount>
+{
+    template <typename Op>
+    static inline void apply(Point&, Op)
+    {}
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+template <typename Point, typename Op>
+inline void for_each_coordinate(Point& point, Op operation)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+    typedef typename detail::coordinates_scanner
+        <
+            Point, 0, dimension<Point>::type::value
+        > scanner;
+
+    scanner::apply(point, operation);
+}
+
+} // namespace ggl
+
+#endif // GGL_UTIL_FOR_EACH_COORDINATE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/util/get_cs_as_radian.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/get_cs_as_radian.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,46 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_UTIL_GET_CS_AS_RADIAN_HPP
+#define GGL_UTIL_GET_CS_AS_RADIAN_HPP
+
+
+#include <boost/type_traits/remove_const.hpp>
+
+
+
+
+namespace ggl {
+
+namespace detail {
+
+    template <typename CoordinateSystem>
+    struct get_cs_as_radian {};
+
+    template <typename Units>
+    struct get_cs_as_radian<cs::geographic<Units> >
+    {
+        typedef cs::geographic<radian> type;
+    };
+
+    template <typename Units>
+    struct get_cs_as_radian<cs::spherical<Units> >
+    {
+        typedef cs::spherical<radian> type;
+    };
+
+}
+
+
+
+
+
+} // namespace ggl
+
+#endif // GGL_UTIL_GET_CS_AS_RADIAN_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/util/less.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/less.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,64 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_LESS_HPP
+#define GGL_UTIL_LESS_HPP
+
+
+namespace ggl
+{
+
+/*!
+    \brief Less predicate for usage in e.g. std::map
+*/
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename P, std::size_t Dimension, std::size_t DimensionCount>
+struct less
+{
+    static inline bool apply(P const& left, P const& right)
+    {
+        typedef typename ggl::coordinate_type<P>::type coordinate_type;
+        coordinate_type const cleft = ggl::get<Dimension>(left);
+        coordinate_type const cright = ggl::get<Dimension>(right);
+
+        return ggl::math::equals(cleft, cright)
+                ? less<P, Dimension + 1, DimensionCount>::apply(left, right)
+                : cleft < cright;
+                ;
+    }
+};
+
+template <typename P, std::size_t DimensionCount>
+struct less<P, DimensionCount, DimensionCount>
+{
+    static inline bool apply(P const&, P const&)
+    {
+        return false;
+    }
+};
+
+}
+#endif
+
+template <typename P>
+struct less
+{
+    inline bool operator()(P const& left, P const& right) const
+    {
+        return detail::less<P, 0,
+            ggl::dimension<P>::type::value>::apply(left, right);
+    }
+};
+
+} // namespace ggl
+
+#endif // GGL_UTIL_LESS_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/util/loop.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/loop.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,85 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_LOOP_HPP
+#define GGL_UTIL_LOOP_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/geometries/segment.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief Loops through segments of a container and call specified functor for all segments.
+    \ingroup loop
+    \details for_each like implementation to:
+    - walk over const segments of a linestring/polygon
+    - be able to break out the loop (if the functor returns false)
+    - have a const functor and keep state in separate state-object
+    - we still keep the "functor" here so it might be a function or an object, at this place
+    - in most algorithms the typename F::state_type is used; in those places it must be an object
+
+    \tparam R range type, for example a vector, linestring, linear_ring
+    \tparam F functor type, class or function, not modified by the algorithm
+    \tparam S state type, might be modified
+    \param range range (linestring iterator pair,vector,list,deque) containing points
+    \param functor functor which is called at each const segment
+    \param state state, specified separately from the strategy functor
+    \return false if the functor returns false, otherwise true
+    \par Concepts
+    - \a V
+        - const_iterator begin()
+        - const_iterator end()
+        - value_type
+    - \a F
+        - <em>if it is a function functor</em>: bool \b function (const segment&, state&)
+        - <em>if it is a class functor</em>: bool operator()(const segment&, state&) const
+    - \a S
+        - no specific requirements here, requirments given by F
+    \note Some algorithms from the Generic Geometry Library, for example within, centroid,
+    use this method.
+    \par Examples:
+    First example, using a class functor
+    \dontinclude doxygen_examples.cpp
+    \skip example_loop1
+    \line {
+    \until //:\\
+    Second example, using a function functor and latlong coordinates
+    \dontinclude doxygen_examples.cpp
+    \skip example_loop2
+    \line {
+    \until //:\\
+*/
+template<typename R, typename F, typename S>
+inline bool loop(R const& range, F const& functor, S& state)
+{
+    typedef typename boost::range_const_iterator<R>::type iterator_type;
+
+    iterator_type it = boost::begin(range);
+    if (it != boost::end(range))
+    {
+        iterator_type previous = it++;
+        while(it != boost::end(range))
+        {
+            segment<const typename boost::range_value<R>::type> s(*previous, *it);
+            if (! functor(s, state))
+            {
+                return false;
+            }
+            previous = it++;
+        }
+    }
+    return true;
+}
+
+} // namespace ggl
+
+#endif // GGL_UTIL_LOOP_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/util/math.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/math.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,98 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_MATH_HPP
+#define GGL_UTIL_MATH_HPP
+
+#include <cmath>
+#include <limits>
+
+#include <boost/math/constants/constants.hpp>
+
+#include <ggl/util/select_most_precise.hpp>
+
+namespace ggl
+{
+
+namespace math
+{
+
+// Maybe replace this by boost equals or boost ublas numeric equals or so
+
+/*!
+    \brief returns true if both arguments are equal.
+
+    equals returns true if both arguments are equal.
+    \param a first argument
+    \param b second argument
+    \return true if a == b
+    \note If both a and b are of an integral type, comparison is done by ==. If one of the types
+    is floating point, comparison is done by abs and comparing with epsilon.
+*/
+
+template <typename T1, typename T2>
+inline bool equals(T1 const& a, T2 const& b)
+{
+    typedef typename select_most_precise<T1, T2>::type select_type;
+
+    // TODO: select on is_fundemental. Otherwise (non-fundamental), take == operator
+    if (std::numeric_limits<select_type>::is_exact)
+    {
+        return a == b;
+    }
+    else
+    {
+        return std::abs(a - b) < std::numeric_limits<select_type>::epsilon();
+    }
+}
+
+
+
+double const pi = boost::math::constants::pi<double>();
+double const two_pi = 2.0 * pi;
+double const d2r = pi / 180.0;
+double const r2d = 1.0 / d2r;
+
+/*!
+    \brief Calculates the haversine of an angle
+    \note See http://en.wikipedia.org/wiki/Haversine_formula
+    haversin(alpha) = sin2(alpha/2)
+*/
+template <typename T>
+inline T hav(T const& theta)
+{
+    using boost::math::constants::half;
+    T const sn = std::sin(half<T>() * theta);
+    return sn * sn;
+}
+
+/*!
+\brief Short utility to return the square
+
+\param value Value to calculate the square from
+\return The squared value
+*/
+template <typename T>
+inline T sqr(T const& value)
+{
+    return value * value;
+}
+
+} // namespace math
+
+// To be moved somewhere.
+namespace constants
+{
+
+double const average_earth_radius = 6372795.0;
+
+} // namespace constants
+
+} // namespace ggl
+
+#endif // GGL_UTIL_MATH_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/util/select_coordinate_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/select_coordinate_type.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,40 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_SELECT_COORDINATE_TYPE_HPP
+#define GGL_UTIL_SELECT_COORDINATE_TYPE_HPP
+
+
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/util/select_most_precise.hpp>
+
+/*!
+\defgroup utility utility: utilities
+*/
+
+namespace ggl
+{
+
+
+/*!
+    \brief Utility selecting the most precise coordinate type of two geometries
+    \ingroup utility
+ */
+template <typename T1, typename T2>
+struct select_coordinate_type
+{
+    typedef typename select_most_precise
+        <
+            typename coordinate_type<T1>::type,
+            typename coordinate_type<T2>::type
+        >::type type;
+};
+
+} // namespace ggl
+
+#endif // GGL_UTIL_SELECT_COORDINATE_TYPE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/util/select_most_precise.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/select_most_precise.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,160 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_SELECT_MOST_PRECISE_HPP
+#define GGL_UTIL_SELECT_MOST_PRECISE_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+
+/*!
+\defgroup utility utility: utilities
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+
+namespace detail { namespace select_most_precise {
+
+
+// At least one of the types is non-fundamental. Take that one.
+// if both are non-fundamental, the type-to-be-selected
+// is unknown, it should be defined by explicit specialization.
+template <bool Fundamental1, bool Fundamental2, typename T1, typename T2>
+struct select_non_fundamental
+{
+    typedef T1 type;
+};
+
+template <typename T1, typename T2>
+struct select_non_fundamental<true, false, T1, T2>
+{
+    typedef T2 type;
+};
+
+template <typename T1, typename T2>
+struct select_non_fundamental<false, true, T1, T2>
+{
+    typedef T1 type;
+};
+
+
+// Selection of largest type (e.g. int of <short int,int>
+// It defaults takes the first one, if second is larger, take the second one
+template <bool SecondLarger, typename T1, typename T2>
+struct select_largest
+{
+    typedef T1 type;
+};
+
+template <typename T1, typename T2>
+struct select_largest<true, T1, T2>
+{
+    typedef T2 type;
+};
+
+
+
+// Selection of floating point and specializations:
+// both FP or both !FP does never occur...
+template <bool FP1, bool FP2, typename T1, typename T2>
+struct select_floating_point
+{
+    typedef char type;
+};
+
+
+// ... so if ONE but not both of these types is floating point, take that one
+template <typename T1, typename T2>
+struct select_floating_point<true, false, T1, T2>
+{
+    typedef T1 type;
+};
+
+
+template <typename T1, typename T2>
+struct select_floating_point<false, true, T1, T2>
+{
+    typedef T2 type;
+};
+
+
+}} // namespace detail::select_most_precise
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief Traits class to select, of two types, the most accurate type for
+        calculations
+    \ingroup utility
+    \details select_most_precise classes, compares two types on compile time.
+    For example, if an addition must be done with a double and an integer, the
+        result must be a double.
+    If both types are integer, the result can be an integer.
+    \note It is different from the "promote" class, already in boost. That
+        class promotes e.g. a (one) float to a double. This class selects a
+        type from two types. It takes the most accurate, but does not promote
+        afterwards.
+    \note This traits class is completely independant from GGL and might be a
+        separate (small) library in Boost
+    \note If the input is a non-fundamental type, it might be a calculation
+        type such as a GMP-value or another high precision value. Therefore,
+        if one is non-fundamental, that one is chosen.
+    \note If both types are non-fundamental, the result is indeterminate and
+        currently the first one is chosen.
+*/
+template <typename T1, typename T2>
+struct select_most_precise
+{
+    static const bool second_larger = sizeof(T2) > sizeof(T1);
+    static const bool one_not_fundamental = !
+        (boost::is_fundamental<T1>::type::value
+          && boost::is_fundamental<T2>::type::value);
+
+    static const bool both_same =
+        boost::is_floating_point<T1>::type::value
+        == boost::is_floating_point<T2>::type::value;
+
+    typedef typename boost::mpl::if_c
+        <
+            one_not_fundamental,
+            typename detail::select_most_precise::select_non_fundamental
+            <
+                boost::is_fundamental<T1>::type::value,
+                boost::is_fundamental<T2>::type::value,
+                T1,
+                T2
+            >::type,
+            typename boost::mpl::if_c
+            <
+                both_same,
+                typename detail::select_most_precise::select_largest
+                <
+                    second_larger,
+                    T1,
+                    T2
+                >::type,
+                typename detail::select_most_precise::select_floating_point
+                <
+                    boost::is_floating_point<T1>::type::value,
+                    boost::is_floating_point<T2>::type::value,
+                    T1,
+                    T2
+                >::type
+            >::type
+        >::type type;
+};
+
+
+
+} // namespace ggl
+
+#endif // GGL_UTIL_SELECT_MOST_PRECISE_HPP
Added: sandbox/ggl/formal_review_request/boost/ggl/util/write_dsv.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review_request/boost/ggl/util/write_dsv.hpp	2009-10-12 08:58:16 EDT (Mon, 12 Oct 2009)
@@ -0,0 +1,375 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_WRITE_DSV_HPP
+#define GGL_UTIL_WRITE_DSV_HPP
+
+#include <iostream>
+#include <string>
+
+#include <boost/concept/assert.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/convert.hpp>
+#include <ggl/core/concepts/point_concept.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/is_multi.hpp>
+#include <ggl/geometries/linear_ring.hpp>
+
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace dsv {
+
+
+struct dsv_settings
+{
+    std::string coordinate_separator;
+    std::string point_open;
+    std::string point_close;
+    std::string point_separator;
+    std::string list_open;
+    std::string list_close;
+    std::string list_separator;
+
+    dsv_settings(std::string const& sep
+            , std::string const& open
+            , std::string const& close
+            , std::string const& psep
+            , std::string const& lopen
+            , std::string const& lclose
+            , std::string const& lsep
+            )
+        : coordinate_separator(sep)
+        , point_open(open)
+        , point_close(close)
+        , point_separator(psep)
+        , list_open(lopen)
+        , list_close(lclose)
+        , list_separator(lsep)
+    {}
+};
+
+template <typename P, int Dimension, int Count>
+struct stream_coordinate
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os, P const& p,
+            dsv_settings const& settings)
+    {
+        os << (Dimension > 0 ? settings.coordinate_separator : "") 
+            << get<Dimension>(p);
+        stream_coordinate<P, Dimension + 1, Count>::apply(os, p, settings);
+    }
+};
+
+template <typename P, int Count>
+struct stream_coordinate<P, Count, Count>
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>&, P const&,
+            dsv_settings const& settings)
+    {}
+};
+
+
+template <typename P, int Index, int Dimension, int Count>
+struct stream_box_corner
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os, P const& p,
+            dsv_settings const& settings)
+    {
+        os << (Dimension > 0 ? settings.coordinate_separator : "") 
+            << get<Index, Dimension>(p);
+        stream_box_corner<P, Index, Dimension + 1, Count>::apply(os, p, settings);
+    }
+};
+
+template <typename P, int Index, int Count>
+struct stream_box_corner<P, Index, Count, Count>
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>&, P const&,
+            dsv_settings const& settings)
+    {}
+};
+
+
+
+
+
+/*!
+\brief Stream points as \ref DSV
+*/
+template <typename Point>
+struct dsv_point
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os, Point const& p,
+            dsv_settings const& settings)
+    {
+        os << settings.point_open;
+        stream_coordinate<Point, 0, dimension<Point>::type::value>::apply(os, p, settings);
+        os << settings.point_close;
+    }
+
+    private:
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point>) );
+};
+
+/*!
+\brief Stream ranges as DSV
+\note policy is used to stream prefix/postfix, enabling derived classes to override this
+*/
+template <typename Range>
+struct dsv_range
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                Range const& range,
+                dsv_settings const& settings)
+    {
+        typedef typename boost::range_const_iterator<Range>::type iterator_type;
+
+        bool first = true;
+
+        os << settings.list_open;
+
+        // TODO: check EMPTY here
+
+        for (iterator_type it = boost::begin(range);
+            it != boost::end(range);
+            ++it)
+        {
+            os << (first ? "" : settings.point_separator)
+                << settings.point_open;
+
+            stream_coordinate
+                <
+                    point, 0, dimension<point>::type::value
+                >::apply(os, *it, settings);
+            os << settings.point_close;
+
+            first = false;
+        }
+
+        os << settings.list_close;
+    }
+
+    private:
+        typedef typename boost::range_value<Range>::type point;
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<point>) );
+};
+
+/*!
+\brief Stream sequence of points as DSV-part, e.g. (1 2),(3 4)
+\note Used in polygon, all multi-geometries
+*/
+
+
+
+
+
+template <typename Polygon>
+struct dsv_poly
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                Polygon const& poly,
+                dsv_settings const& settings)
+    {
+        typedef typename ring_type<Polygon>::type ring;
+        typedef typename boost::range_const_iterator<
+                    typename interior_type<Polygon>::type>::type iterator;
+
+        os << settings.list_open;
+
+        dsv_range<ring>::apply(os, exterior_ring(poly), settings);
+        for (iterator it = boost::begin(interior_rings(poly));
+            it != boost::end(interior_rings(poly));
+            ++it)
+        {
+            os << settings.list_separator;
+            dsv_range<ring>::apply(os, *it, settings);
+        }
+        os << settings.list_close;
+    }
+
+    private:
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<typename point_type<Polygon>::type>) );
+};
+
+template <typename Box, std::size_t Index>
+struct dsv_box_corner
+{
+    typedef typename point_type<Box>::type point_type;
+
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+            Box const& box,
+            dsv_settings const& settings)
+    {
+        os << settings.point_open;
+        stream_box_corner
+            <
+                Box, Index, 0, dimension<Box>::type::value
+            >::apply(os, box, settings);
+        os << settings.point_close;
+    }
+};
+
+
+template <typename Box>
+struct dsv_box
+{
+    typedef typename point_type<Box>::type point_type;
+
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+            Box const& box,
+            dsv_settings const& settings)
+    {
+        os << settings.list_open;
+        dsv_box_corner<Box, 0>::apply(os, box, settings);
+        os << settings.point_separator;
+        dsv_box_corner<Box, 1>::apply(os, box, settings);
+        os << settings.list_close;
+    }
+};
+
+}} // namespace detail::dsv
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+template <typename Tag, bool IsMulti, typename Geometry>
+struct dsv {};
+
+
+template <typename Point>
+struct dsv<point_tag, false, Point>
+    : detail::dsv::dsv_point<Point>
+{};
+
+
+template <typename Linestring>
+struct dsv<linestring_tag, false, Linestring>
+    : detail::dsv::dsv_range<Linestring>
+{};
+
+
+/*!
+\brief Specialization to stream a box as DSV
+*/
+template <typename Box>
+struct dsv<box_tag, false, Box>
+    : detail::dsv::dsv_box<Box>
+{};
+
+
+/*!
+\brief Specialization to stream a ring as DSV
+*/
+template <typename Ring>
+struct dsv<ring_tag, false, Ring>
+    : detail::dsv::dsv_range<Ring>
+{};
+
+
+/*!
+\brief Specialization to stream polygon as DSV
+*/
+template <typename Polygon>
+struct dsv<polygon_tag, false, Polygon>
+    : detail::dsv::dsv_poly<Polygon>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Generic geometry template manipulator class, takes corresponding output class from traits class
+\ingroup dsv
+\details Stream manipulator, streams geometry classes as \ref DSV streams
+\par Example:
+Small example showing how to use the dsv class
+\dontinclude doxygen_examples.cpp
+\skip example_as_dsv_point
+\line {
+\until }
+\note the template parameter must be specified. If that is inconvient, users might use streamdsv
+which streams geometries as manipulators, or the object generator make_dsv
+*/
+template <typename Geometry>
+class dsv_manipulator
+{
+public:
+
+    inline dsv_manipulator(Geometry const& g,
+            detail::dsv::dsv_settings const& settings)
+        : m_geometry(g)
+        , m_settings(settings)
+    {}
+
+    template <typename Char, typename Traits>
+    inline friend std::basic_ostream<Char, Traits>& operator<<(
+            std::basic_ostream<Char, Traits>& os,
+            dsv_manipulator const& m)
+    {
+        dispatch::dsv
+            <
+                typename tag<Geometry>::type,
+                is_multi<Geometry>::type::value,
+                Geometry
+            >::apply(os, m.m_geometry, m.m_settings);
+        os.flush();
+        return os;
+    }
+
+private:
+    Geometry const& m_geometry;
+    detail::dsv::dsv_settings m_settings;
+};
+
+/*!
+\brief Main DSV-streaming function
+\ingroup dsv
+*/
+template <typename Geometry>
+inline dsv_manipulator<Geometry> dsv(Geometry const& geometry
+    , std::string const& coordinate_separator = ", "
+    , std::string const& point_open = "("
+    , std::string const& point_close = ")"
+    , std::string const& point_separator = ", "
+    , std::string const& list_open = "("
+    , std::string const& list_close = ")"
+    , std::string const& list_separator = ", "
+    )
+{
+    return dsv_manipulator<Geometry>(geometry,
+        detail::dsv::dsv_settings(coordinate_separator,
+            point_open, point_close, point_separator,
+            list_open, list_close, list_separator));
+}
+
+
+
+} // namespace ggl
+
+#endif // GGL_UTIL_WRITE_DSV_HPP