static inline void base_test(Geometry1 const& geometry1,
                                 Geometry2 const& geometry2,
                                 MultiLineString const& mls_diff,
                                 std::string const& case_id,
                                 double tolerance,
                                 bool test_vector_and_deque = true,
                                 bool reverse_output_for_checking = false)
    {
        static bool vector_deque_already_tested = false;

        typedef typename boost::range_value<MultiLineString>::type LineString;
        typedef std::vector<LineString> linestring_vector;
        typedef std::deque<LineString> linestring_deque;

        MultiLineString mls_output;

        linestring_vector ls_vector_output;
        linestring_deque ls_deque_output;

        // Check strategy passed explicitly
        typedef typename bg::strategy::relate::services::default_strategy
            <
                Geometry1, Geometry2
            >::type strategy_type;
        bg::difference(geometry1, geometry2, mls_output, strategy_type());

        if (reverse_output_for_checking)
        {
            bg::reverse(mls_output);
        }

        check_result(geometry1, geometry2, mls_output, mls_diff, case_id, tolerance);

        // Check normal behaviour
        bg::clear(mls_output);
        bg::difference(geometry1, geometry2, mls_output);

        if ( reverse_output_for_checking ) 
        {
            bg::reverse(mls_output);
        }

        check_result(geometry1, geometry2, mls_output, mls_diff, case_id, tolerance);
        
        set_operation_output("difference", case_id,
                             geometry1, geometry2, mls_output);

        if ( !vector_deque_already_tested && test_vector_and_deque )
        {
            vector_deque_already_tested = true;
#ifdef BOOST_GEOMETRY_TEST_DEBUG
            std::cout << std::endl;
            std::cout << "Testing with vector and deque as output container..."
                      << std::endl;
#endif
            bg::difference(geometry1, geometry2, ls_vector_output);
            bg::difference(geometry1, geometry2, ls_deque_output);

            BOOST_CHECK(multilinestring_equals
                        <
                            false
                        >::apply(mls_diff, ls_vector_output, tolerance));

            BOOST_CHECK(multilinestring_equals
                        <
                            false
                        >::apply(mls_diff, ls_deque_output, tolerance));

#ifdef BOOST_GEOMETRY_TEST_DEBUG
            std::cout << "Done!" << std::endl << std::endl;
#endif
        }

#ifdef BOOST_GEOMETRY_TEST_DEBUG
        std::cout << "Geometry #1: " << bg::wkt(geometry1) << std::endl;
        std::cout << "Geometry #2: " << bg::wkt(geometry2) << std::endl;
        std::cout << "difference : " << bg::wkt(mls_output) << std::endl;
        std::cout << "expected difference : " << bg::wkt(mls_diff) << std::endl;
        std::cout << std::endl;
        std::cout << "************************************" << std::endl;
        std::cout << std::endl;
        std::cout << std::endl;
#endif

        check_turn_less::apply(geometry1, geometry2);
    }
    static inline void base_test(Geometry1 const& geometry1,
                                 Geometry2 const& geometry2,
                                 MultiLineString const& mls_diff,
                                 std::string const& case_id,
                                 double tolerance,
                                 bool test_vector_and_deque = true,
                                 bool reverse_output_for_checking = false)
    {
        static bool vector_deque_already_tested = false;

        typedef typename boost::range_value<MultiLineString>::type LineString;
        typedef std::vector<LineString> linestring_vector;
        typedef std::deque<LineString> linestring_deque;

        MultiLineString mls_output;

        linestring_vector ls_vector_output;
        linestring_deque ls_deque_output;

        bg::difference(geometry1, geometry2, mls_output);

        if ( reverse_output_for_checking )
        {
            bg::reverse(mls_output);
        }

        BOOST_CHECK_MESSAGE( equals::apply(mls_diff, mls_output, tolerance),
                             "case id: " << case_id
                             << ", difference L/L: " << bg::wkt(geometry1)
                             << " " << bg::wkt(geometry2)
                             << " -> Expected: " << bg::wkt(mls_diff)
                             << std::setprecision(20)
                             << " computed: " << bg::wkt(mls_output) );

        set_operation_output("difference", case_id,
                             geometry1, geometry2, mls_output);

        if ( !vector_deque_already_tested && test_vector_and_deque )
        {
            vector_deque_already_tested = true;
#ifdef BOOST_GEOMETRY_TEST_DEBUG
            std::cout << std::endl;
            std::cout << "Testing with vector and deque as output container..."
                      << std::endl;
#endif
            bg::difference(geometry1, geometry2, ls_vector_output);
            bg::difference(geometry1, geometry2, ls_deque_output);

            BOOST_CHECK(multilinestring_equals
                        <
                        false
                        >::apply(mls_diff, ls_vector_output, tolerance));

            BOOST_CHECK(multilinestring_equals
                        <
                        false
                        >::apply(mls_diff, ls_deque_output, tolerance));

#ifdef BOOST_GEOMETRY_TEST_DEBUG
            std::cout << "Done!" << std::endl << std::endl;
#endif
        }

#ifdef BOOST_GEOMETRY_TEST_DEBUG
        std::cout << "Geometry #1: " << bg::wkt(geometry1) << std::endl;
        std::cout << "Geometry #2: " << bg::wkt(geometry2) << std::endl;
        std::cout << "difference : " << bg::wkt(mls_output) << std::endl;
        std::cout << "expected difference : " << bg::wkt(mls_diff) << std::endl;
        std::cout << std::endl;
        std::cout << "************************************" << std::endl;
        std::cout << std::endl;
        std::cout << std::endl;
#endif

        check_turn_less::apply(geometry1, geometry2);
    }
    static inline void base_test(Geometry1 const& geometry1,
                                 Geometry2 const& geometry2,
                                 MultiLineString const& mls_int1,
                                 MultiLineString const& mls_int2,
                                 std::string const& case_id,
                                 bool test_vector_and_deque = false)
    {
        static bool vector_deque_already_tested = false;

        typedef typename boost::range_value<MultiLineString>::type LineString;
        typedef std::vector<LineString> linestring_vector;
        typedef std::deque<LineString> linestring_deque;

        MultiLineString mls_output;

        linestring_vector ls_vector_output;
        linestring_deque ls_deque_output;

        bg::intersection(geometry1, geometry2, mls_output);

        BOOST_CHECK_MESSAGE( equals::apply(mls_int1, mls_output)
                             || equals::apply(mls_int2, mls_output),
                             "intersection L/L: " << bg::wkt(geometry1)
                             << " " << bg::wkt(geometry2)
                             << " -> Expected: " << bg::wkt(mls_int1)
                             << " or: " << bg::wkt(mls_int2)
                             << " computed: " << bg::wkt(mls_output) );

        set_operation_output("intersection", case_id,
                             geometry1, geometry2, mls_output);
#ifdef BOOST_GEOMETRY_TEST_DEBUG
        std::cout << "Geometry #1: " << bg::wkt(geometry1) << std::endl;
        std::cout << "Geometry #2: " << bg::wkt(geometry2) << std::endl;
        std::cout << "intersection : " << bg::wkt(mls_output) << std::endl;
        std::cout << "expected intersection : " << bg::wkt(mls_int1)
                  << std::endl;
        std::cout << std::endl;
        std::cout << "************************************" << std::endl;
        std::cout << std::endl;
        std::cout << std::endl;
#endif

        if ( !vector_deque_already_tested && test_vector_and_deque )
        {
            vector_deque_already_tested = true;
#ifdef BOOST_GEOMETRY_TEST_DEBUG
            std::cout << std::endl;
            std::cout << "Testing with vector and deque as output container..."
                      << std::endl;
#endif
            bg::intersection(geometry1, geometry2, ls_vector_output);
            bg::intersection(geometry1, geometry2, ls_deque_output);

            BOOST_CHECK(multilinestring_equals<false>::apply(mls_int1,
                        ls_vector_output));

            BOOST_CHECK(multilinestring_equals<false>::apply(mls_int1,
                        ls_deque_output));

#ifdef BOOST_GEOMETRY_TEST_DEBUG
            std::cout << "Done!" << std::endl << std::endl;
#endif
        }

        // check the intersection where the order of the two
        // geometries is reversed
        bg::clear(mls_output);
        bg::intersection(geometry2, geometry1, mls_output);

        BOOST_CHECK_MESSAGE( equals::apply(mls_int1, mls_output)
                             || equals::apply(mls_int2, mls_output),
                             "intersection L/L: " << bg::wkt(geometry1)
                             << " " << bg::wkt(geometry2)
                             << " -> Expected: " << bg::wkt(mls_int1)
                             << " or: " << bg::wkt(mls_int2)
                             << " computed: " << bg::wkt(mls_output) );

#ifdef BOOST_GEOMETRY_TEST_DEBUG
        std::cout << "Geometry #1: " << bg::wkt(geometry2) << std::endl;
        std::cout << "Geometry #2: " << bg::wkt(geometry1) << std::endl;
        std::cout << "intersection : " << bg::wkt(mls_output) << std::endl;
        std::cout << "expected intersection : " << bg::wkt(mls_int2)
                  << std::endl;
        std::cout << std::endl;
        std::cout << "************************************" << std::endl;
        std::cout << std::endl;
        std::cout << std::endl;
#endif
    }