[geos-commits] [SCM] GEOS branch master updated. 52aba2ca24177acc5ceecbcfb8e47d41d45c034b

git at osgeo.org git at osgeo.org
Thu Nov 29 14:22:10 PST 2018


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GEOS".

The branch, master has been updated
       via  52aba2ca24177acc5ceecbcfb8e47d41d45c034b (commit)
      from  2ff10b8e4536e8fb430d2de9e80f5b2075a4ed8e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 52aba2ca24177acc5ceecbcfb8e47d41d45c034b
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date:   Thu Nov 29 14:21:26 2018 -0800

    Add the JTS ./validate XML tests.
    Reorganize the order of XML tests in build files
    to match sort order. Update the xml tester
    to handle the operations in the validate
    tests.

diff --git a/tests/xmltester/CMakeLists.txt b/tests/xmltester/CMakeLists.txt
index d68189f..2f3e299 100644
--- a/tests/xmltester/CMakeLists.txt
+++ b/tests/xmltester/CMakeLists.txt
@@ -128,6 +128,15 @@ if(GEOS_ENABLE_TESTS)
     ${XMLTESTS_DIR}/ticket/bug615.xml
     ${XMLTESTS_DIR}/ticket/bug716.xml
     ${XMLTESTS_DIR}/ticket/bug837.xml
+    ${XMLTESTS_DIR}/validate/TestRelateAA-big.xml
+    ${XMLTESTS_DIR}/validate/TestRelateAA.xml
+    ${XMLTESTS_DIR}/validate/TestRelateAC.xml
+    ${XMLTESTS_DIR}/validate/TestRelateLA.xml
+    ${XMLTESTS_DIR}/validate/TestRelateLC.xml
+    ${XMLTESTS_DIR}/validate/TestRelateLL.xml
+    ${XMLTESTS_DIR}/validate/TestRelatePA.xml
+    ${XMLTESTS_DIR}/validate/TestRelatePL.xml
+    ${XMLTESTS_DIR}/validate/TestRelatePP.xml
     )
 
   set(FAILING_XMLTESTS
diff --git a/tests/xmltester/Makefile.am b/tests/xmltester/Makefile.am
index 61017b7..e38f00b 100644
--- a/tests/xmltester/Makefile.am
+++ b/tests/xmltester/Makefile.am
@@ -13,53 +13,39 @@ CLEANFILES = testrunner
 
 EXTRA_DIST = testrunner.sh CMakeLists.txt
 
-SAFE_XMLTESTS=$(srcdir)/tests/testLeaksBig.xml \
-	$(srcdir)/tests/split.xml \
+SAFE_XMLTESTS= \
+	$(srcdir)/tests/TestBufferExternal.xml \
+	$(srcdir)/tests/TestBufferExternal2.xml \
+	$(srcdir)/tests/TestIsValid.xml \
+	$(srcdir)/tests/badguy3.xml \
+	$(srcdir)/tests/buffer.xml \
+	$(srcdir)/tests/fme.xml \
+	$(srcdir)/tests/heisenbugs.xml \
 	$(srcdir)/tests/hexwkb.xml \
-	$(srcdir)/tests/test.xml \
+	$(srcdir)/tests/hole_from_shell.xml \
+	$(srcdir)/tests/hole_red.xml \
 	$(srcdir)/tests/linemerge.xml \
-	$(srcdir)/tests/TestIsValid.xml \
 	$(srcdir)/tests/robustness.xml \
-	$(srcdir)/tests/buffer.xml \
 	$(srcdir)/tests/singlesidedbuffer.xml \
-	$(srcdir)/tests/ticket/bug176.xml \
-	$(srcdir)/tests/ticket/bug188.xml \
-	$(srcdir)/tests/ticket/bug244.xml \
-	$(srcdir)/tests/ticket/bug275.xml \
-	$(srcdir)/tests/ticket/bug350.xml \
-	$(srcdir)/tests/ticket/bug356.xml \
-	$(srcdir)/tests/ticket/bug358.xml \
-	$(srcdir)/tests/ticket/bug360.xml \
-	$(srcdir)/tests/ticket/bug366.xml \
-	$(srcdir)/tests/ticket/bug392.xml \
-	$(srcdir)/tests/ticket/bug398.xml \
-	$(srcdir)/tests/ticket/bug434.xml \
-	$(srcdir)/tests/ticket/bug459.xml \
-	$(srcdir)/tests/ticket/bug527.xml \
-	$(srcdir)/tests/ticket/bug569.xml \
-	$(srcdir)/tests/ticket/bug582.xml \
-	$(srcdir)/tests/ticket/bug586.xml \
-	$(srcdir)/tests/ticket/bug599.xml \
-	$(srcdir)/tests/ticket/bug605.xml \
-	$(srcdir)/tests/ticket/bug615.xml \
-	$(srcdir)/tests/ticket/bug716.xml \
-	$(srcdir)/tests/ticket/bug837.xml \
+	$(srcdir)/tests/split.xml \
+	$(srcdir)/tests/test.xml \
+	$(srcdir)/tests/testLeaksBig.xml \
 	$(srcdir)/tests/general/TestBoundary.xml \
 	$(srcdir)/tests/general/TestBuffer.xml \
 	$(srcdir)/tests/general/TestBufferMitredJoin.xml \
 	$(srcdir)/tests/general/TestCentroid.xml \
-	$(srcdir)/tests/general/TestConvexHull.xml \
 	$(srcdir)/tests/general/TestConvexHull-big.xml \
+	$(srcdir)/tests/general/TestConvexHull.xml \
 	$(srcdir)/tests/general/TestDistance.xml \
-	$(srcdir)/tests/general/TestFunctionAAPrec.xml \
 	$(srcdir)/tests/general/TestFunctionAA.xml \
-	$(srcdir)/tests/general/TestFunctionLAPrec.xml \
+	$(srcdir)/tests/general/TestFunctionAAPrec.xml \
 	$(srcdir)/tests/general/TestFunctionLA.xml \
-	$(srcdir)/tests/general/TestFunctionLLPrec.xml \
+	$(srcdir)/tests/general/TestFunctionLAPrec.xml \
 	$(srcdir)/tests/general/TestFunctionLL.xml \
+	$(srcdir)/tests/general/TestFunctionLLPrec.xml \
 	$(srcdir)/tests/general/TestFunctionPA.xml \
-	$(srcdir)/tests/general/TestFunctionPLPrec.xml \
 	$(srcdir)/tests/general/TestFunctionPL.xml \
+	$(srcdir)/tests/general/TestFunctionPLPrec.xml \
 	$(srcdir)/tests/general/TestFunctionPP.xml \
 	$(srcdir)/tests/general/TestInteriorPoint.xml \
   $(srcdir)/tests/general/TestPreparedPointPredicate.xml \
@@ -67,35 +53,59 @@ SAFE_XMLTESTS=$(srcdir)/tests/testLeaksBig.xml \
   $(srcdir)/tests/general/TestPreparedPredicatesWithGeometryCollection.xml \
 	$(srcdir)/tests/general/TestRectanglePredicate.xml \
 	$(srcdir)/tests/general/TestRelateAA.xml \
-	$(srcdir)/tests/general/TestRelateLA.xml \
-	$(srcdir)/tests/general/TestRelateLL.xml \
-	$(srcdir)/tests/general/TestRelatePL.xml \
 	$(srcdir)/tests/general/TestRelateAC.xml \
+	$(srcdir)/tests/general/TestRelateLA.xml \
 	$(srcdir)/tests/general/TestRelateLC.xml \
+	$(srcdir)/tests/general/TestRelateLL.xml \
 	$(srcdir)/tests/general/TestRelatePA.xml \
+	$(srcdir)/tests/general/TestRelatePL.xml \
 	$(srcdir)/tests/general/TestRelatePP.xml \
 	$(srcdir)/tests/general/TestSimple.xml \
 	$(srcdir)/tests/general/TestUnaryUnion.xml \
 	$(srcdir)/tests/general/TestUnaryUnionFloating.xml \
 	$(srcdir)/tests/general/TestValid.xml \
-	$(srcdir)/tests/general/TestValid2.xml \
 	$(srcdir)/tests/general/TestValid2-big.xml \
+	$(srcdir)/tests/general/TestValid2.xml \
 	$(srcdir)/tests/general/TestWithinDistance.xml \
-	$(srcdir)/tests/stmlf/stmlf-cases-20061020.xml \
-	$(srcdir)/tests/stmlf/stmlf-cases-20061020-invalid-output.xml \
-	$(srcdir)/tests/stmlf/stmlf-cases-20070119.xml \
 	$(srcdir)/tests/robust/TestRobustOverlayFixed.xml \
 	$(srcdir)/tests/robust/TestRobustRelate.xml \
-	$(srcdir)/tests/fme.xml \
-	$(srcdir)/tests/TestBufferExternal.xml \
-	$(srcdir)/tests/TestBufferExternal2.xml \
-	$(srcdir)/tests/heisenbugs.xml \
-	$(srcdir)/tests/badguy3.xml \
-	$(srcdir)/tests/hole_from_shell.xml \
-	$(srcdir)/tests/hole_red.xml \
 	$(srcdir)/tests/safe/16595.xml \
 	$(srcdir)/tests/safe/16596.xml \
-	$(srcdir)/tests/safe/TestBufferJagged.xml
+	$(srcdir)/tests/safe/TestBufferJagged.xml \
+	$(srcdir)/tests/stmlf/stmlf-cases-20061020-invalid-output.xml \
+	$(srcdir)/tests/stmlf/stmlf-cases-20061020.xml \
+	$(srcdir)/tests/stmlf/stmlf-cases-20070119.xml \
+	$(srcdir)/tests/ticket/bug176.xml \
+	$(srcdir)/tests/ticket/bug188.xml \
+	$(srcdir)/tests/ticket/bug244.xml \
+	$(srcdir)/tests/ticket/bug275.xml \
+	$(srcdir)/tests/ticket/bug350.xml \
+	$(srcdir)/tests/ticket/bug356.xml \
+	$(srcdir)/tests/ticket/bug358.xml \
+	$(srcdir)/tests/ticket/bug360.xml \
+	$(srcdir)/tests/ticket/bug366.xml \
+	$(srcdir)/tests/ticket/bug392.xml \
+	$(srcdir)/tests/ticket/bug398.xml \
+	$(srcdir)/tests/ticket/bug434.xml \
+	$(srcdir)/tests/ticket/bug459.xml \
+	$(srcdir)/tests/ticket/bug527.xml \
+	$(srcdir)/tests/ticket/bug569.xml \
+	$(srcdir)/tests/ticket/bug582.xml \
+	$(srcdir)/tests/ticket/bug586.xml \
+	$(srcdir)/tests/ticket/bug599.xml \
+	$(srcdir)/tests/ticket/bug605.xml \
+	$(srcdir)/tests/ticket/bug615.xml \
+	$(srcdir)/tests/ticket/bug716.xml \
+	$(srcdir)/tests/ticket/bug837.xml \
+	$(srcdir)/tests/validate/TestRelateAA-big.xml \
+	$(srcdir)/tests/validate/TestRelateAA.xml \
+	$(srcdir)/tests/validate/TestRelateAC.xml \
+	$(srcdir)/tests/validate/TestRelateLA.xml \
+	$(srcdir)/tests/validate/TestRelateLC.xml \
+	$(srcdir)/tests/validate/TestRelateLL.xml \
+	$(srcdir)/tests/validate/TestRelatePA.xml \
+	$(srcdir)/tests/validate/TestRelatePL.xml \
+	$(srcdir)/tests/validate/TestRelatePP.xml
 
 INVALID_OUTPUT_XMLTESTS =
 
diff --git a/tests/xmltester/XMLTester.cpp b/tests/xmltester/XMLTester.cpp
index 626ec62..3ad7e53 100644
--- a/tests/xmltester/XMLTester.cpp
+++ b/tests/xmltester/XMLTester.cpp
@@ -949,6 +949,21 @@ XMLTester::parseTest(const tinyxml2::XMLNode* node)
             if (actual_result==opRes) success=1;
         }
 
+        else if (opName=="overlaps")
+        {
+            geom::Geometry *g1 = opArg1 == "B" ? gB : gA;
+            geom::Geometry *g2 = opArg2 == "B" ? gB : gA;
+
+            actual_result="false";
+            if ( usePrepared )
+            {
+                if ( prepare(g1)->overlaps(g2) ) actual_result="true";
+            }
+            else if (g1->overlaps(g2)) actual_result="true";
+
+            if (actual_result==opRes) success=1;
+        }
+
         else if (opName=="within")
         {
             geom::Geometry *g1 = opArg1 == "B" ? gB : gA;
@@ -964,6 +979,51 @@ XMLTester::parseTest(const tinyxml2::XMLNode* node)
             if (actual_result==opRes) success=1;
         }
 
+        else if (opName=="touches")
+        {
+            geom::Geometry *g1 = opArg1 == "B" ? gB : gA;
+            geom::Geometry *g2 = opArg2 == "B" ? gB : gA;
+
+            actual_result="false";
+            if ( usePrepared )
+            {
+                if ( prepare(g1)->touches(g2) ) actual_result="true";
+            }
+            else if (g1->touches(g2)) actual_result="true";
+
+            if (actual_result==opRes) success=1;
+        }
+
+        else if (opName=="crosses")
+        {
+            geom::Geometry *g1 = opArg1 == "B" ? gB : gA;
+            geom::Geometry *g2 = opArg2 == "B" ? gB : gA;
+
+            actual_result="false";
+            if ( usePrepared )
+            {
+                if ( prepare(g1)->crosses(g2) ) actual_result="true";
+            }
+            else if (g1->crosses(g2)) actual_result="true";
+
+            if (actual_result==opRes) success=1;
+        }
+
+        else if (opName=="disjoint")
+        {
+            geom::Geometry *g1 = opArg1 == "B" ? gB : gA;
+            geom::Geometry *g2 = opArg2 == "B" ? gB : gA;
+
+            actual_result="false";
+            if ( usePrepared )
+            {
+                if ( prepare(g1)->disjoint(g2) ) actual_result="true";
+            }
+            else if (g1->disjoint(g2)) actual_result="true";
+
+            if (actual_result==opRes) success=1;
+        }
+
         else if (opName=="covers")
         {
             geom::Geometry *g1 = opArg1 == "B" ? gB : gA;
@@ -979,6 +1039,18 @@ XMLTester::parseTest(const tinyxml2::XMLNode* node)
             if (actual_result==opRes) success=1;
         }
 
+        // equalsTopo() is synomym for equals() in JTS
+        else if (opName=="equalstopo")
+        {
+            geom::Geometry *g1 = opArg1 == "B" ? gB : gA;
+            geom::Geometry *g2 = opArg2 == "B" ? gB : gA;
+
+            actual_result="false";
+            if (g1->equals(g2)) actual_result="true";
+
+            if (actual_result==opRes) success=1;
+        }
+
         else if (opName=="coveredby")
         {
             geom::Geometry *g1 = opArg1 == "B" ? gB : gA;
diff --git a/tests/xmltester/tests/validate/TestRelateAA-big.xml b/tests/xmltester/tests/validate/TestRelateAA-big.xml
new file mode 100644
index 0000000..2d8e9c6
--- /dev/null
+++ b/tests/xmltester/tests/validate/TestRelateAA-big.xml
@@ -0,0 +1,34 @@
+<run>
+<precisionModel type="FLOATING"/>
+
+<case>
+<desc>A/A-6-18: a polygon overlapping a very skinny polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.V-EP = B.A.Bdy.NV-EP}, dim(0){A.A.Bdy.CP = B.A.Bdy.CP}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (100 100, 100 200, 200 200, 200 100, 100 100))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 1000000000000000 110, 1000000000000000 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212111212">true</op>
+  </test>
+</case>
+
+<case>
+<desc>A/A-6-24: a polygon overlapping a very skinny polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.V-EP = B.A.Bdy.NV-NV}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (120 100, 120 200, 200 200, 200 100, 120 100))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 1000000000000000 110, 1000000000000000 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212111212">true</op>
+  </test>
+</case>
+
+</run>
diff --git a/tests/xmltester/tests/validate/TestRelateAA.xml b/tests/xmltester/tests/validate/TestRelateAA.xml
new file mode 100644
index 0000000..bb9c3ea
--- /dev/null
+++ b/tests/xmltester/tests/validate/TestRelateAA.xml
@@ -0,0 +1,2833 @@
+<run>
+<precisionModel type="FLOATING"/>
+
+<case>
+<desc>A/A-1-1: same polygons [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.SP-EP = B.A.Bdy.SP-EP}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 100, 120 100, 140 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 20, 20 100, 120 100, 140 20, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="2FFF1FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>A/A-1-2: same polygons with reverse sequence of points [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.SP-EP = B.A.Bdy.EP-SP}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 100, 120 100, 140 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 20, 140 20, 120 100, 20 100, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="2FFF1FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>A/A-1-3: same polygons with different sequence of points [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.SP-EP = B.A.Bdy.SP-EP}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 100, 120 100, 140 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (120 100, 140 20, 20 20, 20 100, 120 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="2FFF1FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>A/A-1-4: same polygons with different number of points [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.SP-EP = B.A.Bdy.SP-EP}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 100, 120 100, 140 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 100, 60 100, 120 100, 140 20, 80 20, 20 20, 20 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="2FFF1FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>A/A-2: different polygons [dim(2){A.A.Int = B.A.Ext}]</desc>
+  <a>
+    POLYGON(
+      (0 0, 80 0, 80 80, 0 80, 0 0))
+  </a>
+  <b>
+    POLYGON(
+      (100 200, 100 140, 180 140, 180 200, 100 200))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2FF1212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-1-1: the closing point of a polygon touching the closing point of another polygon [dim(0){A.A.Bdy.CP = B.A.Bdy.CP}]</desc>
+  <a>
+    POLYGON(
+      (140 120, 160 20, 20 20, 20 120, 140 120))
+  </a>
+  <b>
+    POLYGON(
+      (140 120, 140 200, 240 200, 240 120, 140 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-1-2: the closing point of a polygon touching the boundary (at a non-vertex) of another polygon [dim(0){A.A.Bdy.CP = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (140 120, 160 20, 20 20, 20 120, 140 120))
+  </a>
+  <b>
+    POLYGON(
+      (80 180, 140 260, 260 200, 200 60, 80 180))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-1-3: the closing point of a polygon touching the boundary (at a vertex) of another polygon [dim(0){A.A.Bdy.CP = B.A.Bdy.V}]</desc>
+  <a>
+    POLYGON(
+      (140 120, 160 20, 20 20, 20 120, 140 120))
+  </a>
+  <b>
+    POLYGON(
+      (240 80, 140 120, 180 240, 280 200, 240 80))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-1-4: the boundary (at a non-vertex) of a polygon touching the closing point of another polygon [dim(0){A.A.Bdy.NV = B.A.Bdy.CP}]</desc>
+  <a>
+    POLYGON(
+      (140 160, 20 20, 270 20, 150 160, 230 40, 60 40, 140 160))
+  </a>
+  <b>
+    POLYGON(
+      (140 40, 180 80, 120 100, 140 40))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-1-5: the boundary (at a non-vertex) of a polygon touching the boundary (at a vertex) of another polygon [dim(0){A.A.Bdy.NV = B.A.Bdy.V}]</desc>
+  <a>
+    POLYGON(
+      (140 160, 20 20, 270 20, 150 160, 230 40, 60 40, 140 160))
+  </a>
+  <b>
+    POLYGON(
+      (120 100, 180 80, 130 40, 120 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-1-6: the boundary (at a vertex) of a polygon touching the boundary (at a non-vertex) of another polygon [dim(0){A.A.Bdy.V = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 180 20, 140 140, 20 140, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (180 100, 80 200, 180 280, 260 200, 180 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-1-7: the boundary (at a vertex) of a polygon touching the boundary (at a vertex) of another polygon [dim(0){A.A.Bdy.V = B.A.Bdy.V}]</desc>
+  <a>
+    POLYGON(
+      (140 120, 160 20, 20 20, 20 120, 140 120))
+  </a>
+  <b>
+    POLYGON(
+      (140 140, 20 120, 0 220, 120 240, 140 140))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-2-1: two polygons touching at multiple points [dim(0){A.A.Bdy.CP = B.A.Bdy.CP}, dim(0){A.A.Bdy.V = B.A.Bdy.V}]</desc>
+  <a>
+    POLYGON(
+      (20 120, 20 20, 260 20, 260 120, 200 40, 140 120, 80 40, 20 120))
+  </a>
+  <b>
+    POLYGON(
+      (20 120, 20 240, 260 240, 260 120, 200 200, 140 120, 80 200, 20 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-2-2: two polygons touching at multiple points [dim(0){A.A.Bdy.CP = B.A.Bdy.CP}, dim(0){A.A.Bdy.V = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (20 120, 20 20, 260 20, 260 120, 180 40, 140 120, 100 40, 20 120))
+  </a>
+  <b>
+    POLYGON(
+      (20 120, 300 120, 140 240, 20 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-2-3: two polygons touching at multiple points [dim(0){A.A.Bdy.CP = B.A.Bdy.NV}, dim(0){A.A.Bdy.V = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 300, 280 300, 280 260, 220 260, 60 100, 60 60, 280 60, 280 20, 
+      20 20))
+  </a>
+  <b>
+    POLYGON(
+      (100 140, 160 80, 280 180, 200 240, 220 160, 160 200, 180 120, 100 140))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-2-4: two polygons touching at multiple points [dim(0){A.A.Bdy.V = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 300, 280 300, 280 260, 220 260, 60 100, 60 60, 280 60, 280 20, 
+      20 20))
+  </a>
+  <b>
+    POLYGON(
+      (260 200, 180 80, 120 160, 200 160, 180 220, 260 200))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-2-5: two polygons touching at multiple points [dim(0){A.A.Bdy.V = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 280 20, 280 140, 220 60, 140 140, 80 60, 20 140, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (0 140, 300 140, 140 240, 0 140))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-2-6: two polygons touching at multiple points [dim(0){A.A.Bdy.V = B.A.Bdy.V}, dim(0){A.A.Bdy.V = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 280 20, 280 140, 220 60, 140 140, 80 60, 20 140, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 240, 20 140, 320 140, 180 240, 20 240))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-2-7: two polygons touching at multiple points [dim(0){A.A.Bdy.V = B.A.Bdy.V}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 280 20, 280 140, 220 60, 140 140, 80 60, 20 140, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 240, 20 140, 80 180, 140 140, 220 180, 280 140, 280 240, 20 240))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-3-1: two polygons touching along a boundary [dim(1){A.A.Bdy.SP-V = B.A.Bdy.SP-NV}]</desc>
+  <a>
+    POLYGON(
+      (120 120, 180 60, 20 20, 20 120, 120 120))
+  </a>
+  <b>
+    POLYGON(
+      (120 120, 220 20, 280 20, 240 160, 120 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-3-2: two polygons touching along a boundary [dim(1){A.A.Bdy.SP-V = B.A.Bdy.SP-V}]</desc>
+  <a>
+    POLYGON(
+      (140 120, 160 20, 20 20, 20 120, 140 120))
+  </a>
+  <b>
+    POLYGON(
+      (140 120, 160 20, 260 120, 220 200, 140 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-3-3: two polygons touching along a boundary [dim(1){A.A.Bdy.SP-V = B.A.Bdy.NV-V}]</desc>
+  <a>
+    POLYGON(
+      (20 140, 120 40, 20 40, 20 140))
+  </a>
+  <b>
+    POLYGON(
+      (190 140, 190 20, 140 20, 20 140, 190 140))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-3-4: two polygons touching along a boundary [dim(1){A.A.Bdy.SP-V = B.A.Bdy.NV-V}]</desc>
+  <a>
+    POLYGON(
+      (120 120, 180 60, 20 20, 20 120, 120 120))
+  </a>
+  <b>
+    POLYGON(
+      (300 20, 220 20, 120 120, 260 160, 300 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-3-5: two polygons touching along a boundary [dim(1){A.A.Bdy.SP-V = B.A.Bdy.V-EP}]</desc>
+  <a>
+    POLYGON(
+      (140 120, 160 20, 20 20, 20 120, 140 120))
+  </a>
+  <b>
+    POLYGON(
+      (140 120, 240 160, 280 60, 160 20, 140 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-3-6: two polygons touching along a boundary [dim(1){A.A.Bdy.SP-V = B.A.Bdy.V-V}]</desc>
+  <a>
+    POLYGON(
+      (120 120, 180 60, 20 20, 20 120, 120 120))
+  </a>
+  <b>
+    POLYGON(
+      (280 60, 180 60, 120 120, 260 180, 280 60))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-3-7: two polygons touching along a boundary [dim(1){A.A.Bdy.NV-NV = B.A.Bdy.V-V}]</desc>
+  <a>
+    POLYGON(
+      (140 120, 160 20, 20 20, 20 120, 140 120))
+  </a>
+  <b>
+    POLYGON(
+      (120 200, 120 120, 40 120, 40 200, 120 200))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-3-8: two polygons touching along a boundary [dim(1){A.A.Bdy.NV-EP = B.A.Bdy.V-V}]</desc>
+  <a>
+    POLYGON(
+      (140 120, 160 20, 20 20, 20 120, 140 120))
+  </a>
+  <b>
+    POLYGON(
+      (160 220, 140 120, 60 120, 40 220, 160 220))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-3-9: two polygons touching along a boundary [dim(1){A.A.Bdy.V-EP = B.A.Bdy.V-SP}]</desc>
+  <a>
+    POLYGON(
+      (140 120, 160 20, 20 20, 20 120, 140 120))
+  </a>
+  <b>
+    POLYGON(
+      (140 120, 20 120, 20 220, 140 220, 140 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-3-3-10: two polygons touching along a boundary [dim(1){A.A.Bdy.V-V = B.A.Bdy.NV-NV}]</desc>
+  <a>
+    POLYGON(
+      (120 120, 180 60, 20 20, 20 120, 120 120))
+  </a>
+  <b>
+    POLYGON(
+      (320 20, 220 20, 80 160, 240 140, 320 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-1: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.SP-EP = B.A.Int}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (60 40, 60 140, 180 140, 180 40, 60 40))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212FF1FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-2-1: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.CP = B.A.Bdy.CP}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 20, 80 140, 160 60, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F01FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-2-2: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.CP = B.A.Bdy.V}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (160 60, 20 20, 100 140, 160 60))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F01FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-2-3: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.NV = B.A.Bdy.CP}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 100, 140 160, 160 40, 20 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F01FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-2-4: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.NV = B.A.Bdy.V}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (160 40, 20 100, 160 160, 160 40))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F01FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-2-5: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.V = B.A.Bdy.CP}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 180, 180 120, 80 40, 20 180))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F01FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-2-6: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.V = B.A.Bdy.V}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (180 120, 100 40, 20 180, 180 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F01FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-3-1: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.CP = B.A.Bdy.CP}, dim(0){A.A.Bdy.NV = B.A.Bdy.V}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 20, 140 40, 140 120, 20 160, 80 80, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F01FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-3-2: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.CP = B.A.Bdy.CP}, dim(0){A.A.Bdy.V = B.A.Bdy.V}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 20, 140 40, 140 140, 20 180, 80 100, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F01FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-3-3: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.NV = B.A.Bdy.V}, dim(0){A.A.Bdy.NV = B.A.Bdy.V}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (40 180, 60 100, 180 100, 200 180, 120 120, 40 180))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F01FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-3-4: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.V = B.A.Bdy.CP}, dim(0){A.A.Bdy.V = B.A.Bdy.V}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 180, 60 80, 180 80, 220 180, 120 120, 20 180))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F01FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-3-5: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.V = B.A.Bdy.V}, dim(0){A.A.Bdy.NV = B.A.Bdy.V}, dim(0){A.A.Bdy.NV = B.A.Bdy.V}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (40 60, 20 180, 100 100, 140 180, 160 120, 220 100, 140 40, 40 60))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F01FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-3-6: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.V = B.A.Bdy.V}, dim(0){A.A.Bdy.V = B.A.Bdy.V}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (60 100, 180 100, 220 180, 120 140, 20 180, 60 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F01FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-4-1: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.SP-NV = B.A.Bdy.SP-V}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 20, 20 140, 120 120, 120 40, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F11FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-4-2: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.SP-V = B.A.Bdy.SP-V)}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 20, 20 180, 140 140, 140 60, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F11FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-4-3: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.SP-NV = B.A.Bdy.V-EP}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 20, 120 40, 120 120, 20 140, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F11FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-4-4: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.SP-NV = B.A.Bdy.V-V}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (120 40, 20 20, 20 140, 120 120, 120 40))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F11FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-4-5: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.SP-V = B.A.Bdy.V-EP}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 20, 140 60, 140 140, 20 180, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F11FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-4-6: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.SP-V = B.A.Bdy.V-V}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (140 60, 20 20, 20 180, 140 140, 140 60))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F11FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-4-7: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.NV-EP = B.A.Bdy.V-EP}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 20, 60 120, 140 120, 180 20, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F11FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-4-8: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.NV-NV = B.A.Bdy.V-EP}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 40, 120 40, 120 120, 20 140, 20 40))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F11FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-5-5-1: a polygon containing another polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.SP-V = B.A.Bdy.SP-V},  dim(1){A.A.Bdy.(NV, V) = B.A.Bdy.(V, V)}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 20 180, 220 180, 220 20, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (20 20, 20 180, 60 120, 100 180, 140 120, 220 180, 200 120, 140 60, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212F11FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-1: a polygon overlapping another polygon [dim(2){A.A.Int = B.A.Int}]</desc>
+  <a>
+    POLYGON(
+      (150 150, 330 150, 250 70, 70 70, 150 150))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 270 150, 140 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212111212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-2: a polygon overlapping another polygon [dim(2){A.A.Int = B.A.Int}]</desc>
+  <a>
+    POLYGON(
+      (150 150, 270 150, 330 150, 250 70, 190 70, 70 70, 150 150))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 270 150, 190 70, 140 20, 20 20, 70 70, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212111212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-3: spiky polygons overlapping; boundary <-> boundary intersecting at 0 dimension [dim(2){A.A.Int = B.A.Int}]</desc>
+  <a>
+    POLYGON(
+      (20 20, 60 50, 20 40, 60 70, 20 60, 60 90, 20 90, 70 110, 20 130, 
+      80 130, 20 150, 80 160, 20 170, 80 180, 20 200, 80 200, 30 240, 80 220, 50 260, 
+      100 220, 100 260, 120 220, 130 260, 140 220, 150 280, 150 190, 160 280, 170 190, 180 280, 
+      190 190, 200 280, 210 190, 220 280, 230 190, 240 260, 250 230, 260 260, 260 220, 290 270, 
+      290 220, 330 260, 300 210, 340 240, 290 180, 340 210, 290 170, 350 170, 240 150, 350 150, 
+      240 140, 350 130, 240 120, 350 120, 240 110, 350 110, 240 100, 350 100, 240 90, 350 90, 
+      240 80, 350 80, 300 70, 340 60, 290 60, 340 40, 300 50, 340 20, 270 60, 310 20, 
+      250 60, 270 20, 230 60, 240 20, 210 60, 210 20, 190 70, 190 20, 180 90, 170 20, 
+      160 90, 150 20, 140 90, 130 20, 120 90, 110 20, 100 90, 100 20, 90 60, 80 20, 
+      70 40, 20 20))
+  </a>
+  <b>
+    POLYGON(
+      (190 140, 140 130, 200 160, 130 150, 210 170, 130 170, 210 180, 120 190, 220 200, 
+      120 200, 250 210, 120 210, 250 220, 120 220, 250 230, 120 240, 230 240, 120 250, 240 260, 
+      120 260, 240 270, 120 270, 270 290, 120 290, 230 300, 150 310, 250 310, 180 320, 250 320, 
+      200 360, 260 330, 240 360, 280 320, 290 370, 290 320, 320 360, 310 320, 360 360, 310 310, 
+      380 340, 310 290, 390 330, 310 280, 410 310, 310 270, 420 280, 310 260, 430 250, 300 250, 
+      440 240, 300 240, 450 230, 280 220, 440 220, 280 210, 440 210, 300 200, 430 190, 300 190, 
+      440 180, 330 180, 430 150, 320 180, 420 130, 300 180, 410 120, 280 180, 400 110, 280 170, 
+      390 90, 280 160, 400 70, 270 160, 450 30, 260 160, 420 30, 250 160, 390 30, 240 160, 
+      370 30, 230 160, 360 30, 230 150, 330 50, 240 130, 330 30, 230 130, 310 30, 220 130, 
+      280 30, 230 100, 270 40, 220 110, 250 30, 210 130, 240 30, 210 100, 220 40, 200 90, 
+      200 20, 190 100, 180 30, 20 20, 180 40, 20 30, 180 50, 20 50, 180 60, 30 60, 
+      180 70, 20 70, 170 80, 80 80, 170 90, 20 80, 180 100, 40 100, 200 110, 60 110, 
+      200 120, 120 120, 190 140))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212101212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-4: spiky polygons overlapping; boundary <-> boundary intersecting at 1 dimension at a few locations [dim(2){A.A.Int = B.A.Int}]</desc>
+  <a>
+    POLYGON(
+      (70 150, 20 160, 110 160, 20 180, 100 200, 20 200, 190 210, 20 210, 160 220, 
+      20 220, 150 230, 60 240, 180 250, 20 260, 170 260, 60 270, 160 270, 100 310, 170 280, 
+      200 260, 180 230, 210 260, 130 330, 230 250, 210 290, 240 250, 230 210, 260 300, 250 230, 
+      270 300, 270 240, 300 340, 280 250, 320 330, 290 250, 340 350, 290 240, 350 360, 270 190, 
+      350 340, 290 200, 350 330, 300 190, 360 320, 310 190, 360 300, 320 200, 360 280, 330 200, 
+      360 260, 340 200, 370 260, 340 180, 390 290, 340 170, 400 260, 350 170, 400 250, 350 160, 
+      410 240, 350 150, 400 170, 350 140, 310 170, 340 140, 270 180, 330 140, 260 170, 310 140, 
+      240 170, 290 140, 200 190, 270 140, 180 190, 260 140, 170 190, 260 130, 170 180, 250 130, 
+      170 170, 240 120, 170 160, 210 120, 170 150, 210 110, 340 130, 230 110, 420 140, 220 100, 
+      410 130, 220 90, 400 120, 220 80, 390 110, 220 70, 420 110, 240 70, 420 100, 260 70, 
+      420 90, 280 70, 430 80, 230 60, 430 60, 270 50, 450 40, 210 50, 370 40, 260 40, 
+      460 30, 160 40, 210 60, 200 110, 190 60, 190 120, 170 50, 180 130, 150 30, 170 130, 
+      140 20, 160 120, 130 20, 160 150, 120 20, 160 170, 110 20, 160 190, 100 20, 150 190, 
+      90 20, 140 180, 80 20, 120 140, 70 20, 120 150, 60 20, 110 150, 50 20, 100 140, 
+      50 30, 90 130, 40 30, 80 120, 30 30, 80 130, 30 40, 80 140, 20 40, 70 140, 
+      40 90, 60 130, 20 90, 60 140, 20 130, 70 150))
+  </a>
+  <b>
+    POLYGON(
+      (190 140, 140 130, 200 160, 130 150, 210 170, 130 170, 210 180, 120 190, 220 200, 
+      120 200, 250 210, 120 210, 250 220, 120 220, 250 230, 120 240, 230 240, 120 250, 240 260, 
+      120 260, 240 270, 120 270, 270 290, 120 290, 230 300, 150 310, 250 310, 180 320, 250 320, 
+      200 360, 260 330, 240 360, 280 320, 290 370, 290 320, 320 360, 310 320, 360 360, 310 310, 
+      380 340, 310 290, 390 330, 310 280, 410 310, 310 270, 420 280, 310 260, 430 250, 300 250, 
+      440 240, 300 240, 450 230, 280 220, 440 220, 280 210, 440 210, 300 200, 430 190, 300 190, 
+      440 180, 330 180, 430 150, 320 180, 420 130, 300 180, 410 120, 280 180, 400 110, 280 170, 
+      390 90, 280 160, 400 70, 270 160, 450 30, 260 160, 420 30, 250 160, 390 30, 240 160, 
+      370 30, 230 160, 360 30, 230 150, 330 50, 240 130, 330 30, 230 130, 310 30, 220 130, 
+      280 30, 230 100, 270 40, 220 110, 250 30, 210 130, 240 30, 210 100, 220 40, 200 90, 
+      200 20, 190 100, 180 30, 20 20, 180 40, 20 30, 180 50, 20 50, 180 60, 30 60, 
+      180 70, 20 70, 170 80, 80 80, 170 90, 20 80, 180 100, 40 100, 200 110, 60 110, 
+      200 120, 120 120, 190 140))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212111212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-5: a polygon overlapping another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.CP = B.A.Bdy.CP}, dim(0){A.A.Bdy.V = B.A.Bdy.V}]</desc>
+  <a>
+    POLYGON(
+      (60 160, 220 160, 220 20, 60 20, 60 160))
+  </a>
+  <b>
+    POLYGON(
+      (60 160, 20 200, 260 200, 220 160, 140 80, 60 160))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212101212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-6: a polygon overlapping another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.CP = B.A.Bdy.CP}, dim(0){A.A.Bdy.V = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (60 160, 220 160, 220 20, 60 20, 60 160))
+  </a>
+  <b>
+    POLYGON(
+      (60 160, 20 200, 260 200, 140 80, 60 160))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212101212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-7: a polygon overlapping another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.CP = B.A.Bdy.NV}, dim(0){A.A.Bdy.V = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (60 160, 220 160, 220 20, 60 20, 60 160))
+  </a>
+  <b>
+    POLYGON(
+      (20 200, 140 80, 260 200, 20 200))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212101212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-8: a polygon overlapping another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.CP = B.A.Bdy.V}, dim(0){A.A.Bdy.V = B.A.Bdy.V}]</desc>
+  <a>
+    POLYGON(
+      (60 160, 220 160, 220 20, 60 20, 60 160))
+  </a>
+  <b>
+    POLYGON(
+      (20 200, 60 160, 140 80, 220 160, 260 200, 20 200))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212101212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-9: a polygon overlapping another polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.CP = B.A.Bdy.V}, dim(0){A.A.Bdy.V = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (60 160, 220 160, 220 20, 60 20, 60 160))
+  </a>
+  <b>
+    POLYGON(
+      (20 200, 60 160, 140 80, 260 200, 20 200))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212101212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-10: a polygon overlapping a skinny polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (0 0, 0 200, 200 200, 200 0, 0 0))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 1000000 110, 10000000 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212101212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-11: a polygon overlapping a skinny polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.NV = B.A.Bdy.CP}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (100 0, 100 200, 200 200, 200 0, 100 0))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 1000000 110, 10000000 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212101212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-12: a polygon overlapping a skinny polygon [dim(2){A.A.Int = B.A.Int},  dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (120 0, 120 200, 200 200, 200 0, 120 0))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 1000000 110, 10000000 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212101212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-13: a polygon overlapping a skinny polygon [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (0 0, 0 200, 110 200, 110 0, 0 0))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 1000000 110, 10000000 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212101212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-14: a polygon overlapping a skinny polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.V-EP = B.A.Bdy.NV-EP}, dim(0){A.A.Bdy.CP = B.A.Bdy.CP}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (100 100, 100 200, 200 200, 200 100, 100 100))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 2100 110, 2100 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212111212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-15: a polygon overlapping a skinny polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.V-EP = B.A.Bdy.NV-EP}, dim(0){A.A.Bdy.CP = B.A.Bdy.CP}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (100 100, 100 200, 200 200, 200 100, 100 100))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 2101 110, 2101 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212111212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-16: two skinny polygons overlapping [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.V-EP = B.A.Bdy.NV-EP}, dim(0){A.A.Bdy.CP = B.A.Bdy.CP}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (100 100, 200 200, 200 100, 100 100))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 2101 110, 2101 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212111212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-17: a polygon overlapping a skinny polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.V-EP = B.A.Bdy.NV-EP}, dim(0){A.A.Bdy.CP = B.A.Bdy.CP}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (100 100, 100 200, 200 200, 200 100, 100 100))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 1000000 110, 1000000 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212111212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-19: a polygon overlapping a skinny polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.V-EP = B.A.Bdy.NV-NV}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (120 100, 120 200, 200 200, 200 100, 120 100))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 500 110, 500 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212111212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-20: a polygon overlapping a skinny polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.V-EP = B.A.Bdy.NV-NV}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (120 100, 120 200, 200 200, 200 100, 120 100))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 501 110, 501 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212111212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-21: a polygon overlapping a skinny polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.V-EP = B.A.Bdy.NV-NV}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (120 100, 130 200, 200 200, 200 100, 120 100))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 501 110, 501 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212111212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-22: a polygon overlapping a skinny polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.V-EP = B.A.Bdy.NV-NV}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (120 100, 17 200, 200 200, 200 100, 120 100))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 501 110, 501 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212111212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-23: a polygon overlapping a skinny polygon [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.V-EP = B.A.Bdy.NV-NV}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (120 100, 120 200, 200 200, 200 100, 120 100))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 1000000 110, 1000000 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212111212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-25: two skinny polygons overlapping [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (101 99, 101 1000000, 102 1000000, 101 99))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 1000000 110, 1000000 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212101212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-26: two skinny polygons overlapping [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.Bdy.V-EP = B.A.Bdy.NV-EP}, dim(0){A.A.Bdy.CP = B.A.Bdy.CP}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (100 100, 200 101, 200 100, 100 100))
+  </a>
+  <b>
+    POLYGON(
+      (100 100, 2101 110, 2101 100, 100 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212111212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/A-6-26: two polygons overlapping [dim(2){A.A.Int = B.A.Int}, dim(0){A.A.Bdy.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (16 319, 150 39, 25 302, 160 20, 265 20, 127 317, 16 319))
+  </a>
+  <b>
+    POLYGON(
+      (10 307, 22 307, 153 34, 22 34, 10 307))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212101212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/Ah-3-1: the closing point of a polygon touching the closing points of another polygon and its hole [dim(0){A.A.Bdy.CP = B.A.oBdy.CP}, dim(0){A.A.Bdy.CP = B.A.iBdy.CP}]</desc>
+  <a>
+    POLYGON(
+      (160 200, 210 70, 120 70, 160 200))
+  </a>
+  <b>
+    POLYGON(
+      (160 200, 310 20, 20 20, 160 200), 
+      (160 200, 260 40, 70 40, 160 200))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/Ah-3-2: the boundary of a polygon touching the inner boundary of another polygon at two spots [dim(2){A.A.Int = B.A.Ext.h}, dim(0){A.A.oBdy.SP = B.A.iBdy.SP}, dim(0){A.A.oBdy.V = B.A.iBdy.V}]</desc>
+  <a>
+    POLYGON(
+      (170 120, 240 100, 260 50, 190 70, 170 120))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 330 120, 260 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/Ah-3-3: the boundary of a polygon touching the inner boundary of another polygon at two spots [dim(2){A.A.Int = B.A.Ext.h}, dim(0){A.A.oBdy.SP = B.A.iBdy.SP}, dim(0){A.A.oBdy.V = B.A.iBdy.V}]</desc>
+  <a>
+    POLYGON(
+      (270 90, 200 50, 150 80, 210 120, 270 90))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 330 120, 260 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/Ah-3-4: the boundary of a polygon touching the inner boundary of another polygon at one spot [dim(2){A.A.Int = B.A.Ext.h}, dim(0){A.A.oBdy.SP = B.A.iBdy.SP}]</desc>
+  <a>
+    POLYGON(
+      (170 120, 260 100, 240 60, 150 80, 170 120))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 330 120, 260 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/Ah-3-5: the boundary of a polygon touching the inner boundary of another polygon at one spot [dim(2){A.A.Int = B.A.Ext.h}, dim(0){A.A.oBdy.SP = B.A.iBdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (220 120, 270 80, 200 60, 160 100, 220 120))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 330 120, 260 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/Ah-3-6: the boundary of a polygon touching the inner boundary of another polygon at one spot [dim(2){A.A.Int = B.A.Ext.h}, dim(0){A.A.oBdy.SP = B.A.iBdy.V}]</desc>
+  <a>
+    POLYGON(
+      (260 50, 180 70, 180 110, 260 90, 260 50))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 330 120, 260 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/Ah-3-7: the boundary of a polygon touching the inner boundary of another polygon at two spots [dim(2){A.A.Int = B.A.Ext.h}, dim(0){A.A.oBdy.V = B.A.iBdy.NV}, dim(0){A.A.oBdy.V = B.A.iBdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (230 110, 290 80, 190 60, 140 90, 230 110))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 330 120, 260 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/Ah-3-8: the boundary of a polygon touching the inner boundary of another polygon [dim(2){A.A.Int = B.A.Ext.h}, dim(1){A.A.oBdy.SP-EP = B.A.iBdy.SP-EP}]</desc>
+  <a>
+    POLYGON(
+      (170 120, 330 120, 260 50, 100 50, 170 120))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 330 120, 260 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F1F212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/Ah-3-9: part of the boundary of a polygon touching part of the inner boundary of another polygon [dim(2){A.A.Int = B.A.Ext.h}, dim(1){A.A.oBdy.SP-V = B.A.iBdy.SP-NV}, dim(1){A.A.oBdy.V-EP = B.A.iBdy.NV-EP}]</desc>
+  <a>
+    POLYGON(
+      (170 120, 330 120, 280 70, 120 70, 170 120))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 330 120, 260 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/Ah-3-10: part of the boundary of a polygon touching part of the inner boundary of another polygon [dim(2){A.A.Int = B.A.Ext.h}, dim(1){A.A.oBdy.SP-V = B.A.iBdy.SP-NV}, dim(1){A.A.oBdy.V-EP = B.A.iBdy.NV-EP}]</desc>
+  <a>
+    POLYGON(
+      (170 120, 300 120, 250 70, 120 70, 170 120))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 330 120, 260 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/Ah-3-11: part of the boundary of a polygon touching part of the inner boundary of another polygon [dim(2){A.A.Int = B.A.Ext.h}, dim(1){A.A.oBdy.V-V-V = B.A.iBdy.NV-V-NV}]</desc>
+  <a>
+    POLYGON(
+      (190 100, 310 100, 260 50, 140 50, 190 100))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 330 120, 260 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/Ah-5-1: an entire polygon within another polygon which has a hole [dim(2){A.A.Ext = B.A.Int}, dim(2){A.A.Int = B.A.Int}]</desc>
+  <a>
+    POLYGON(
+      (280 130, 360 130, 270 40, 190 40, 280 130))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 250 120, 180 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="2FF1FF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>A/Ah-5-2: an entire polygon within another polygon which has a hole [dim(2){A.A.Int = B.A.Int}, dim(2){A.A.Ext = B.A.Int}]</desc>
+  <a>
+    POLYGON(
+      (220 80, 180 40, 80 40, 170 130, 270 130, 230 90, 300 90, 250 30, 280 30, 
+      390 140, 150 140, 40 30, 230 30, 280 80, 220 80))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 250 120, 180 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="2FF1FF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>A/Ah-5-3: polygon A within polygon B, the boundary of A touching the inner boundary of B [dim(2){A.A.Int = B.A.Int}, dim(2){A.A.Ext = B.A.Int}, dim(1){A.A.Bdy.NV-NV = B.A.iBdy.V-V}]</desc>
+  <a>
+    POLYGON(
+      (260 130, 360 130, 280 40, 170 40, 260 130))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 250 120, 180 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="2FF11F212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>A/Ah-5-4: polygon A within polygon B, the boundary of A touching the inner boundary of B [dim(2){A.A.Int = B.A.Int}, dim(2){A.A.Ext = B.A.Int}, dim(1){A.A.Bdy.V-V = B.A.iBdy.NV-NV}]</desc>
+  <a>
+    POLYGON(
+      (240 110, 340 110, 290 60, 190 60, 240 110))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 250 120, 180 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="2FF11F212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>A/Ah-5-5: polygon A within polygon B, the boundary of A touching the inner boundary of B [dim(2){A.A.Int = B.A.Int}, dim(2){A.A.Ext = B.A.Int}, dim(1){A.A.Bdy.V-V = B.A.iBdy.V-V}]</desc>
+  <a>
+    POLYGON(
+      (250 120, 350 120, 280 50, 180 50, 250 120))
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 250 120, 180 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="2FF11F212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>Ah/Ah-1-1: same polygons (with a hole) [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.oBdy.SP-EP = B.A.oBdy.SP-EP}, dim(1){A.A.iBdy.SP-EP = B.A.iBdy.SP-EP}]</desc>
+  <a>
+    POLYGON(
+      (230 210, 230 20, 20 20, 20 210, 230 210), 
+      (120 180, 50 50, 200 50, 120 180))
+  </a>
+  <b>
+    POLYGON(
+      (230 210, 230 20, 20 20, 20 210, 230 210), 
+      (120 180, 50 50, 200 50, 120 180))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="2FFF1FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>A2h/A2h-1-1: same polygons (with two holes) [dim(2){A.A.Int = B.A.Int}, dim(1){A.A.oBdy.SP-EP = B.A.oBdy.SP-EP}, dim(1){A.A.iBdy.SP-EP = B.A.iBdy.SP-EP}]</desc>
+  <a>
+    POLYGON(
+      (230 210, 230 20, 20 20, 20 210, 230 210), 
+      (140 40, 40 40, 40 170, 140 40), 
+      (110 190, 210 190, 210 50, 110 190))
+  </a>
+  <b>
+    POLYGON(
+      (230 210, 230 20, 20 20, 20 210, 230 210), 
+      (140 40, 40 40, 40 170, 140 40), 
+      (110 190, 210 190, 210 50, 110 190))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="2FFF1FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>A/mA-3-1: a polygon touching multipolygon at two points [dim(2){A.A.Int = B.2A.Ext}, dim(0){A.A.oBdy.CP = B.2A2.oBdy.NV}, dim(0){A.A.oBdy.V = B.2A1.oBdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (280 190, 330 150, 200 110, 150 150, 280 190))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (140 110, 260 110, 170 20, 50 20, 140 110)), 
+      (
+        (300 270, 420 270, 340 190, 220 190, 300 270)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/mA-3-2: a polygon touching multipolygon at two points [dim(2){A.A.Int = B.2A.Ext}, dim(0){A.A.oBdy.V = B.2A1.oBdy.CP}, dim(0){A.A.oBdy.V = B.2A2.oBdy.V}]</desc>
+  <a>
+    POLYGON(
+      (80 190, 220 190, 140 110, 0 110, 80 190))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (140 110, 260 110, 170 20, 50 20, 140 110)), 
+      (
+        (300 270, 420 270, 340 190, 220 190, 300 270)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/mA-3-3: a polygon touching multipolygon at two points [dim(2){A.A.Int = B.2A.Ext}, dim(0){A.A.oBdy.V = B.2A2.oBdy.NV}, dim(0){A.A.oBdy.V = B.2A1.oBdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (330 150, 200 110, 150 150, 280 190, 330 150))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (140 110, 260 110, 170 20, 50 20, 140 110)), 
+      (
+        (300 270, 420 270, 340 190, 220 190, 300 270)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/mA-3-4: a polygon touching multipolygon at one spoint [dim(2){A.A.Int = B.2A.Ext}, dim(0){A.A.oBdy.V = B.2A2.oBdy.NV}]</desc>
+  <a>
+    POLYGON(
+      (290 190, 340 150, 220 120, 170 170, 290 190))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (140 110, 260 110, 170 20, 50 20, 140 110)), 
+      (
+        (300 270, 420 270, 340 190, 220 190, 300 270)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/mA-3-5: a polygon touching multipolygon along boundaries [dim(2){A.A.Int = B.2A.Ext}, dim(1){A.A.oBdy.SP-V = B.2A2.oBdy.V-V}, dim(1){A.A.oBdy.V-V = B.2A1.oBdy.V-SP}]</desc>
+  <a>
+    POLYGON(
+      (220 190, 340 190, 260 110, 140 110, 220 190))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (140 110, 260 110, 170 20, 50 20, 140 110)), 
+      (
+        (300 270, 420 270, 340 190, 220 190, 300 270)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/mA-3-6: a polygon touching multipolygon along boundaries and at a point [dim(2){A.A.Int = B.2A.Ext}, dim(1){A.A.oBdy.V-NV = B.2A1.oBdy.NV-SP}, dim(0){A.A.oBdy.V = B.2A2.oBdy.V}]</desc>
+  <a>
+    POLYGON(
+      (140 190, 220 190, 100 70, 20 70, 140 190))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (140 110, 260 110, 170 20, 50 20, 140 110)), 
+      (
+        (300 270, 420 270, 340 190, 220 190, 300 270)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>A/mA-6-1: a polygon overlapping multipolygon [dim(2){A.A.Int = B.4A.Int}, dim(0){A.A.Bdy.NV = B.A.Bdy.V}, dim(0){A.A.Bdy.NV = B.A.Bdy.CP}, dim(0){A.A.Bdy.NV = B.A.Bdy.V}, dim(0){A.A.Bdy.NV = B.A.Bdy.CP}]</desc>
+  <a>
+    POLYGON(
+      (140 220, 60 140, 140 60, 220 140, 140 220))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (100 20, 180 20, 180 100, 100 100, 100 20)), 
+      (
+        (20 100, 100 100, 100 180, 20 180, 20 100)), 
+      (
+        (100 180, 180 180, 180 260, 100 260, 100 180)), 
+      (
+        (180 100, 260 100, 260 180, 180 180, 180 100)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="21210F212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mA/mA-3-1: MultiPolygon touching MultiPolygon [dim(0){A.mA.Bdy.TP = B.mA.Bdy.TP}]</desc>
+  <a>
+    MULTIPOLYGON(
+      (
+        (110 110, 70 200, 150 200, 110 110)), 
+      (
+        (110 110, 150 20, 70 20, 110 110)))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (110 110, 160 160, 210 110, 160 60, 110 110)), 
+      (
+        (110 110, 60 60, 10 110, 60 160, 110 110)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mAh/mAh-3-1: MultiPolygon touching MultiPolygon [dim(0){A.mA.Bdy.TP = B.mA.Bdy.TP}]</desc>
+  <a>
+    MULTIPOLYGON(
+      (
+        (110 110, 70 200, 150 200, 110 110), 
+        (110 110, 100 180, 120 180, 110 110)), 
+      (
+        (110 110, 150 20, 70 20, 110 110), 
+        (110 110, 120 40, 100 40, 110 110)))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (110 110, 160 160, 210 110, 160 60, 110 110), 
+        (110 110, 160 130, 160 90, 110 110)), 
+      (
+        (110 110, 60 60, 10 110, 60 160, 110 110), 
+        (110 110, 60 90, 60 130, 110 110)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F01212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mAh/mAh-3-2: MultiPolygon touching MultiPolygon [dim(1){A.mA.Bdy.NV-EP = B.mA.Bdy.V-SP}, dim(1){A.mA.Bdy.SP-NV = B.mA.Bdy.EP-V}]</desc>
+  <a>
+    MULTIPOLYGON(
+      (
+        (110 110, 70 200, 200 200, 110 110), 
+        (110 110, 100 180, 120 180, 110 110)), 
+      (
+        (110 110, 200 20, 70 20, 110 110), 
+        (110 110, 120 40, 100 40, 110 110)))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (110 110, 160 160, 210 110, 160 60, 110 110), 
+        (110 110, 160 130, 160 90, 110 110)), 
+      (
+        (110 110, 60 60, 10 110, 60 160, 110 110), 
+        (110 110, 60 90, 60 130, 110 110)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mAh/mAh-3-3: MultiPolygon touching MultiPolygon [dim(1){A.mA.Bdy.SP-NV = B.mA.Bdy.EP-V}, dim(1){A.mA.Bdy.NV-EP = B.mA.Bdy.V-SP},   dim(1){A.mA.Bdy.NV-EP = B.mA.Bdy.V-SP}, dim(1){A.mA.Bdy.SP-NV = B.mA.Bdy.EP-V}]</desc>
+  <a>
+    MULTIPOLYGON(
+      (
+        (110 110, 20 200, 200 200, 110 110), 
+        (110 110, 100 180, 120 180, 110 110)), 
+      (
+        (110 110, 200 20, 20 20, 110 110), 
+        (110 110, 120 40, 100 40, 110 110)))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (110 110, 160 160, 210 110, 160 60, 110 110), 
+        (110 110, 160 130, 160 90, 110 110)), 
+      (
+        (110 110, 60 60, 10 110, 60 160, 110 110), 
+        (110 110, 60 90, 60 130, 110 110)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mAh/mAh-6-1: MultiPolygon touching MultiPolygon [dim(2){A.mA.Int = B.mA.Int}]</desc>
+  <a>
+    MULTIPOLYGON(
+      (
+        (110 110, 70 200, 200 200, 110 110), 
+        (110 110, 100 180, 120 180, 110 110)), 
+      (
+        (110 110, 200 20, 70 20, 110 110), 
+        (110 110, 120 40, 100 40, 110 110)))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (110 110, 160 160, 210 110, 160 60, 110 110), 
+        (110 110, 160 130, 160 90, 110 110)), 
+      (
+        (110 110, 60 60, 10 110, 60 160, 110 110), 
+        (110 110, 60 90, 60 130, 110 110)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF2F11212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mAh/mAh-6-2: MultiPolygon touching MultiPolygon [dim(2){A.mA.Int = B.mA.Int}]</desc>
+  <a>
+    MULTIPOLYGON(
+      (
+        (110 110, 70 200, 200 200, 110 110), 
+        (110 110, 100 180, 120 180, 110 110)), 
+      (
+        (110 110, 200 20, 70 20, 110 110), 
+        (110 110, 120 40, 100 40, 110 110)))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (110 110, 70 200, 210 110, 70 20, 110 110), 
+        (110 110, 110 140, 150 110, 110 80, 110 110)), 
+      (
+        (110 110, 60 60, 10 110, 60 160, 110 110), 
+        (110 110, 60 90, 60 130, 110 110)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="212111212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+</run>
diff --git a/tests/xmltester/tests/validate/TestRelateAC.xml b/tests/xmltester/tests/validate/TestRelateAC.xml
new file mode 100644
index 0000000..526288b
--- /dev/null
+++ b/tests/xmltester/tests/validate/TestRelateAC.xml
@@ -0,0 +1,36 @@
+<run>
+<precisionModel type="FLOATING"/>
+
+<case>
+<desc>AC A-shells overlapping B-shell at A-vertex</desc>
+  <a>
+    POLYGON(
+      (100 60, 140 100, 100 140, 60 100, 100 60))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (80 40, 120 40, 120 80, 80 80, 80 40)), 
+      (
+        (120 80, 160 80, 160 120, 120 120, 120 80)), 
+      (
+        (80 120, 120 120, 120 160, 80 160, 80 120)), 
+      (
+        (40 80, 80 80, 80 120, 40 120, 40 80)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="21210F212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+</run>
diff --git a/tests/xmltester/tests/validate/TestRelateLA.xml b/tests/xmltester/tests/validate/TestRelateLA.xml
new file mode 100644
index 0000000..3be916e
--- /dev/null
+++ b/tests/xmltester/tests/validate/TestRelateLA.xml
@@ -0,0 +1,1932 @@
+<run>
+<precisionModel type="FLOATING"/>
+
+<case>
+<desc>L/A-3-1: a line touching the closing point of a polygon [dim(0){A.L.Bdy.SP = B.oBdy.CP}]</desc>
+  <a>
+    LINESTRING(150 150, 40 230)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A-3-2: the start and end points of a LineString touching the boundary (at non-vertices) of a polygon [dim(0){A.L.Bdy.SP = B.oBdy.NV}, dim(0){A.L.Bdy.EP = B.oBdy.NV}]</desc>
+  <a>
+    LINESTRING(40 40, 50 130, 130 130)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F0F212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A-3-3: the end point of a line touching the closing point of a polygon [dim(0){A.L.Bdy.EP = B.oBdy.CP}]</desc>
+  <a>
+    LINESTRING(40 230, 150 150)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A-3-4: an entire LineString touching the boundary (at non-vertices) of a polygon [dim(1){A.L.Int.SP-EP = B.oBdy.NV-NV}]</desc>
+  <a>
+    LINESTRING(210 150, 330 150)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F1FF0F212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A-3-5: the start portion of a LineString touching the boundary (at non-vertices) of a polygon [dim(1){A.L.Int.SP-V = B.oBdy.NV-NV}]</desc>
+  <a>
+    LINESTRING(200 150, 310 150, 360 220)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F11F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A-3-6: the start portion and the end point of a LineString touching the boundary of a polygon [dim(1){A.L.Int.SP-V = B.oBdy.NV-NV}, dim(0){A.L.Bdy.EP = B.A.oBdy.V}]</desc>
+  <a>
+    LINESTRING(180 150, 250 150, 230 250, 370 250, 410 150)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F11F0F212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A-3-7: the middle portion of a LineString touching the boundary (at non-vertices) of a polygon [dim(1){A.L.Int.V-V = B.oBdy.NV-NV}]</desc>
+  <a>
+    LINESTRING(210 210, 220 150, 320 150, 370 210)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F11FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A-4-1: a line at non-vertex crossing non-vertex boundary of polygon [dim(0){A.L.Int.NV = B.A.oBdy.NV}, dim(1){A.L.Int.NV-EP = B.A.Int}]</desc>
+  <a>
+    LINESTRING(20 60, 150 60)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1010F0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A-4-2: a line at non-vertex crossing non-vertex boundaries of polygon twice [dim(0){A.L.Int.NV = B.A.oBdy.NV}, dim(1){A.L.Int.NV-NV = B.A.Int}]</desc>
+  <a>
+    LINESTRING(60 90, 310 180)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A-4-3: a line at non-vertex crossing vertex boundary of polygon [dim(0){A.L.Int.NV = B.A.oBdy.V}, dim(1){A.L.Int.NV-EP = B.A.Int}]</desc>
+  <a>
+    LINESTRING(90 210, 210 90)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1010F0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A-4-4: a line at non-vertex crossing vertex boundaries of polygon twice [dim(0){A.L.Int.NV = B.A.oBdy.V}, dim(1){A.L.Int.NV-NV = B.A.Int}, dim(0){A.L.Int.NV = B.A.oBdy.CP}]</desc>
+  <a>
+    LINESTRING(290 10, 130 170)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A-4-5: a line at vertex crossing non-vertex boundary of polygon [dim(0){A.L.Int.V = B.A.oBdy.NV}, dim(1){A.L.Int.V-EP = B.A.Int}]</desc>
+  <a>
+    LINESTRING(30 100, 100 100, 180 100)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1010F0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A-4-6: a line at vertex crossing non-vertex boundaries of polygon twice [dim(0){A.L.Int.V = B.A.oBdy.NV}, dim(1){A.L.Int.V-V = B.A.Int}]</desc>
+  <a>
+    LINESTRING(20 100, 100 100, 360 100, 410 100)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A-4-7: a line at vertex crossing vertex boundary of polygon [dim(0){A.L.Int.V = B.A.oBdy.V}, dim(1){A.L.Int.V-EP = B.A.Int}]</desc>
+  <a>
+    LINESTRING(90 210, 150 150, 210 90)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1010F0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A-5-1: an entire line within a polygon [dim(1){A.L.Int.SP-EP = B.A.Int}]</desc>
+  <a>
+    LINESTRING(180 90, 280 120)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FF0FF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>L/A-5-2: a line within a polygon but the line's both ends touching the boundary of the polygon [dim(1){A.L.Int.SP-EP = B.A.Int}, dim(0){A.L.Bdy.SP = B.oBdy.NV}, dim(0){A.L.Bdy.EP = B.oBdy.NV}]</desc>
+  <a>
+    LINESTRING(70 70, 80 20)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFF0F212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>L/A-5-3: a line within a polygon but the line's start point touching the boundary of the polygon [dim(1){A.L.Int.SP-EP = B.A.Int}, dim(0){A.L.Bdy.SP = B.oBdy.NV}]</desc>
+  <a>
+    LINESTRING(130 20, 150 60)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FF00F212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>L/A-5-4: a line within a polygon but the line's start point and middle portion touching the boundary of the polygon [dim(1){A.L.Int.SP-V = B.A.Int}, dim(1){A.L.Int.V-V = B.oBdy.NV-NV}, dim(1){A.L.Int.V-EP = B.A.Int}, dim(0){A.L.Bdy.SP = B.A.oBdy.NV}]</desc>
+  <a>
+    LINESTRING(70 70, 80 20, 140 20, 150 60)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="11F00F212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>L/A-5-5: a line within a polygon but the line's middle portion touching the boundary of the polygon [dim(1){A.L.Int.SP-V = B.A.Int}, dim(1){A.L.Int.V-V = B.A.oBdy.NV-NV}, dim(1){A.L.Int.V-EP = B.A.Int}]</desc>
+  <a>
+    LINESTRING(170 50, 170 20, 240 20, 260 60)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="11F0FF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>L/Ah-2-1: a line outside a polygon [dim(1){A.L.Int.SP-EP = B.A.Ext}]</desc>
+  <a>
+    LINESTRING(50 100, 140 190, 280 190)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 330 120, 260 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/Ah-2-2: a line inside a polygon's hole [dim(1){A.L.Int.SP-EP = B.A.Ext.h}]</desc>
+  <a>
+    LINESTRING(140 60, 180 100, 290 100)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 330 120, 260 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/Ah-3-1: the start point of a line touching the inner boundary of a polygon [dim(0){A.L.Bdy.SP = B.A.iBdy.CP}, dim(1){A.L.Int.SP-EP = B.A.Ext.h}]</desc>
+  <a>
+    LINESTRING(170 120, 210 80, 270 80)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 330 120, 260 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/Ah-3-2: both ends of a line touching the inner boundary of a polygon [dim(0){A.L.Bdy.SP = B.A.iBdy.CP}, dim(1){A.L.Int.SP-EP = B.A.Ext.h}, dim(0){A.L.Bdy.SP = B.A.iBdy.CP}]</desc>
+  <a>
+    LINESTRING(170 120, 260 50)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 330 120, 260 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F0F212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/Ah-3-1: both ends of a line touching the inner boundary of a polygon [dim(0){A.L.Int.NV = B.A.Bdy.TP}]</desc>
+  <a>
+    LINESTRING(190 90, 190 270)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (190 190, 280 50, 100 50, 190 190))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/Ah-3-2: a line at a non-vertex crossing the boundary of a polygon where the closing point of the hole touches the shell at a non-vertex [dim(0){A.L.Int.NV = B.A.Bdy.TP}]</desc>
+  <a>
+    LINESTRING(60 160, 150 70)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (110 110, 250 100, 140 30, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/Ah-3-3: a line at a non-vertex crossing the boundary of a polygon where the hole at a vertex touches the shell at a non-vertex [dim(0){A.L.Int.NV = B.A.Bdy.TP}]</desc>
+  <a>
+    LINESTRING(60 160, 150 70)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 20 20, 360 20, 190 190), 
+      (250 100, 110 110, 140 30, 250 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/Ah-3-4: a line at a non-vertex crossing the boundary of a polygon where the hole at a vertex touches the shell at a vertex [dim(0){A.L.Int.NV = B.A.Bdy.TP}]</desc>
+  <a>
+    LINESTRING(60 160, 150 70)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 20 20, 360 20, 190 190), 
+      (250 100, 110 110, 140 30, 250 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/Ah-3-5: a line crossing polygon boundary where the closing point of the hole touches the shell at a vertex [dim(0){A.L.Int.V = B.A.Bdy.TP}]</desc>
+  <a>
+    LINESTRING(190 90, 190 190, 190 270)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (190 190, 280 50, 100 50, 190 190))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/Ah-3-6: a line at a vertex crossing the boundary of a polygon where closing point of the hole touches the shell at a non-vertex [dim(0){A.L.Int.V = B.A.Bdy.TP}]</desc>
+  <a>
+    LINESTRING(60 160, 110 110, 150 70)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (110 110, 250 100, 140 30, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/Ah-3-7: a line at a vertex crossing the boundary of a polygon where the hole at a vertex touches the shell at a non-vertex [dim(0){A.L.Int.V = B.A.Bdy.TP}]</desc>
+  <a>
+    LINESTRING(60 160, 110 110, 150 70)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 20 20, 360 20, 190 190), 
+      (250 100, 110 110, 140 30, 250 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/Ah-3-8: a line at a non-vertex crossing the boundary of a polygon where the hole at a vertex touches the shell at a vertex [dim(0){A.L.Int.V = B.A.Bdy.TP}]</desc>
+  <a>
+    LINESTRING(60 160, 110 110, 150 70)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 110 110, 20 20, 360 20, 190 190), 
+      (250 100, 110 110, 140 30, 250 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A2h-3-1: the start point a line touching the closing points of two connected holes in a polygon [dim(0){A.L.Int.SP = B.A.iBdy.TP}]</desc>
+  <a>
+    LINESTRING(130 110, 180 110, 190 60)
+  </a>
+  <b>
+    POLYGON(
+      (20 200, 240 200, 240 20, 20 20, 20 200), 
+      (130 110, 60 180, 60 40, 130 110), 
+      (130 110, 200 40, 200 180, 130 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A2h-3-2: the interior (at a non-vertex) of a line touching the closing points of two connected holes in a polygon [dim(0){A.L.Int.NV = B.A.iBdy.TP}]</desc>
+  <a>
+    LINESTRING(80 110, 180 110)
+  </a>
+  <b>
+    POLYGON(
+      (20 200, 240 200, 240 20, 20 20, 20 200), 
+      (130 110, 60 180, 60 40, 130 110), 
+      (130 110, 200 40, 200 180, 130 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A2h-3-3: the interior (at a non-vertex) of a line touching the closing point and at a vertex of two connected holes in a polygon [dim(0){A.L.Int.NV = B.A.iBdy1.TP}]</desc>
+  <a>
+    LINESTRING(80 110, 180 110)
+  </a>
+  <b>
+    POLYGON(
+      (20 200, 20 20, 240 20, 240 200, 20 200), 
+      (60 180, 130 110, 60 40, 60 180), 
+      (130 110, 200 40, 200 180, 130 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A2h-3-4: the interior (at a non-vertex) of a line touching the closing point and at a non-vertex of two connected holes in a polygon [dim(0){A.L.Int.NV = B.A.iBdy.TP}]</desc>
+  <a>
+    LINESTRING(80 110, 170 110)
+  </a>
+  <b>
+    POLYGON(
+      (20 200, 20 20, 240 20, 240 200, 20 200), 
+      (130 110, 60 40, 60 180, 130 110), 
+      (130 180, 130 40, 200 110, 130 180))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A2h-3-5: the start point a line touching the closing point and a non-vertex of two connected holes in a polygon [dim(0){A.L.Int.V = B.A.iBdy.TP}]</desc>
+  <a>
+    LINESTRING(80 110, 130 110, 170 110)
+  </a>
+  <b>
+    POLYGON(
+      (20 200, 20 20, 240 20, 240 200, 20 200), 
+      (130 110, 60 40, 60 180, 130 110), 
+      (130 180, 130 40, 200 110, 130 180))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A2h-3-6: the interior (at a vertex) of a line touching the closing points of two connected holes in a polygon [dim(0){A.L.Int.V = B.A.iBdy.TP}]</desc>
+  <a>
+    LINESTRING(80 110, 130 110, 180 110)
+  </a>
+  <b>
+    POLYGON(
+      (20 200, 240 200, 240 20, 20 20, 20 200), 
+      (130 110, 60 180, 60 40, 130 110), 
+      (130 110, 200 40, 200 180, 130 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A2h-3-7: the interior (at a vertex) of a line touching the closing point and at a vertex of two connected holes in a polygon [dim(0){A.L.Int.V = B.A.iBdy1.TP}]</desc>
+  <a>
+    LINESTRING(80 110, 130 110, 180 110)
+  </a>
+  <b>
+    POLYGON(
+      (20 200, 20 20, 240 20, 240 200, 20 200), 
+      (60 180, 130 110, 60 40, 60 180), 
+      (130 110, 200 40, 200 180, 130 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/A2h-3-8: the interior (at a vertex) of a line touching the closing point and at a non-vertex of two connected holes in a polygon [dim(0){A.L.Int.V = B.A.iBdy.TP}]</desc>
+  <a>
+    LINESTRING(80 110, 130 110, 170 110)
+  </a>
+  <b>
+    POLYGON(
+      (20 200, 20 20, 240 20, 240 200, 20 200), 
+      (130 110, 60 40, 60 180, 130 110), 
+      (130 180, 130 40, 200 110, 130 180))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/mA-4-1: a line intersecting the interior and exterior of MultiPolygon [dim(1){A.L.Int.SP-NV = B.2A1.Int}, dim (1){A.L.Int.NV-EP = B.2A2.Int}]</desc>
+  <a>
+    LINESTRING(160 70, 320 230)
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (140 110, 260 110, 170 20, 50 20, 140 110)), 
+      (
+        (300 270, 420 270, 340 190, 220 190, 300 270)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1010FF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/mA-4-2: a line intersecting the interior and exterior of MultiPolygon [dim(1){A.L.Int.SP-V = B.2A1.Int}, dim (1){A.L.Int.V-EP = B.2A2.Int}]</desc>
+  <a>
+    LINESTRING(160 70, 200 110, 280 190, 320 230)
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (140 110, 260 110, 170 20, 50 20, 140 110)), 
+      (
+        (300 270, 420 270, 340 190, 220 190, 300 270)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1010FF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/mA-5-1: a line within two connected polygons [dim(1){A.L.Int = B.2A.Int}, dim(0){A.L.Int.NV = B.2A.Bdy.TP]</desc>
+  <a>
+    LINESTRING(70 50, 70 150)
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (0 0, 0 100, 140 100, 140 0, 0 0)), 
+      (
+        (20 170, 70 100, 130 170, 20 170)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="10F0FF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>RL/A-3-1: a LinearRing touching a polygon's closing point [dim(0){A.RL.Int.CP = B.A.Bdy.CP}]</desc>
+  <a>
+    LINESTRING(110 110, 20 200, 200 200, 110 110)
+  </a>
+  <b>
+    POLYGON(
+      (20 20, 200 20, 110 110, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>RL/A-3-2: a LinearRing touching a polygon's boundary at a non-vertex [dim(0){A.RL.Int.CP = B.A.Bdy.NV}]</desc>
+  <a>
+    LINESTRING(150 70, 160 110, 200 60, 150 70)
+  </a>
+  <b>
+    POLYGON(
+      (20 20, 200 20, 110 110, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>RL/A-3-3: a LinearRing touching a polygon's boundary at a non-vertex [dim(0){A.RL.Int.CP = B.A.iBdy.NV}]</desc>
+  <a>
+    LINESTRING(80 60, 120 40, 120 70, 80 60)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110), 
+      (110 90, 50 30, 170 30, 110 90))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>RL/A-3-4: a LinearRing on the boundary of a polygon [dim(1){A.RL.Int.SP-EP = B.A.Bdy.SP-EP}]</desc>
+  <a>
+    LINESTRING(20 20, 200 20, 110 110, 20 20)
+  </a>
+  <b>
+    POLYGON(
+      (20 20, 200 20, 110 110, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F1FFFF2F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>RL/A-3-5: a LinearRing on the inner boundary of a polygon [dim(1){A.RL.Int.SP-EP = B.A.iBdy.SP-EP}]</desc>
+  <a>
+    LINESTRING(110 90, 170 30, 50 30, 110 90)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110), 
+      (110 90, 50 30, 170 30, 110 90))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F1FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>RL/A-3-6: a LinearRing on the inner boundary of a polygon [dim(1){A.RL.Int.SP-V = B.A.oBdy.SP-NV}]</desc>
+  <a>
+    LINESTRING(110 110, 170 50, 170 110, 110 110)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110), 
+      (110 90, 50 30, 170 30, 110 90))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F11FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>RL/A-3-7: a LinearRing on the inner boundary of a polygon [dim(1){A.RL.Int.SP-V = B.A.iBdy.SP-NV}]</desc>
+  <a>
+    LINESTRING(110 90, 70 50, 130 50, 110 90)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110), 
+      (110 90, 50 30, 170 30, 110 90))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F11FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>RL/A-4-1: a LinearRing crossing a polygon [dim(1){A.RL.Int.CP-NV = B.A.Int}, dim(0){A.L.Int.NV = B.A.Bdy.NV}]</desc>
+  <a>
+    LINESTRING(110 60, 20 150, 200 150, 110 60)
+  </a>
+  <b>
+    POLYGON(
+      (20 20, 200 20, 110 110, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>RL/A-4-2: a LinearRing crossing a polygon with a hole [dim(1){A.RL.Int.NV-NV = B.A.Int}, dim(0){A.RL.Int.NV = B.A.oBdy.CP}, dim(0){A.RL.Int.NV = B.A.iBdy.CP}, dim(0){A.RL.Int.NV = B.A.oBdy.NV}, dim(0){A.RL.Int.NV = B.A.iBdy.NV}]</desc>
+  <a>
+    LINESTRING(110 130, 110 70, 200 100, 110 130)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110), 
+      (110 90, 50 30, 170 30, 110 90))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>RL/A-5-1: a LinearRing within a polygon [dim(1){A.RL.Int.SP-EP = B.A.Int}]</desc>
+  <a>
+    LINESTRING(110 90, 160 40, 60 40, 110 90)
+  </a>
+  <b>
+    POLYGON(
+      (20 20, 200 20, 110 110, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>RL/A-5-2: a LinearRing within a polygon with a hole [dim(1){A.RL.Int.SP-EP = B.A.Int}]</desc>
+  <a>
+    LINESTRING(110 100, 40 30, 180 30, 110 100)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110), 
+      (110 90, 60 40, 160 40, 110 90))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>RL/A-5-3: a LinearRing within a polygon with a hole [dim(1){A.RL.Int.SP-EP = B.A.Int}, dim(0){A.L.Int.CP = B.A.oBdy.CP}]</desc>
+  <a>
+    LINESTRING(110 110, 180 30, 40 30, 110 110)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110), 
+      (110 90, 60 40, 160 40, 110 90))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="10FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>RL/A-5-4: a LinearRing within a polygon with a hole [dim(1){A.RL.Int.SP-EP = B.A.Int}, dim(0){A.RL.Int.CP = B.A.iBdy.CP}]</desc>
+  <a>
+    LINESTRING(110 90, 180 30, 40 30, 110 90)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110), 
+      (110 90, 60 40, 160 40, 110 90))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="10FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>RL/A-5-5: a LinearRing within a polygon with a hole [dim(1){A.RL.Int.SP-EP = B.A.Int}, dim(1){A.RL.Int.SP-NV = B.A.Bdy.iBdy.SP-V}]</desc>
+  <a>
+    LINESTRING(110 90, 50 30, 180 30, 110 90)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110), 
+      (110 90, 60 40, 160 40, 110 90))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="11FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>nsL/A-3-1: a non-simple LineString touching a polygon [dim(0){A.nsL.Bdy.SP = B.A.Bdy.CP}]</desc>
+  <a>
+    LINESTRING(110 110, 200 200, 200 110, 110 200)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>nsL/A-3-2: a non-simple LineString touching a polygon [dim(0){A.nsL.Bdy.SPb = B.A.Bdy.CP}]</desc>
+  <a>
+    LINESTRING(110 110, 200 200, 110 110, 20 200, 20 110, 200 110)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>nsL/A-3-3: a non-simple LineString touching a polygon [dim(0){A.nsL.Bdy.SPo = B.A.Bdy.CP}]</desc>
+  <a>
+    LINESTRING(110 110, 20 110, 200 110, 50 110, 110 170)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>nsL/A-3-4: a non-simple LineString touching a polygon [dim(0){A.nsL.Bdy.SPx = B.A.Bdy.CP}]</desc>
+  <a>
+    LINESTRING(110 110, 20 200, 110 200, 110 110, 200 200)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>nsL/A-3-5: a non-simple LineString touching a polygon [dim(1){A.nsL.Int.SPb-Vo = B.A.Bdy.SP-NV}]</desc>
+  <a>
+    LINESTRING(110 110, 170 50, 20 200, 20 110, 200 110)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F11F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>nsL/A-4-1: a non-simple LineString crossing a polygon [dim(1){A.nsL.Int.V-V-NV = B.A.Int}, dim(1){A.nsL.SPx-V = B.A.Bdy.SP-NV}]</desc>
+  <a>
+    LINESTRING(110 110, 180 40, 110 40, 110 180)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="111F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>nsL/A-5-1: a non-simple LineString within a polygon [dim(1){A.nsL.Int.SPx-EP = B.A.Int}]</desc>
+  <a>
+    LINESTRING(110 60, 50 30, 170 30, 90 70)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FF0FF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>nsL/A-5-2: a non-simple LineString within a polygon [dim(1){A.nsL.Int.SPx-EP = B.A.Int}, dim(1){A.nsL.Int.SPx-V = B.A.Bdy.SP-NV}]</desc>
+  <a>
+    LINESTRING(110 110, 180 40, 110 40, 110 110, 70 40)
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="11F00F212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>nsL/Ah: the self-crossing point of a non-simple LineString touching the closing point of the inner boundary of a polygon [dim(0){A.nsL.Int.V = B.A.iBdy.CP}]</desc>
+  <a>
+    LINESTRING(230 70, 170 120, 190 60, 140 60, 170 120, 270 90)
+  </a>
+  <b>
+    POLYGON(
+      (150 150, 410 150, 280 20, 20 20, 150 150), 
+      (170 120, 330 120, 260 50, 100 50, 170 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/A-3-1: MultiLineString touching a polygon's closing point [dim(0){A.mL.Bdy.SPb = B.A.Bdy.CP}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 110, 200 110), 
+      (200 200, 110 110, 20 210, 110 110))
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/A-3-2: MultiLineString touching a polygon's closing point [dim(0){A.mL.Bdy.SPo = B.A.Bdy.CP}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 110, 200 110), 
+      (60 180, 60 110, 160 110, 110 110))
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/A-3-3: MultiLineString touching a polygon's closing point [dim(0){A.mL.Bdy.SPx = B.A.Bdy.CP}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 110, 200 110), 
+      (200 200, 110 110, 20 200, 110 200, 110 110))
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/A-4-1: MultiLineString crossing a polygon [dim(1){A.mL.Int.SP-NVb = B.A.Int}, dim(0){A.mL.Int.NVb = B.A.Bdy.CP}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 110, 200 110), 
+      (110 50, 110 170, 110 70, 110 150, 200 150))
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1010F0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/A-4-2: MultiLineString crossing a polygon [dim(1){A.mL.Int.SP-NVo = B.A.Int}, dim(0){A.mL.Int.NVo = B.A.Bdy.CP}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 110, 200 110), 
+      (50 110, 170 110, 110 170, 110 50, 110 170, 110 50))
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1010F0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/A-4-3: MultiLineString crossing a polygon [dim(1){A.mL.Int.SP-NVx = B.A.Int}, dim(0){A.mL.Int.NVx = B.A.Bdy.CP}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 110, 200 110), 
+      (110 60, 110 160, 200 160))
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1010F0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/A-4-4: MultiLineString crossing a polygon [dim(1){A.mL.Int.Vb-Vb = B.A.Int}, dim(0){A.mL.Int.Vb = B.A.oBdy.CP}, dim(0){A.mL.Int.Vb = B.A.iBdy.CP}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 110, 200 110), 
+      (110 60, 110 160, 200 160))
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1010F0212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/A-5-1: MultiLineString within a polygon [dim(1){A.mL.Int.SP-EP = B.A.Int}]</desc>
+  <a>
+    MULTILINESTRING(
+      (110 100, 40 30, 180 30), 
+      (170 30, 110 90, 50 30))
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FF0FF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mL/A-5-2: MultiLineString within a polygon [dim(1){A.mL.Int.SP-EP = B.A.Int}]</desc>
+  <a>
+    MULTILINESTRING(
+      (110 110, 60 40, 70 20, 150 20, 170 40), 
+      (180 30, 40 30, 110 80))
+  </a>
+  <b>
+    POLYGON(
+      (110 110, 200 20, 20 20, 110 110))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="11F00F212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mL/mA-3-1: MultiLineString within a MultiPolygon [dim(0){A.mL.Bdy.SPb = B.mA.Bdy.TP}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 110, 200 110, 200 160), 
+      (110 110, 200 110, 200 70, 20 150))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (110 110, 20 20, 200 20, 110 110)), 
+      (
+        (110 110, 20 200, 200 200, 110 110)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/mA-3-2: MultiLineString within a MultiPolygon [dim(0){A.mL.Bdy.SPo = B.mA.Bdy.TP}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 160, 70 110, 150 110, 200 160), 
+      (110 110, 20 110, 50 80, 70 110, 200 110))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (110 110, 20 20, 200 20, 110 110)), 
+      (
+        (110 110, 20 200, 200 200, 110 110)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/mA-3-3: MultiLineString within a MultiPolygon [dim(0){A.mL.Bdy.SPx = B.mA.Bdy.TP}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 110, 200 110), 
+      (110 110, 20 170, 20 130, 200 90))
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (110 110, 20 20, 200 20, 110 110)), 
+      (
+        (110 110, 20 200, 200 200, 110 110)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+</run>
diff --git a/tests/xmltester/tests/validate/TestRelateLC.xml b/tests/xmltester/tests/validate/TestRelateLC.xml
new file mode 100644
index 0000000..c002318
--- /dev/null
+++ b/tests/xmltester/tests/validate/TestRelateLC.xml
@@ -0,0 +1,57 @@
+<run>
+<precisionModel type="FLOATING"/>
+
+<case>
+<desc>LC - topographically equal with no boundary</desc>
+  <a>
+    LINESTRING(0 0, 0 50, 50 50, 50 0, 0 0)
+  </a>
+  <b>
+    MULTILINESTRING(
+      (0 0, 0 50), 
+      (0 50, 50 50), 
+      (50 50, 50 0), 
+      (50 0, 0 0))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFFFFFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>LC - equal with boundary intersection</desc>
+  <a>
+    LINESTRING(0 0, 60 0, 60 60, 60 0, 120 0)
+  </a>
+  <b>
+    MULTILINESTRING(
+      (0 0, 60 0), 
+      (60 0, 120 0), 
+      (60 0, 60 60))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="10FF0FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+</run>
diff --git a/tests/xmltester/tests/validate/TestRelateLL.xml b/tests/xmltester/tests/validate/TestRelateLL.xml
new file mode 100644
index 0000000..0308d75
--- /dev/null
+++ b/tests/xmltester/tests/validate/TestRelateLL.xml
@@ -0,0 +1,3388 @@
+<run>
+<precisionModel type="FLOATING"/>
+
+<case>
+<desc>L/L.1-3-1: touching at the start points of two lines [dim(0){A.L.Bdy.SP = B.L.Bdy.SP}]</desc>
+  <a>
+    LINESTRING(40 40, 120 120)
+  </a>
+  <b>
+    LINESTRING(40 40, 60 120)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.1-3-2: start point of one line touching end point of another line [dim(0){A.L.Bdy.SP = B.L.Bdy.EP}]</desc>
+  <a>
+    LINESTRING(40 40, 120 120)
+  </a>
+  <b>
+    LINESTRING(60 240, 40 40)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.1-3-3: start point of a line touching the interior of another line at a non-vertex [dim(0){A.L.Bdy.SP = B.L.Int.NV}]</desc>
+  <a>
+    LINESTRING(40 40, 180 180)
+  </a>
+  <b>
+    LINESTRING(120 120, 20 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.1-3-4: touching at the end points of two lines [dim(0){A.L.Bdy.EP = B.L.Bdy.EP}]</desc>
+  <a>
+    LINESTRING(40 40, 120 120)
+  </a>
+  <b>
+    LINESTRING(60 240, 120 120)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.1-3-5: end point of a line touching the interior of another line at a non-vertex [dim(0){A.L.Bdy.EP = B.L.Int.NV}]</desc>
+  <a>
+    LINESTRING(40 40, 180 180)
+  </a>
+  <b>
+    LINESTRING(20 180, 140 140)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.1-4-1: two lines crossing at non-vertex [dim(0){A.L.Int.NV = B.L.Int.NV}]</desc>
+  <a>
+    LINESTRING(40 40, 120 120)
+  </a>
+  <b>
+    LINESTRING(40 120, 120 40)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.1-1-1: equal pointwise [dim(1){A.L.Int.SP-EP = B.L.Int.SP-EP}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100)
+  </a>
+  <b>
+    LINESTRING(40 40, 100 100)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFF0FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>L/L.1-1-2: equal lines but points in reverse sequence [dim(1){A.L.Int.SP-EP = B.L.Int.EP-SP}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100)
+  </a>
+  <b>
+    LINESTRING(100 100, 40 40)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFF0FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>L/L.1-2-1: dim(1){A.L.Int.SP-EP = B.L.Ext}</desc>
+  <a>
+    LINESTRING(40 40, 120 120)
+  </a>
+  <b>
+    LINESTRING(40 120, 120 160)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.1-5-1: line A containing line B [dim(1){A.L.Int.SP-EP = B.L.Int.SP-EP}]</desc>
+  <a>
+    LINESTRING(20 20, 180 180)
+  </a>
+  <b>
+    LINESTRING(20 20, 180 180)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFF0FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>L/L.1-5-2: line B is part of line A [dim(1){A.L.Int.SP-NV) = B.L.Int.SP-EP}]</desc>
+  <a>
+    LINESTRING(20 20, 180 180)
+  </a>
+  <b>
+    LINESTRING(20 20, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101F00FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.1-5-3: Line B is part of line A (in the middle portion) [dim(1){A.L.Int.NV-NV = B.L.Int.SP-EP}]</desc>
+  <a>
+    LINESTRING(20 20, 180 180)
+  </a>
+  <b>
+    LINESTRING(50 50, 140 140)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101FF0FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.1-6-1: start portions of two lines overlapping [dim(1){A.L.Int.SP-NV = B.L.Int.SP-NV]</desc>
+  <a>
+    LINESTRING(180 180, 40 40)
+  </a>
+  <b>
+    LINESTRING(120 120, 260 260)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1010F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.1-6-2: end portions of two lines overlapping [dim(1){A.L.Int.NV-EP = B.L.Int.NV-EP]</desc>
+  <a>
+    LINESTRING(40 40, 180 180)
+  </a>
+  <b>
+    LINESTRING(260 260, 120 120)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1010F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.1-6-3: end portion of line A overlapping the start portion of line B [dim(1){A.L.Int.NV-EP = B.L.Int.SP-NV]</desc>
+  <a>
+    LINESTRING(40 40, 180 180)
+  </a>
+  <b>
+    LINESTRING(120 120, 260 260)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1010F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-3-1: two LineStrings touching at start points [dim(0){A.L.Bdy.SP = B.L.Bdy.SP}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(40 40, 20 100, 40 160, 20 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-3-2: start point of LineStrings A touching the end point of LineString B [dim(0){A.L.Bdy.SP = B.L.Bdy.EP}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(20 200, 40 160, 20 100, 40 40)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-3-3: two LineStrings touching at end points [dim(0){A.L.Bdy.EP = B.L.Bdy.EP}]</desc>
+  <a>
+    LINESTRING(80 240, 200 120, 100 100, 40 40)
+  </a>
+  <b>
+    LINESTRING(20 200, 40 160, 20 100, 40 40)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-3-4: both the start and end points of LineString A touching the interior of LineString B at two vertices  [dim(0){A.L.Bdy.SP = B.L.Int.V}, dim(0){A.L.Bdy.EP = B.L.Int.V}]</desc>
+  <a>
+    LINESTRING(60 60, 60 230, 140 230, 250 160)
+  </a>
+  <b>
+    LINESTRING(20 20, 60 60, 250 160, 310 230)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF10FF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-3-5: both the start and end points of LineString A touching the interior of LineString B at two non-vertices  [dim(0){A.L.Bdy.SP = B.L.Int.NV}, dim(0){A.L.Bdy.EP = B.L.Int.NV}]</desc>
+  <a>
+    LINESTRING(60 60, 60 230, 140 230, 250 160)
+  </a>
+  <b>
+    LINESTRING(20 20, 110 110, 200 110, 320 230)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF10FF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-3-6: the start and end points of two LineStrings touching each other [dim(0){A.L.Bdy.SP = B.L.Bdy.SP}, dim(0){A.L.Bdy.EP = B.L.Bdy.EP}]</desc>
+  <a>
+    LINESTRING(60 110, 60 250, 360 210)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F0F1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-3-7: the start and end points of two LineStrings touching each other [dim(0){A.L.Bdy.SP = B.L.Bdy.EP}, dim(0){A.L.Bdy.EP = B.L.Bdy.SP}]</desc>
+  <a>
+    LINESTRING(60 110, 60 250, 360 210)
+  </a>
+  <b>
+    LINESTRING(360 210, 310 160, 110 160, 60 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F0F1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-3-8: start point of LineString B touching LineString A at a non-vertex [dim(0){A.L.Int.NV = B.L.Bdy.SP}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(160 160, 240 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-3-9: end point of LineString B touching LineString A at a non-vertex [dim(0){A.L.Int.NV = B.L.Bdy.EP}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(240 240, 160 160)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-3-10: both the start and end points of LineString B touching the interior of LineString A at two non-vertices  [dim(0){A.L.Int.NV = B.L.Bdy.SP}, dim(0){A.L.Int.NV = B.L.Bdy.EP}]</desc>
+  <a>
+    LINESTRING(60 60, 60 230, 140 230, 250 160)
+  </a>
+  <b>
+    LINESTRING(60 150, 110 100, 170 100, 110 230)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF01F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-3-11: the start point of LineString B touching the interior of LineString A at a non-vertex and the end point of LineString A touching the interior of LineString B at a vertex  [dim(0){A.L.Int.NV = B.L.Bdy.SP}, dim(0){A.L.Bdy.EP = B.L.Int.V}]</desc>
+  <a>
+    LINESTRING(60 60, 60 230, 140 230, 250 160)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F010F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-3-12: start point of LineString B touching LineString A at a vertex [dim(0){A.L.Int.V = B.L.Bdy.SP}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(200 120, 200 190, 150 240, 200 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-3-13: end point of LineString B touching LineString A at a vertex [dim(0){A.L.Int.V = B.L.Bdy.EP}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(200 240, 150 240, 200 200, 200 120)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-3-14: both the start and end points of LineString B touching the interior of LineString A at two vertices  [dim(0){A.L.Int.V = B.L.Bdy.SP}, dim(0){A.L.Int.V = B.L.Bdy.EP}]</desc>
+  <a>
+    LINESTRING(60 60, 60 230, 140 230, 250 160)
+  </a>
+  <b>
+    LINESTRING(60 230, 80 140, 120 140, 140 230)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF01F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-1: two LineStrings crossing at two points [dim(0){A.L.Bdy.SP = B.L.Bdy.SP}, dim(0){A.L.Int.V = B.L.Int.V}]</desc>
+  <a>
+    LINESTRING(60 110, 200 110, 250 160, 300 210)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-2: two LineStrings crossing at two points [dim(0){A.L.Bdy.SP = B.L.Int.SP}, dim(0){A.L.Int.V = B.L.Int.V}, dim(0){A.L.Bdy.EP = B.L.Int.EP}]</desc>
+  <a>
+    LINESTRING(60 110, 200 110, 250 160, 300 210, 360 210)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1F0F1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-3: two LineStrings crossing on one side [dim(0){A.L.Bdy.SP = B.L.Bdy.SP}, dim(0){A.L.Int.V = B.L.Int.V}]</desc>
+  <a>
+    LINESTRING(60 110, 220 110, 250 160, 280 110)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-4: two LineStrings crossing on one side [dim(0){A.L.Bdy.SP = B.L.Int.SP}, dim(0){A.L.Int.V = B.L.Int.NV}, dim(0){A.L.Bdy.EP = B.L.Int.EP}]</desc>
+  <a>
+    LINESTRING(60 110, 150 110, 200 160, 250 110, 360 110, 360 210)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1F0F1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-5: two LineStrings crossing at two points [dim(0){A.L.Bdy.SP = B.L.Int.NV}, dim(0){A.L.Int.V = B.L.Int.V}]</desc>
+  <a>
+    LINESTRING(130 160, 160 110, 220 110, 250 160, 250 210)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F10F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-6: two LineStrings crossing at two points [dim(0){A.L.Bdy.SP = B.L.Int.NV}, dim(0){A.L.Int.NV = B.L.Int.NV}]</desc>
+  <a>
+    LINESTRING(130 160, 160 110, 190 110, 230 210)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F10F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-7: two LineStrings crossing at two points [dim(0){A.L.Bdy.SP = B.L.Int.NV}, dim(0){A.L.Int.V = B.L.Int.NV}, dim(0){A.L.Bdy.SP = B.L.Bdy.EP}]</desc>
+  <a>
+    LINESTRING(130 160, 160 110, 200 110, 230 160, 260 210, 360 210)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F100F102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-8: two LineStrings crossing at two points [dim(0){A.L.Bdy.SP = B.L.Int.NV}, dim(0){A.L.Int.V = B.L.Int.NV}, dim(0){A.L.Int.V = B.L.Bdy.EP}]</desc>
+  <a>
+    LINESTRING(130 160, 160 110, 200 110, 230 160, 260 210, 360 210, 380 210)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0010F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-9: two LineStrings crossing at three points [dim(0){A.L.Bdy.SP = B.L.Int.NV}, dim(0){A.L.Int.V = B.L.Int.NV}, dim(0){A.L.Int.NV = B.L.Bdy.EP}]</desc>
+  <a>
+    LINESTRING(130 160, 160 110, 200 110, 230 160, 260 210, 380 210)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0010F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-10: two LineStrings crossing at two points [dim(0){A.L.Bdy.SP = B.L.Int.V}, dim(0){A.L.Int.V = B.L.Int.V}]</desc>
+  <a>
+    LINESTRING(110 160, 160 110, 200 110, 250 160, 250 210)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F10F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-11: two LineStrings crossing on one side [dim(0){A.L.Bdy.SP = B.L.Int.V}, dim(0){A.L.Int.V = B.L.Int.V}]</desc>
+  <a>
+    LINESTRING(110 160, 180 110, 250 160, 320 110)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F10F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-12: two LineStrings crossing on one side [dim(0){A.L.Bdy.SP = B.L.Int.NV}, dim(0){A.L.Int.V = B.L.Int.NV}]</desc>
+  <a>
+    LINESTRING(140 160, 180 80, 220 160, 250 80)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F10F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-13: two LineStrings crossing at a vertex for one of the LineStrings [dim(0){A.L.Int.V = B.L.Int.NV}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 130 190)
+  </a>
+  <b>
+    LINESTRING(20 130, 70 130, 160 40)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-14: two LineStrings crossing at non-vertices for both of the LineStrings [dim(0){A.L.Int.NV = B.L.Int.NV}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 130 190)
+  </a>
+  <b>
+    LINESTRING(40 160, 40 100, 110 40, 170 40)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-15: two LineStrings crossing on one side [dim(0){A.L.Int.V = B.L.Int.NV}, dim(0){A.L.Int.V = B.L.Int.NV}]</desc>
+  <a>
+    LINESTRING(130 110, 180 160, 230 110, 280 160, 330 110)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-16: two LineStrings crossing at vertices for both LineString  [dim(0){A.L.Int.V = B.L.Int.V}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 130 190)
+  </a>
+  <b>
+    LINESTRING(30 140, 80 140, 100 100, 200 30)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-17: two LineStrings crossing on one side [dim(0){A.L.Int.V = B.L.Int.V}, dim(0){A.L.Int.V = B.L.Int.V}]</desc>
+  <a>
+    LINESTRING(110 110, 110 160, 180 110, 250 160, 250 110)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-18: multiple crossings [dim(0){A.L.Int.V = B.L.Int.V}, dim(0){A.L.Int.NV = B.L.Int.NV}]</desc>
+  <a>
+    LINESTRING(20 20, 80 80, 160 80, 240 80, 300 140)
+  </a>
+  <b>
+    LINESTRING(20 60, 60 60, 60 140, 80 80, 100 20, 140 140, 180 20, 200 80, 220 20, 
+    240 80, 300 80, 270 110, 200 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-4-19: spiky LineStrings with multiple crossing [dim(0){A.L.Int.V = B.L.Int.V}]</desc>
+  <a>
+    LINESTRING(20 20, 230 20, 20 30, 170 30, 20 40, 230 40, 20 50, 230 60, 60 60, 
+    230 70, 20 70, 180 80, 60 80, 230 90, 20 90, 230 100, 30 100, 210 110, 20 110, 
+    80 120, 20 130, 170 130, 90 120, 230 130, 170 140, 230 140, 80 150, 160 140, 20 140, 
+    70 150, 20 150, 230 160, 80 160, 230 170, 20 160, 180 170, 20 170, 230 180, 20 180, 
+    40 190, 230 190, 20 200, 230 200)
+  </a>
+  <b>
+    LINESTRING(30 210, 30 60, 40 210, 40 30, 50 190, 50 20, 60 160, 60 50, 70 220, 
+    70 50, 80 20, 80 210, 90 50, 90 150, 100 30, 100 210, 110 20, 110 190, 120 50, 
+    120 180, 130 210, 120 20, 140 210, 130 50, 150 210, 130 20, 160 210, 140 30, 170 210, 
+    150 20, 180 210, 160 20, 190 210, 180 80, 170 50, 170 20, 180 70, 180 20, 190 190, 
+    190 30, 200 210, 200 30, 210 210, 210 20, 220 150, 220 20)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="001FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-1-1: two equal LineStrings with equal pointwise [dim(1){A.L.Int.SP-EP = B.L.Int.SP-EP}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFF0FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>L/L.2-1-2: two equal LineStrings with points in reverse sequence [dim(1){A.L.Int.SP-EP = B.L.Int.EP-SP}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(80 240, 200 120, 100 100, 40 40)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFF0FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>L/L.2-1-3: two equal LineStrings with different number of points [dim(1){A.L.Int.SP-EP = B.L.Int.EP-SP}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(80 240, 120 200, 200 120, 100 100, 80 80, 40 40)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFF0FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>L/L.2-2-1: disjoint [dim(1){A.L.Int.SP-EP = B.L.Ext}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(260 210, 240 130, 280 120, 260 40)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-2-2: wrapping around but still disjoint [dim(1){A.L.Int.SP-EP = B.L.Ext}]</desc>
+  <a>
+    LINESTRING(100 20, 20 20, 20 160, 210 160, 210 20, 110 20, 50 120, 120 150, 200 150)
+  </a>
+  <b>
+    LINESTRING(140 130, 100 110, 120 60, 170 60)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-5-1: LineString A containing LineString B, same pointwise [dim(1){A.L.Int.SP-EP = B.L.Int.SP-EP}]</desc>
+  <a>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFF0FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>L/L.2-5-2: LineString A containing LineString B, LineString A with less points [dim(1){A.L.Int.SP-V = B.L.Int.SP-EP}]</desc>
+  <a>
+    LINESTRING(60 110, 110 160, 310 160, 360 210)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFF0FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>L/L.2-5-3: LineString A containing LineString B [dim(1){A.L.Int.SP-V = B.L.Int.SP-EP}]</desc>
+  <a>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </a>
+  <b>
+    LINESTRING(60 110, 110 160, 250 160)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101F00FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-5-4: LineString A containing LineString B [dim(1){A.L.Int.NV-NV = B.L.Int.SP-EP}]</desc>
+  <a>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </a>
+  <b>
+    LINESTRING(110 160, 310 160, 340 190)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101FF0FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-5-5: LineString A containing LineString B [dim(1){A.L.Int.V-NV = B.L.Int.SP-EP}]</desc>
+  <a>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </a>
+  <b>
+    LINESTRING(140 160, 250 160, 310 160, 340 190)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101FF0FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-5-6: LineString A containing LineString B [dim(1){A.L.Int.V-V = B.L.Int.SP-EP}]</desc>
+  <a>
+    LINESTRING(60 110, 110 160, 250 160, 310 160, 360 210)
+  </a>
+  <b>
+    LINESTRING(110 160, 250 160, 310 160)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101FF0FF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-6-1: start portions of two LineStrings overlapping [dim(1){A.L.Int.SP-V = B.L.Int.SP-V}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(200 120, 100 100, 40 40, 140 80, 200 40)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1010F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-6-2: start portion of LineString A overlapping end portion of LineString B, intersecting at the middle of LineString A [dim(1){A.L.Int.SP-V = B.L.Int.V-EP}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(280 240, 240 140, 200 120, 100 100, 40 40)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1F1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-6-3: start portion of LineString A overlapping end portion of LineString B, intersecting at the middle of LineString A [dim(1){A.L.Int.SP-V = B.L.Int.NV-EP}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(80 190, 140 140, 40 40)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1F1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-6-4: end portions of two LineStrings overlapping [dim(1){A.L.Int.NV-EP = B.L.Int.V-EP}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(240 200, 200 260, 80 240, 140 180)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1010F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-6-5: end portion of LineString A overlapping start portion of LineString B [dim(1){A.L.Int.NV-EP = B.L.Int.SP-V}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(140 180, 80 240, 200 260, 240 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1010F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-6-6: end portion of LineString A overlapping end portion of LineString B, intersecting at the middle of LineString A [dim(1){A.L.Int.V-EP = B.L.Int.V-EP}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(280 240, 240 140, 200 120, 80 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1F1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-6-7: middle portions of two LineStrings overlapping [dim(1){A.L.Int.V-NV = B.L.Int.NV-V}]</desc>
+  <a>
+    LINESTRING(20 20, 80 80, 160 80, 240 80, 300 140)
+  </a>
+  <b>
+    LINESTRING(20 80, 120 80, 200 80, 260 20)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-6-8: middle portion of LineString A overlapping start portion of LineString B [dim(1){A.L.Int.V-V = B.L.Int.SP-V}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(100 100, 200 120, 240 140, 280 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-6-9: middle portion of LineString A overlapping end portion of LineString B [dim(1){A.L.Int.V-V = B.L.Int.V-EP}]</desc>
+  <a>
+    LINESTRING(40 40, 100 100, 200 120, 80 240)
+  </a>
+  <b>
+    LINESTRING(280 240, 240 140, 200 120, 100 100)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-6-10: middle portions of two LineStrings overlapping [dim(1){A.L.Int.V-V = B.L.Int.V-V}]</desc>
+  <a>
+    LINESTRING(20 20, 80 80, 160 80, 240 80, 300 140)
+  </a>
+  <b>
+    LINESTRING(80 20, 80 80, 240 80, 300 20)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/L.2-6-11: middle portions of two LineStrings overlapping, multiple intersects [dim(1){A.L.Int.V-V = B.L.Int.V-NV}, dim(1){A.L.Int.V-V = B.L.Int.V-NV}, dim(1){A.L.Int.V-V = B.L.Int.V-NV}]</desc>
+  <a>
+    LINESTRING(20 20, 80 80, 160 80, 240 80, 300 140)
+  </a>
+  <b>
+    LINESTRING(20 80, 80 80, 120 80, 140 140, 160 80, 200 80, 220 20, 240 80, 270 110, 
+    300 80)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/LR-3-1: a LineString touching a LinearRing [dim(0){A.L.Bdy.SP = B.LR.Int.CP}]</desc>
+  <a>
+    LINESTRING(100 100, 20 180, 180 180)
+  </a>
+  <b>
+    LINESTRING(100 100, 180 20, 20 20, 100 100)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF10F01F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/LR-4-1: a LineString crossing a LinearRing [dim(0){A.L.Int.NV = B.LR.Int.CP}]</desc>
+  <a>
+    LINESTRING(20 100, 180 100, 100 180)
+  </a>
+  <b>
+    LINESTRING(100 100, 180 20, 20 20, 100 100)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF01F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/LR-4-2: a LineString crossing a LinearRing [dim(0){A.L.Int.NV = B.LR.Int.CP}]</desc>
+  <a>
+    LINESTRING(100 40, 100 160, 180 160)
+  </a>
+  <b>
+    LINESTRING(100 100, 180 20, 20 20, 100 100)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF01F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/LR-4-3: a LineString crossing a LinearRing [dim(0){A.L.Int.V = B.LR.Int.CP}]</desc>
+  <a>
+    LINESTRING(20 100, 100 100, 180 100, 100 180)
+  </a>
+  <b>
+    LINESTRING(100 100, 180 20, 20 20, 100 100)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF01F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/LR-5-1: a LineString within a LinearRing [dim(1){A.L.Int.SP-EP = B.LR.Int.SP-NV}]</desc>
+  <a>
+    LINESTRING(100 100, 160 40)
+  </a>
+  <b>
+    LINESTRING(100 100, 180 20, 20 20, 100 100)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FF0FF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>L/LR-5-2: a LineString within a LinearRing [dim(1){A.L.Int.SP-EP = B.LR.Int.SP-NV}]</desc>
+  <a>
+    LINESTRING(100 100, 180 20)
+  </a>
+  <b>
+    LINESTRING(100 100, 180 20, 20 20, 100 100)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FF0FF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>L/LR-5-3: a LineString within a LinearRing [dim(1){A.L.Int.SP-V-EP = B.LR.Int.NV-CP-NV}]</desc>
+  <a>
+    LINESTRING(60 60, 100 100, 140 60)
+  </a>
+  <b>
+    LINESTRING(100 100, 180 20, 20 20, 100 100)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FF0FF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>L/LR-6-1: a LineString crossing a LinearRing [dim(1){A.L.Int.SP-NV = B.LR.Int.SP-V}]</desc>
+  <a>
+    LINESTRING(100 100, 190 10, 190 100)
+  </a>
+  <b>
+    LINESTRING(100 100, 180 20, 20 20, 100 100)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1F10F01F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/LR-6-2: a LineString crossing a LinearRing [dim(1){A.L.Int.SP-V = B.LR.Int.SP-NV}]</desc>
+  <a>
+    LINESTRING(100 100, 160 40, 160 100)
+  </a>
+  <b>
+    LINESTRING(100 100, 180 20, 20 20, 100 100)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1F10F01F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/LR-6-3: a LineString crossing a LinearRing [dim(1){A.L.Int.NV-V = B.LR.Int.SP-NV}]</desc>
+  <a>
+    LINESTRING(60 140, 160 40, 160 140)
+  </a>
+  <b>
+    LINESTRING(100 100, 180 20, 20 20, 100 100)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1F1FF01F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL: A line's interior at a non-vertex intersecting a non-simple linestring's end point with both crossing and overlapping line segments [dim(0){A.L.Int.NV = B.nsL.Bdy.EPb}]</desc>
+  <a>
+    LINESTRING(20 20, 140 140)
+  </a>
+  <b>
+    LINESTRING(80 80, 20 80, 140 80, 80 20, 80 140)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL: A line's interior at a non-vertex intersecting a non-simple linestring's end point with overlapping line segments [dim(0){A.L.Int.NV = B.nsL.Bdy.EPo}]</desc>
+  <a>
+    LINESTRING(20 20, 140 140)
+  </a>
+  <b>
+    LINESTRING(80 80, 20 80, 140 80)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL: A line's interior at a non-vertex intersecting a non-simple linestring's end point with crossing line segments [dim(0){A.L.Int.NV = B.nsL.Bdy.EPx}]</desc>
+  <a>
+    LINESTRING(20 20, 140 140)
+  </a>
+  <b>
+    LINESTRING(80 80, 140 80, 80 20, 80 140)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL: A line's interior at a non-vertex intersecting a non-simple linestring's closing point with both crossing and overlapping line segments [dim(0){A.L.Int.NV = B.nsL.Int.CPb}]</desc>
+  <a>
+    LINESTRING(20 20, 140 140)
+  </a>
+  <b>
+    LINESTRING(80 80, 20 80, 140 80, 80 20, 80 80)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF01F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL: A line's interior at a non-vertex intersecting a non-simple linestring's closing point with overlapping line segments [dim(0){A.L.Int.NV = B.nsL.Int.CPo}]</desc>
+  <a>
+    LINESTRING(20 20, 140 140)
+  </a>
+  <b>
+    LINESTRING(80 80, 20 80, 140 80, 80 80)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF01F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL: A line's interior at a non-vertex intersecting a non-simple linestring's closing point with crossing line segments [dim(0){A.L.Int.NV = B.nsL.Int.CPx}]</desc>
+  <a>
+    LINESTRING(20 20, 140 140)
+  </a>
+  <b>
+    LINESTRING(80 80, 20 80, 20 140, 140 20, 80 20, 80 80)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF01F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL: A line's interior at a non-vertex intersecting a non-simple linestring's interior at a non-vertex [dim(0){A.L.Int.NV = B.nsL.Int.NV}]</desc>
+  <a>
+    LINESTRING(20 20, 140 140)
+  </a>
+  <b>
+    LINESTRING(20 140, 140 20, 100 20, 100 80)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL: A line's interior at a non-vertex intersecting a non-simple linestring's interior at a non-vertex with both crossing and overlapping line segments [dim(0){A.L.Int.NV = B.nsL.Int.NVb}]</desc>
+  <a>
+    LINESTRING(20 20, 140 140)
+  </a>
+  <b>
+    LINESTRING(140 80, 20 80, 120 80, 80 20, 80 140)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL: A line's interior at a non-vertex intersecting a non-simple linestring's interior at a non-vertex with overlapping line segments [dim(0){A.L.Int.NV = B.nsL.Int.NVo}]</desc>
+  <a>
+    LINESTRING(20 20, 140 140)
+  </a>
+  <b>
+    LINESTRING(140 80, 20 80, 140 80)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF01F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL: A line's interior at a non-vertex intersecting a non-simple linestring's interior at a non-vertex with crossing line segments [dim(0){A.L.Int.NV = B.nsL.Int.NVx}]</desc>
+  <a>
+    LINESTRING(20 20, 140 140)
+  </a>
+  <b>
+    LINESTRING(140 80, 20 80, 80 140, 80 20)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL: A line's interior at a non-vertex intersecting a non-simple linestring's interior at a vertex [dim(0){A.L.Int.NV = B.nsL.Int.V}]</desc>
+  <a>
+    LINESTRING(20 20, 140 140)
+  </a>
+  <b>
+    LINESTRING(140 80, 80 80, 20 80, 50 140, 50 60)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL: A line's interior at a non-vertex intersecting a non-simple linestring's interior at a vertex with both crossing and overlapping line segments [dim(0){A.L.Int.NV = B.nsL.Int.Vb}]</desc>
+  <a>
+    LINESTRING(20 20, 140 140)
+  </a>
+  <b>
+    LINESTRING(140 80, 20 80, 120 80, 80 20, 80 80, 80 140)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL: A line's interior at a non-vertex intersecting a non-simple linestring's interior at a vertex with overlapping line segments [dim(0){A.L.Int.NV = B.nsL.Int.Vo}]</desc>
+  <a>
+    LINESTRING(20 20, 140 140)
+  </a>
+  <b>
+    LINESTRING(140 80, 20 80, 80 80, 140 80)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF01F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL: A line's interior at a non-vertex intersecting a non-simple linestring's interior at a vertex with crossing line segments [dim(0){A.L.Int.NV = B.nsL.Int.Vx}]</desc>
+  <a>
+    LINESTRING(20 20, 140 140)
+  </a>
+  <b>
+    LINESTRING(140 80, 20 80, 80 140, 80 80, 80 20)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL.1-3-1: start point of a LineString touching the self-intersecting point of a non-simple LineString [dim(0){A.L.Bdy.SP = B.nsL.Bdy.EPx}]</desc>
+  <a>
+    LINESTRING(130 150, 220 150, 220 240)
+  </a>
+  <b>
+    LINESTRING(130 240, 130 150, 220 20, 50 20, 130 150)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL.1-3-2: the interior of a LineString touching the self-intersecting point of a non-simple LineString [dim(0){A.L.Int.V = B.nsL.Bdy.EPx}]</desc>
+  <a>
+    LINESTRING(30 150, 130 150, 250 150)
+  </a>
+  <b>
+    LINESTRING(130 240, 130 150, 220 20, 50 20, 130 150)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL.1-3-3: the interior of a LineString touching the self-intersecting point of a non-simple LineString [dim(0){A.L.Int.NV = B.nsL.Bdy.EPx}]</desc>
+  <a>
+    LINESTRING(30 150, 250 150)
+  </a>
+  <b>
+    LINESTRING(130 240, 130 150, 220 20, 50 20, 130 150)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL.1-3-4: the interior of a LineString touching the self-intersecting point of a non-simple LineString [dim(0){A.L.Int.V = B.nsL.Bdy.EPx}]</desc>
+  <a>
+    LINESTRING(30 150, 130 150, 250 150)
+  </a>
+  <b>
+    LINESTRING(130 240, 130 20, 30 20, 130 150)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL.1-4: a Line crossing a non-simple LineString at non-vertices [dim(0){A.L.Int.NV = B.nsL.Int.NV}]</desc>
+  <a>
+    LINESTRING(30 150, 250 150)
+  </a>
+  <b>
+    LINESTRING(120 240, 120 20, 20 20, 120 170)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>nsL.5/L-3-1: switching the geometries for case L/nsL.5-3-1 [dim(0){A.nsL.Bdy.EPx = B.L.Bdy.SP}]</desc>
+  <a>
+    LINESTRING(200 200, 20 20, 200 20, 110 110, 20 200, 110 200, 110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 200 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL.5-3-2: the start point of a line touching the self-intersecting and self-crossing point of a non-simple LineString [dim(0){A.L.Bdy.SP = B.nsL.Bdy.EPx}]</desc>
+  <a>
+    LINESTRING(110 110, 200 110)
+  </a>
+  <b>
+    LINESTRING(200 200, 20 20, 200 20, 110 110, 20 200, 110 200, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL.5-3-3: the interior of a line touching the self-intersecting and self-crossing point of a non-simple LineString [dim(0){A.L.Int.NV = B.nsL.Bdy.EPx}]</desc>
+  <a>
+    LINESTRING(20 110, 200 110)
+  </a>
+  <b>
+    LINESTRING(200 200, 20 20, 200 20, 110 110, 20 200, 110 200, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>nsL.5/L-3-4 touches dim(0){A.nsL.Bdy.EPx = B.L.Int.NV}</desc>
+  <a>
+    LINESTRING(200 200, 20 20, 200 20, 110 110, 20 200, 110 200, 110 110)
+  </a>
+  <b>
+    LINESTRING(20 110, 200 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF10F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL.10-6-1: the middle portion of a line overlapping from the self-intersecting to the self-crossing a non-simple LineString [dim(1){A.L.Int.V-V = B.nsL.Int.EPx-NVx}]</desc>
+  <a>
+    LINESTRING(90 200, 90 130, 110 110, 150 200)
+  </a>
+  <b>
+    LINESTRING(200 200, 20 20, 200 20, 20 200, 20 130, 90 130)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/nsL.10-6-2: the middle portion of a line overlapping from the self-intersecting to the self-crossing a non-simple LineString [dim(1){A.L.Int.V-V = B.nsL.Int.NVx-EPx}]</desc>
+  <a>
+    LINESTRING(200 110, 110 110, 90 130, 90 200)
+  </a>
+  <b>
+    LINESTRING(200 200, 20 20, 200 20, 20 200, 20 130, 90 130)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>L/mL-3-1: a line's end point touching a non-vertex with crossing line segments of a MultiLineString [dim(0){A.L.Bdy.SP = B.mL.Int.NVx]</desc>
+  <a>
+    LINESTRING(80 80, 150 80, 210 80)
+  </a>
+  <b>
+    MULTILINESTRING(
+      (20 20, 140 140), 
+      (20 140, 140 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF10F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>LR/LR-1-1: two equal LinearRings, pointwise [dim(1){A.LR.Int.SP-EP = B.LR.Int.SP-EP}, dim(0){A.LR.Int.CP = B.LR.Int.CP}]</desc>
+  <a>
+    LINESTRING(40 80, 160 200, 260 20, 40 80)
+  </a>
+  <b>
+    LINESTRING(40 80, 160 200, 260 20, 40 80)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFFFFFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>LR/LR-1-2: two equal LinearRings with points in reverse sequence [dim(1){A.LR.Int.SP-EP = B.LR.Int.EP-SP}, dim(0){A.LR.Int.CP = B.LR.Int.CP}]</desc>
+  <a>
+    LINESTRING(40 80, 160 200, 260 20, 40 80)
+  </a>
+  <b>
+    LINESTRING(40 80, 260 20, 160 200, 40 80)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFFFFFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>LR/LR-1-3: two equal LinearRings with points in different sequence [dim(1){A.LR.Int.SP-EP = B.LR.Int.SP-EP}, dim(0){A.LR.Int.CP = B.LR.Int.V}, dim(0){A.LR.Int.V = B.LR.Int.CP}]</desc>
+  <a>
+    LINESTRING(40 80, 160 200, 260 20, 40 80)
+  </a>
+  <b>
+    LINESTRING(260 20, 40 80, 160 200, 260 20)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFFFFFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>LR/LR-1-4: two equal LinearRings with different number of points [dim(1){A.LR.Int.SP-EP = B.LR.Int.SP-EP}, dim(0){A.LR.Int.CP = B.LR.Int.V}, dim(0){A.LR.Int.NV = B.LR.Int.CP}]</desc>
+  <a>
+    LINESTRING(40 80, 160 200, 260 20, 40 80)
+  </a>
+  <b>
+    LINESTRING(100 140, 160 200, 260 20, 40 80, 100 140)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFFFFFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>LR/LR-4-1: two LinearRings crossing at closing points [dim(0){A.LR.Int.CP = B.LR.Int.CP}]</desc>
+  <a>
+    LINESTRING(100 100, 180 20, 20 20, 100 100)
+  </a>
+  <b>
+    LINESTRING(100 100, 180 180, 20 180, 100 100)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>LR/LR-4-2: two LinearRings crossing at two points [dim(0){A.LR.Int.CP = B.LR.Int.CP}, dim(0){A.LR.Int.V = B.LR.Int.V},]</desc>
+  <a>
+    LINESTRING(40 150, 40 40, 150 40, 150 150, 40 150)
+  </a>
+  <b>
+    LINESTRING(40 150, 150 40, 170 20, 170 190, 40 150)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>LR/LR-4-3: two LinearRings crossing at the closing and a non-vertex [dim(0){A.LR.Int.CP = B.LR.Int.NV}]</desc>
+  <a>
+    LINESTRING(100 100, 180 20, 20 20, 100 100)
+  </a>
+  <b>
+    LINESTRING(180 100, 20 100, 100 180, 180 100)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>LR/LR-4-4: two LinearRings crossing at the closing and a vertex [dim(0){A.LR.Int.CP = B.LR.Int.V}]</desc>
+  <a>
+    LINESTRING(100 100, 180 20, 20 20, 100 100)
+  </a>
+  <b>
+    LINESTRING(180 180, 100 100, 20 180, 180 180)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>LR/LR-4-5: two LinearRings crossing at a vertex and a non-vertex [dim(0){A.LR.Int.V = B.LR.Int.NV}]</desc>
+  <a>
+    LINESTRING(20 180, 100 100, 20 20, 20 180)
+  </a>
+  <b>
+    LINESTRING(100 20, 100 180, 180 100, 100 20)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>LR/LR-4-6: two LinearRings crossing at two points [dim(0){A.LR.Int.V = B.LR.Int.NV}, dim(0){A.LR.Int.V = B.LR.Int.NV},]</desc>
+  <a>
+    LINESTRING(40 150, 40 40, 150 40, 150 150, 40 150)
+  </a>
+  <b>
+    LINESTRING(170 20, 20 170, 170 170, 170 20)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>LR/LR-6-1: two LinearRings overlapping [dim(1){A.LR.Int.CP-V = B.LR.Int.CP-V}]</desc>
+  <a>
+    LINESTRING(40 150, 40 40, 150 40, 150 150, 40 150)
+  </a>
+  <b>
+    LINESTRING(40 150, 150 150, 90 210, 40 150)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1F1FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>LR/LR-6-2: two LinearRings overlapping [dim(1){A.LR.Int.CP-V = B.LR.Int.NV-NV}]</desc>
+  <a>
+    LINESTRING(40 150, 40 40, 150 40, 150 150, 40 150)
+  </a>
+  <b>
+    LINESTRING(20 150, 170 150, 90 230, 20 150)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1F1FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>LR/LR-6-3: two LinearRings overlapping [dim(1){A.LR.Int.(V-V-V-EP) = B.LR.Int.(NV-V-V-SP)}]</desc>
+  <a>
+    LINESTRING(40 150, 40 40, 150 40, 150 150, 40 150)
+  </a>
+  <b>
+    LINESTRING(40 150, 150 150, 150 40, 20 40, 20 150, 40 150)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1F1FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>LR/nsL-3-1: a LinearRing touching a non-simple LineString [dim(0){A.nsL.Int.CP = B.nsL.Bdy.SPb}]</desc>
+  <a>
+    LINESTRING(110 110, 200 20, 20 20, 110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 200 200, 110 110, 20 200, 20 110, 200 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>LR/nsL-3-1: a LinearRing touching a non-simple LineString [dim(0){A.nsL.Int.CP = B.nsL.Bdy.SPo}]</desc>
+  <a>
+    LINESTRING(110 110, 200 20, 20 20, 110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 20 110, 200 110, 50 110, 110 170)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>LR/nsL-3-1: a LinearRing touching a non-simple LineString [dim(0){A.nsL.Int.CP = B.nsL.Bdy.SPx}]</desc>
+  <a>
+    LINESTRING(110 110, 200 20, 20 20, 110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 20 200, 110 200, 110 110, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F01FFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>LR/nsL-6-1: a LinearRing and a non-simple LineString overlapping [dim(1){A.nsL.Int.SP-V = B.nsL.Int.NVx-SP}]</desc>
+  <a>
+    LINESTRING(110 110, 200 20, 20 20, 110 110)
+  </a>
+  <b>
+    LINESTRING(200 20, 20 200, 200 200, 110 110, 110 40)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101FFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>LR/nsL-6-2: a LinearRing and a non-simple LineString overlapping [dim(1){A.nsL.Int.SP-V = B.nsL.Int.NVx-SP}, dim(1){A.nsL.Int.V-EP = B.nsL.Int.EP-NVx}]</desc>
+  <a>
+    LINESTRING(110 110, 200 20, 20 20, 110 110)
+  </a>
+  <b>
+    LINESTRING(200 20, 20 200, 200 200, 20 20)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="101FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>nsL/nsL-4-1: non-simple LineStrings crossing at closing points [dim(0){A.nsL.Int.CP = B.nsL.Int.CP}]</desc>
+  <a>
+    LINESTRING(110 110, 20 110, 110 20, 20 20, 110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 200 200, 110 200, 200 110, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>nsL/nsL-4-2: non-simple LineStrings crossing at two points without vertices [dim(0){A.nsL.Int.NV = B.nsL.Int.NV}]</desc>
+  <a>
+    LINESTRING(20 120, 120 120, 20 20, 120 20, 20 120)
+  </a>
+  <b>
+    LINESTRING(170 100, 70 100, 170 170, 70 170, 170 100)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>nsL/nsL-4-3: non-simple LineStrings crossing at a point [dim(0){A.nsL.Int.NV = B.nsL.Int.V}]</desc>
+  <a>
+    LINESTRING(20 110, 110 110, 20 20, 110 20, 20 110)
+  </a>
+  <b>
+    LINESTRING(110 160, 70 110, 60 160, 20 130, 110 160)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>nsL/nsL-4-4: non-simple LineStrings crossing at self-crossing points [dim(0){A.nsL.Int.NVx = B.nsL.Int.NVx}]</desc>
+  <a>
+    LINESTRING(20 200, 200 200, 20 20, 200 20, 20 200)
+  </a>
+  <b>
+    LINESTRING(20 110, 200 110, 200 160, 20 60, 20 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>nsL/nsL-4-5: non-simple LineStrings crossing at vertices [dim(0){A.nsL.Int.V = B.nsL.Int.V}]</desc>
+  <a>
+    LINESTRING(20 110, 110 110, 20 20, 110 20, 20 110)
+  </a>
+  <b>
+    LINESTRING(200 200, 110 110, 200 110, 110 200, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>nsL/nsL-4-6: non-simple LineStrings crossing at two points with vertices [dim(0){A.nsL.Int.V = B.nsL.Int.V}]</desc>
+  <a>
+    LINESTRING(20 120, 120 120, 20 20, 120 20, 20 120)
+  </a>
+  <b>
+    LINESTRING(220 120, 120 20, 220 20, 120 120, 220 120)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/mL-1: MultiLineString [dim(1){A.mL.Int.SP-EP = B.mL.Int.SP-EP}]</desc>
+  <a>
+    MULTILINESTRING(
+      (70 20, 20 90, 70 170), 
+      (70 170, 120 90, 70 20))
+  </a>
+  <b>
+    MULTILINESTRING(
+      (70 20, 20 90, 70 170), 
+      (70 170, 120 90, 70 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFFFFFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mL/mL-1-1: non-simple MultiLineString  [dim(1){A.mL.Int.SP-EP = B.mL.Int.SP-EP}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 20, 90 20, 170 20), 
+      (90 20, 90 80, 90 140))
+  </a>
+  <b>
+    MULTILINESTRING(
+      (20 20, 90 20, 170 20), 
+      (90 20, 90 80, 90 140))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFF0FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mL/mL-1-2: equal non-simple MultiLineString with different sequence of lines and points [dim(1){A.mL.Int.SP-EP = B.mL.Int.EP-SP}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 20, 90 20, 170 20), 
+      (90 20, 90 80, 90 140))
+  </a>
+  <b>
+    MULTILINESTRING(
+      (90 140, 90 60, 90 20), 
+      (170 20, 130 20, 20 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="1FFF0FFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mL/mL-3-1: non-simple MultiLineStrings touching at boundaries [dim(0){A.mL.Bdy.SPx = B.mL.Bdy.SPb}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 20, 90 20, 170 20), 
+      (90 20, 90 80, 90 140))
+  </a>
+  <b>
+    MULTILINESTRING(
+      (90 20, 170 100, 170 140), 
+      (170 60, 90 20, 20 60), 
+      (130 100, 130 60, 90 20, 50 90))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/mL-3-2: non-simple MultiLineStrings touching at boundaries [dim(0){A.mL.Bdy.SPx = B.mL.Bdy.SPo}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 20, 90 20, 170 20), 
+      (90 20, 90 80, 90 140))
+  </a>
+  <b>
+    MULTILINESTRING(
+      (90 20, 170 100, 170 140), 
+      (130 140, 130 60, 90 20, 20 90, 90 20, 130 60, 170 60))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/mL-3-3: non-simple MultiLineStrings touching at boundaries [dim(0){A.mL.Bdy.SPx = B.mL.Bdy.SPx}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 20, 90 20, 170 20), 
+      (90 20, 90 80, 90 140))
+  </a>
+  <b>
+    MULTILINESTRING(
+      (90 20, 170 100, 170 140), 
+      (170 60, 90 20, 20 60))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF1F00102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/mL-3-4: non-simple MultiLineStrings touching at boundaries [dim(0){A.mL.Bdy.SPx = B.mL.Bdy.SPx}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 20, 90 20, 170 20), 
+      (90 20, 90 80, 90 140))
+  </a>
+  <b>
+    MULTILINESTRING(
+      (90 20, 170 100, 170 140), 
+      (170 60, 90 20, 20 60), 
+      (130 100, 90 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF10F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/mL-3-5: non-simple MultiLineStrings touching at boundaries [dim(0){A.mL.Bdy.SPx = B.mL.Bdy.SPx}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 20, 90 20, 170 20), 
+      (90 20, 90 80, 90 140))
+  </a>
+  <b>
+    MULTILINESTRING(
+      (90 20, 170 100, 170 140), 
+      (170 60, 90 20, 20 60), 
+      (120 100, 170 100, 90 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF10F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/mL-3-6: non-simple MultiLineStrings touching at boundaries [dim(0){A.mL.Bdy.SPx = B.mL.Int.SPb}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 20, 90 20, 170 20), 
+      (90 20, 90 80, 90 140))
+  </a>
+  <b>
+    MULTILINESTRING(
+      (90 20, 170 100, 170 140), 
+      (170 60, 90 20, 20 60), 
+      (120 100, 170 100, 90 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF10F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/mL-3-7: non-simple MultiLineStrings touching at boundaries [dim(0){A.mL.Bdy.SPx = B.mL.Int.SPo}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 20, 90 20, 170 20), 
+      (90 20, 90 80, 90 140))
+  </a>
+  <b>
+    MULTILINESTRING(
+      (90 20, 170 100, 170 140), 
+      (130 140, 130 60, 90 20, 20 90, 90 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF10F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/mL-3-8: non-simple MultiLineStrings touching at boundaries [dim(0){A.mL.Bdy.SPx = B.mL.Int.SPx}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 20, 90 20, 170 20), 
+      (90 20, 90 80, 90 140))
+  </a>
+  <b>
+    MULTILINESTRING(
+      (90 20, 170 100, 170 140), 
+      (170 60, 90 20, 20 60, 20 140, 90 20))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF10F0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/mL-4-1: non-simple MultiLineStrings crossing [dim(0){A.mL.Int.Vx = B.mL.Int.Vb}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 20, 90 90, 20 160), 
+      (90 160, 90 20))
+  </a>
+  <b>
+    MULTILINESTRING(
+      (160 160, 90 90, 160 20), 
+      (160 120, 120 120, 90 90, 160 60))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/mL-4-2: non-simple MultiLineStrings crossing [dim(0){A.mL.Int.Vx = B.mL.Int.Vo}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 20, 90 90, 20 160), 
+      (90 160, 90 20))
+  </a>
+  <b>
+    MULTILINESTRING(
+      (160 160, 90 90, 160 20), 
+      (160 120, 120 120, 90 90, 120 60, 160 60))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mL/mL-4-3: non-simple MultiLineStrings crossing [dim(0){A.mL.Int.Vx = B.mL.Int.Vx}]</desc>
+  <a>
+    MULTILINESTRING(
+      (20 20, 90 90, 20 160), 
+      (90 160, 90 20))
+  </a>
+  <b>
+    MULTILINESTRING(
+      (160 160, 90 90, 160 20), 
+      (160 120, 90 90, 160 60))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F1FF0102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+</run>
diff --git a/tests/xmltester/tests/validate/TestRelatePA.xml b/tests/xmltester/tests/validate/TestRelatePA.xml
new file mode 100644
index 0000000..643e766
--- /dev/null
+++ b/tests/xmltester/tests/validate/TestRelatePA.xml
@@ -0,0 +1,1018 @@
+<run>
+<precisionModel type="FLOATING"/>
+
+<case>
+<desc>P/A-2-1: a point outside a polygon [dim(0){A.P.Int = B.A.Ext}]</desc>
+  <a>
+    POINT(20 20)
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/A-2-2: a point outside a convex polygon [dim(0){A.P.Int = B.A.Ext}]</desc>
+  <a>
+    POINT(70 170)
+  </a>
+  <b>
+    POLYGON(
+      (110 230, 80 160, 20 160, 20 20, 200 20, 200 160, 140 160, 110 230))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/A-2-3: a point outside a concave polygon [dim(0){A.P.Int = B.A.Ext}]</desc>
+  <a>
+    POINT(110 130)
+  </a>
+  <b>
+    POLYGON(
+      (20 160, 80 160, 110 100, 140 160, 200 160, 200 20, 20 20, 20 160))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/A-2-4: dim(0){A.P.Int = B.A.Ext}</desc>
+  <a>
+    POINT(100 70)
+  </a>
+  <b>
+    POLYGON(
+      (20 150, 100 150, 40 50, 170 50, 110 150, 190 150, 190 20, 20 20, 20 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/A-2-5: a point outside a concave polygon [dim(0){A.P.Int = B.A.Ext}]</desc>
+  <a>
+    POINT(100 70)
+  </a>
+  <b>
+    POLYGON(
+      (20 150, 90 150, 40 50, 160 50, 110 150, 180 150, 180 20, 20 20, 20 150))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/A-3-1: a point on the closing point of a polygon [dim(0){A.P.Int = B.A.Bdy.CP}]</desc>
+  <a>
+    POINT(60 120)
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/A-3-2: a point on the boudary of a polygon at a non-vertex [dim(0){A.P.Int = B.A.Bdy.NV}]</desc>
+  <a>
+    POINT(110 120)
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/A-3-3: a point on the boundary of a polygon at a vertex [dim(0){A.P.Int = B.A.Bdy.V]</desc>
+  <a>
+    POINT(160 120)
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/A-5: a point on the interior of a polygon [dim(0){A.P.Int = B.A.Int}]</desc>
+  <a>
+    POINT(100 80)
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/Ah-2-1: a point outside of polygon with a hole [dim(0){A.P.Int = B.A.Ext}]</desc>
+  <a>
+    POINT(60 160)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (280 50, 100 50, 190 140, 280 50))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/Ah-2-2: a point inside the hole of the polygon [dim(0){A.P.Int = B.A.Ext.h}]</desc>
+  <a>
+    POINT(190 90)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (280 50, 100 50, 190 140, 280 50))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/Ah-3-1: a point on the closing point of the outer boundary of a polygon with a hole [dim(0){A.P.Int = B.A.oBdy.CP}]</desc>
+  <a>
+    POINT(190 190)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (280 50, 100 50, 190 140, 280 50))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/Ah-3-2: a point on the outer boundary of a polygon at a vertex [dim(0){A.P.Int = B.A.oBdy.V}]</desc>
+  <a>
+    POINT(360 20)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (280 50, 100 50, 190 140, 280 50))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/Ah-3-3: a point on the outer boundary of a polygon at a non-vertex [dim(0){A.P.Int = B.A.oBdy.NV}]</desc>
+  <a>
+    POINT(130 130)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (280 50, 100 50, 190 140, 280 50))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/Ah-3-4: a point on the closing point of the inner boundary of a polygon [dim(0){A.P.Int = B.A.iBdy.CP}]</desc>
+  <a>
+    POINT(280 50)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (280 50, 100 50, 190 140, 280 50))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/Ah-3-5: a point on the inner boundary of a polygon at a non-vertex [dim(0){A.P.Int = B.A.iBdy.NV}]</desc>
+  <a>
+    POINT(150 100)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (280 50, 100 50, 190 140, 280 50))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/Ah-3-6: a point on the inner boundary of a polygon at a vertex [dim(0){A.P.Int = B.A.iBdy.V}]</desc>
+  <a>
+    POINT(100 50)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (280 50, 100 50, 190 140, 280 50))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/Ah-5: a point inside the interior of a polygon with a hole [dim(0){A.P.Int = B.A.Int}]</desc>
+  <a>
+    POINT(140 120)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (280 50, 100 50, 190 140, 280 50))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/A2h-3-1: a point on the touching point of two holes in a polygon [dim(0){A.P.Int = B.A.iBdy.TP}]</desc>
+  <a>
+    POINT(190 50)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (90 50, 150 110, 190 50, 90 50), 
+      (190 50, 230 110, 290 50, 190 50))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/A2h-3-2: a point on the touching point of two holes in a polygon [dim(0){A.P.Int = B.A.iBdy.TP}]</desc>
+  <a>
+    POINT(180 90)
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (180 140, 180 40, 80 40, 180 140), 
+      (180 90, 210 140, 310 40, 230 40, 180 90))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/A-2: 3 points outside a polygon [dim(0){A.2P.Int = B.A.Ext}]</desc>
+  <a>
+    MULTIPOINT((20 80), (110 160), (20 160))
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/A-3-1: one of 3 points on the closing point of the boundary of a polygon [dim(0){A.3P1.Int = B.A.Bdy.CP}]</desc>
+  <a>
+    MULTIPOINT((20 80), (60 120), (20 160))
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F00FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/A-3-2: one of 3 points on the boundary of a polygon at a non-vertex [dim(0){A.3P3 = B.A.Bdy.NV}]</desc>
+  <a>
+    MULTIPOINT((10 80), (110 170), (110 120))
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F00FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/A-3-3: one of 3 points on the boundary of a polygon at a vertex [dim(0){A.3P1.Int = B.A.Bdy.V}]</desc>
+  <a>
+    MULTIPOINT((10 80), (110 170), (160 120))
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F00FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/A-3-4: 3 of the 5 points on the boundary of a polygon [dim(0){A.5P2.Int = B.A.Bdy.CP}, dim(0){A.5P3.Int = B.A.Bdy.NV}, dim(0){A.5P4.Int = B.A.Bdy.V}]</desc>
+  <a>
+    MULTIPOINT((20 120), (60 120), (110 120), (160 120), (200 120))
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F00FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/A-3-5: all 3 points on the boundary of a polygon [dim(0){A.3P1.Int = B.A.Bdy.CP}, dim(0){A.3P2.Int = B.A.Bdy.NV}, dim(0){A.3P3.Int = B.A.Bdy.V}]</desc>
+  <a>
+    MULTIPOINT((60 120), (110 120), (160 120))
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/A-3-6: all 4 points on the boundary of a polygon [dim(0){A.4P = B.A.Bdy}]</desc>
+  <a>
+    MULTIPOINT((60 120), (160 120), (160 40), (60 40))
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/A-4-1: 1 point outside a polygon, 1 point on the boundary and 1 point inside [dim(0){A.3P1.Int = B.A.Ext}, dim(0){A.3P2.Int = B.A.Bdy.CP}, dim(0){A.3P3.Int = B.A.Int}]</desc>
+  <a>
+    MULTIPOINT((20 150), (60 120), (110 80))
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="000FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/A-4-2: 1 point outside a polygon, 1 point on the boundary and 1 point inside [dim(0){A.3P1.Int = B.A.Ext}, dim(0){A.3P2.Int = B.A.Bdy.V}, dim(0){A.3P3.Int = B.A.Int}]</desc>
+  <a>
+    MULTIPOINT((110 80), (160 120), (200 160))
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="000FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/A-4-3: 1 point outside a polygon, 1 point on the boundary and 1 point inside [dim(0){A.3P1.Int = B.A.Ext}, dim(0){A.3P2.Int = B.A.Bdy.NV}, dim(0){A.3P3.Int = B.A.Int}]</desc>
+  <a>
+    MULTIPOINT((110 80), (110 120), (110 160))
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="000FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/A-4-4: 1 point outside a polygon, 1 point inside [dim(0){A.2P1.Int = B.A.Ext}, dim(0){A.2P2.Int = B.A.Int}]</desc>
+  <a>
+    MULTIPOINT((110 170), (110 80))
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F0FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/A-4-5: 1 point outside a polygon, 2 points on the boundary and 1 point inside [dim(0){A.4P1.Int = B.A.Ext}, dim(0){A.4P2.Int = B.A.Bdy.CP}, dim(0){A.4P3.Int = B.A.Bdy.V}, dim(0){A.4P4.Int = B.A.Int}]</desc>
+  <a>
+    MULTIPOINT((60 120), (160 120), (110 80), (110 170))
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="000FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/A-5-1: 2 points within a polygon [dim(0){A.2P.Int = B.A.Int]</desc>
+  <a>
+    MULTIPOINT((90 80), (130 80))
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mP/A-5-2: 1 point on the boundary and 1 point inside a polygon [dim(0){A.2P1.Int = B.A.Bdy.CP}, dim(0){A.2P2.Int = B.A.Int}]</desc>
+  <a>
+    MULTIPOINT((60 120), (160 120), (110 80))
+  </a>
+  <b>
+    POLYGON(
+      (60 120, 60 40, 160 40, 160 120, 60 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="00FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mP/Ah-2-1: 3 points outside a polygon [dim(0){A.3P.Int = B.Ah.Ext}]</desc>
+  <a>
+    MULTIPOINT((40 170), (40 90), (130 170))
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (280 50, 100 50, 190 140, 280 50))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/Ah-2-2: 2 points outside a polygon and 1 point inside the hole of the polygon [dim(0){A.3P1.Int = B.Ah.Ext}, dim(0){A.3P2.Int = B.Ah.Ext}, dim(0){A.3P3.Int = B.Ah.Ext.h}]</desc>
+  <a>
+    MULTIPOINT((90 170), (280 170), (190 90))
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (280 50, 100 50, 190 140, 280 50))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/Ah-2-3: all 3 points in polygon's hole [dim(0){A.3P.Int = B.Ah.Ext.h}]</desc>
+  <a>
+    MULTIPOINT((190 110), (150 70), (230 70))
+  </a>
+  <b>
+    POLYGON(
+      (190 190, 360 20, 20 20, 190 190), 
+      (280 50, 100 50, 190 140, 280 50))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/mA-3-1: a point on the touching point of two polygons [dim(0){A.P.Int = B.2A.Bdy}]</desc>
+  <a>
+    POINT(100 100)
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (20 100, 20 20, 100 20, 100 100, 20 100)), 
+      (
+        (100 180, 100 100, 180 100, 180 180, 100 180)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/mA-3-2: a point on the boundary of one of the 2 polygons [dim(0){A.P.Int = B.2A1.Bdy.CP}]</desc>
+  <a>
+    POINT(20 100)
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (20 100, 20 20, 100 20, 100 100, 20 100)), 
+      (
+        (100 180, 100 100, 180 100, 180 180, 100 180)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/mA-3-3: a point on the boundary of one of the 2 polygons [dim(0){A.P.Int = B.2A1.Bdy.V}]</desc>
+  <a>
+    POINT(60 100)
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (20 100, 20 20, 100 20, 100 100, 20 100)), 
+      (
+        (100 180, 100 100, 180 100, 180 180, 100 180)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/mA-3-4: a point touching a polygon's boundary where the boundaries touch at a point [dim(0){A.P.Int = B.2A.Bdy.TP}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    MULTIPOLYGON(
+      (
+        (110 110, 20 200, 200 200, 110 110), 
+        (110 110, 80 180, 140 180, 110 110)), 
+      (
+        (110 110, 20 20, 200 20, 110 110), 
+        (110 110, 80 40, 140 40, 110 110)))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF212">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+</run>
diff --git a/tests/xmltester/tests/validate/TestRelatePL.xml b/tests/xmltester/tests/validate/TestRelatePL.xml
new file mode 100644
index 0000000..2e11fb7
--- /dev/null
+++ b/tests/xmltester/tests/validate/TestRelatePL.xml
@@ -0,0 +1,2286 @@
+<run>
+<precisionModel type="FLOATING"/>
+
+<case>
+<desc>P/L-2: a point and a line disjoint [dim(0){A.P.Int = B.L.Ext}]</desc>
+  <a>
+    POINT(110 200)
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/L-2: a point and a zero-length line </desc>
+  <a>
+    POINT(110 200)
+  </a>
+  <b>
+    LINESTRING(110 200, 110 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFFFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/L-3-1: a point touching the start point of a line  [dim(0){A.P.Int = B.L.Bdy.SP}]</desc>
+  <a>
+    POINT(90 80)
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/L-3-2: a point touching the end point of a line [dim(0){A.P.Int = B.L.Bdy.EP}]</desc>
+  <a>
+    POINT(340 240)
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/L-5-1: a point on the line at a non-vertex [dim(0){A.P.Int = B.L.Int.NV}]</desc>
+  <a>
+    POINT(230 150)
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/L-5-2: a point on the line at a vertex [dim(0){A.P.Int = B.L.Int.V}]</desc>
+  <a>
+    POINT(160 150)
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/LR-2-1: a point outside a LinearRing [dim(0){A.P.Int = B.LR.Ext}]</desc>
+  <a>
+    POINT(90 150)
+  </a>
+  <b>
+    LINESTRING(150 150, 20 20, 280 20, 150 150)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/LR-2-2: a point inside a LinearRing  [dim(0){A.P.Int = B.LR.Ext}]</desc>
+  <a>
+    POINT(150 80)
+  </a>
+  <b>
+    LINESTRING(150 150, 20 20, 280 20, 150 150)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/LR-5-1: a point on the closing point of a LinearRing [dim(0){A.P.Int = B.LR.Int.CP}]</desc>
+  <a>
+    POINT(150 150)
+  </a>
+  <b>
+    LINESTRING(150 150, 20 20, 280 20, 150 150)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/LR-5-2: a point on a LinearRing at a non-vertex [dim(0){A.P.Int = B.L.Int.NV}]</desc>
+  <a>
+    POINT(100 20)
+  </a>
+  <b>
+    LINESTRING(150 150, 20 20, 280 20, 150 150)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/LR-5-3: a point on a LinearRing at a vertex [dim(0){A.P.Int = B.L.Int.V}]</desc>
+  <a>
+    POINT(20 20)
+  </a>
+  <b>
+    LINESTRING(150 150, 20 20, 280 20, 150 150)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.1-3-1: a point on a non-simple LineString's end point [dim(0){A.P.Int = B.nsL.Bdy.EP}]</desc>
+  <a>
+    POINT(220 220)
+  </a>
+  <b>
+    LINESTRING(110 110, 220 20, 20 20, 110 110, 220 220)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.1-5-1: a point on a non-simple LineString's start point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.SPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 220 20, 20 20, 110 110, 220 220)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.1-5-2: a point a non-simple LineString's start point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.SPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 220 20, 20 20, 220 220)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.1-5-3: a point on a non-simple LineString's interior at a non-vertex [dim(0){A.P.Int = B.nsL.Int.NV}]</desc>
+  <a>
+    POINT(110 20)
+  </a>
+  <b>
+    LINESTRING(110 110, 220 20, 20 20, 220 220)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.1-5-4: a point on a non-simple LineString's interior at a vertex [dim(0){A.P.Int = B.nsL.Int.V}]</desc>
+  <a>
+    POINT(220 20)
+  </a>
+  <b>
+    LINESTRING(110 110, 220 20, 20 20, 220 220)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.2-5-2: a point on a non-simple LineString's interior at a vertex [dim(0){A.P.Int = B.nsL.Int.NV}]</desc>
+  <a>
+    POINT(110 20)
+  </a>
+  <b>
+    LINESTRING(220 220, 20 20, 220 20, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.2-5-3: a point on a non-simple LineString's interior at a vertex [dim(0){A.P.Int = B.nsL.Int.V}]</desc>
+  <a>
+    POINT(20 20)
+  </a>
+  <b>
+    LINESTRING(220 220, 20 20, 220 20, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.2-5-4: a point on a non-simple LineString's interior at a vertex with crossing line segments [dim(0){A.P.Int = B.nsL.Int.Vx}]</desc>
+  <a>
+    POINT(20 110)
+  </a>
+  <b>
+    LINESTRING(20 200, 20 20, 110 20, 20 110, 110 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.3-3-1: a point on a non-simple LineString's start point [dim(0){A.P.Int = B.nsL.Bdy.SP}]</desc>
+  <a>
+    POINT(20 200)
+  </a>
+  <b>
+    LINESTRING(20 200, 200 20, 20 20, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.3-5-1: a point on a non-simple LineString's interior at a non-vertex with overlapping line segments [dim(0){A.P.Int = B.nsL.Int.NVo}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(20 200, 200 20, 140 20, 140 80, 80 140, 20 140)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.3-5-2: a point on a non-simple LineString's interior at a non-vertex with crossing line segments [dim(0){A.P.Int = B.nsL.Int.NVx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(20 200, 200 20, 20 20, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.3-5-3: a point on a non-simple LineString's interior at a vertex with both crossing and overlapping line segments [dim(0){A.P.Int = B.nsL.Int.Vb}]</desc>
+  <a>
+    POINT(80 140)
+  </a>
+  <b>
+    LINESTRING(20 200, 110 110, 200 20, 140 20, 140 80, 110 110, 80 140, 20 140)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.3-5-4: a point on a non-simple LineString's interior at a two-vertex point with overlapping line segments [dim(0){A.P.Int = B.nsL.Int.Vo}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(20 200, 110 110, 200 20, 140 20, 140 80, 110 110, 80 140, 20 140)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.3-5-5: a point on a non-simple LineString's interior at a vertex with overlapping line segments [dim(0){A.P.Int = B.nsL.Int.Vo}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(20 200, 200 20, 140 20, 140 80, 110 110, 80 140, 20 140)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.3-5-6: a point on a non-simple LineString's interior at a two-vertex point with crossing line segments [dim(0){A.P.Int = B.nsL.Int.Vx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(20 200, 110 110, 200 20, 20 20, 110 110, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.3-5-7: a point on a non-simple LineString's interior at a vertex with crossing line segments [dim(0){A.P.Int = B.nsL.Int.Vx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(20 200, 200 20, 20 20, 110 110, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.3-5-8: a point on a non-simple LineString's interior at a two-vertex point with crossing line segments [dim(0){A.P.Int = B.nsL.Int.Vx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(20 200, 110 110, 20 20, 200 20, 110 110, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.4-3-1: a point on a non-simple LineString's start point with crossing and overlapping line segments [dim(0){A.P.Int = B.nsL.Bdy.SPb}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 110 200, 20 200, 110 110, 200 20, 140 20, 140 80, 110 110, 80 140, 
+    20 140)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.4-3-2: a point on a non-simple LineString's start point with crossing and overlapping line segments [dim(0){A.P.Int = B.nsL.Bdy.SPb}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 110 200, 20 200, 200 20, 140 20, 140 80, 110 110, 80 140, 20 140)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.4-3-3:a point on a non-simple LineString's start point with crossing and overlapping line segments [dim(0){A.P.Int = B.nsL.Bdy.SPb}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 110 200, 20 200, 200 20, 140 20, 140 80, 80 140, 20 140)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.4-3-4: a point on a non-simple LineString's start point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.SPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 110 200, 20 200, 110 110, 200 20, 20 20, 110 110, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.4-3-5: a point on a non-simple LineString's start point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.SPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 110 200, 20 200, 200 20, 20 20, 110 110, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.4-3-6: a point on a non-simple LineString's start point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.SPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 110 200, 20 200, 200 20, 20 20, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.4-3-7: a point on a non-simple LineString's start point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.SPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 110 200, 20 200, 110 110, 20 20, 200 20, 110 110, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.4-3-8: a point on a non-simple LineString's start point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.SPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 110 200, 20 200, 200 20, 200 110, 110 110, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.5-3-1: a point on a non-simple LineString's end point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.EPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(200 200, 110 110, 20 20, 200 20, 110 110, 20 200, 110 200, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.5-3-2: a point on a non-simple LineString's end point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.EPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(200 200, 20 20, 200 20, 110 110, 20 200, 110 200, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.5-3-3: a point on a non-simple LineString's end point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.EPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(200 200, 20 20, 200 20, 20 200, 110 200, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.5-3-4: a point on a non-simple LineString's end point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.EPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(200 200, 110 110, 200 20, 20 20, 110 110, 20 200, 110 200, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.5-3-5: a point on a non-simple LineString's end point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.EPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(200 200, 20 20, 20 110, 110 110, 20 200, 110 200, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.6-3-1: a point on a non-simple LineString's start point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.SPx}]</desc>
+  <a>
+    POINT(110 160)
+  </a>
+  <b>
+    LINESTRING(110 160, 200 250, 110 250, 110 160, 110 110, 110 20, 20 20, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.6-3-2: a point on a non-simple LineString's start point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.SPx}]</desc>
+  <a>
+    POINT(110 160)
+  </a>
+  <b>
+    LINESTRING(110 160, 200 250, 110 250, 110 110, 110 20, 20 20, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.6-3-3: a point on a non-simple LineString's end point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.EPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 160, 200 250, 110 250, 110 160, 110 110, 110 20, 20 20, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.6-3-4: a point on a non-simple LineString's end point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.EPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 160, 200 250, 110 250, 110 160, 110 20, 20 20, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.7-5-1: a point on a closed non-simple LineString's closing point with crossing line segments [dim(0){A.P.Int = B.nsL.Int.CPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 200 200, 110 200, 110 110, 110 20, 20 20, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.7-5-2: a point on a closed non-simple LineString's closing point with crossing line segments [dim(0){A.P.Int = B.nsL.Int.CPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 200 200, 110 200, 110 20, 20 20, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.7-5-3: a point on a closed non-simple LineString's interior at a non-vertex [dim(0){A.P.Int = B.nsL.Int.NV}]</desc>
+  <a>
+    POINT(140 200)
+  </a>
+  <b>
+    LINESTRING(110 110, 200 200, 110 200, 110 110, 110 20, 20 20, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.7-5-4: a point on a closed non-simple LineString's interior at a vertex [dim(0){A.P.Int = B.nsL.Int.V}]</desc>
+  <a>
+    POINT(110 200)
+  </a>
+  <b>
+    LINESTRING(110 110, 200 200, 110 200, 110 110, 110 20, 20 20, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.8-5-1: a point on a closed non-simple LineString's closing point with crossing line segments [dim(0){A.P.Int = B.nsL.Int.CPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 200 200, 110 200, 110 110, 110 20, 200 20, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.8-5-2: a point on the interior (at a non-vertex) of a closed non-simple LineString [dim(0){A.P.Int = B.nsL.Int.NV}]</desc>
+  <a>
+    POINT(140 200)
+  </a>
+  <b>
+    LINESTRING(110 110, 200 200, 110 200, 110 110, 110 20, 200 20, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.8-5-3: a point on a closed non-simple LineString's interior at a vertex [dim(0){A.P.Int = B.nsL.Int.V}]</desc>
+  <a>
+    POINT(110 200)
+  </a>
+  <b>
+    LINESTRING(110 110, 200 200, 110 200, 110 110, 110 20, 200 20, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.9-3-1: a point on a non-simple LineString's start point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.SPx}]</desc>
+  <a>
+    POINT(90 130)
+  </a>
+  <b>
+    LINESTRING(90 130, 20 130, 20 200, 90 130, 200 20, 20 20, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.9-5-1: a point on a non-simple LineString's interior at a non-vertex with crossing line segments [dim(0){A.P.Int = B.nsL.Int.NVx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(90 130, 20 130, 20 200, 90 130, 200 20, 20 20, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.10-3-1: a point on a non-simple LineString's start point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.SPx}]</desc>
+  <a>
+    POINT(90 130)
+  </a>
+  <b>
+    LINESTRING(90 130, 20 130, 20 200, 200 20, 20 20, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.10-5-1: a point on a non-simple LineString's interior at a non-vertex with crossing line segments [dim(0){A.P.Int = B.nsL.Int.NVx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(90 130, 20 130, 20 200, 200 20, 20 20, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.11-3-1: a point on a closed non-simple LineString's end point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.EPx}]</desc>
+  <a>
+    POINT(90 130)
+  </a>
+  <b>
+    LINESTRING(200 200, 20 20, 200 20, 90 130, 20 200, 20 130, 90 130)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.11-5-1: a point on a closed non-simple LineString's interior at a non-vertex with crossing line segments [dim(0){A.P.Int = B.nsL.Int.NVx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(200 200, 20 20, 200 20, 90 130, 20 200, 20 130, 90 130)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.12-3-1: a point on a closed non-simple LineString's end point with crossing line segments [dim(0){A.P.Int = B.nsL.Bdy.SPx}]</desc>
+  <a>
+    POINT(90 130)
+  </a>
+  <b>
+    LINESTRING(200 200, 20 20, 200 20, 20 200, 20 130, 90 130)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.12-5-1: a point on a closed non-simple LineString's interior at a non-vertex with crossing line segments [dim(0){A.P.Int = B.nsL.Int.NVx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(200 200, 20 20, 200 20, 20 200, 20 130, 90 130)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.13-5-1: a point on a closed non-simple LineString's closing point with crossing line segments [dim(0){A.P.Int = B.nsL.Int.CPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 20 130, 20 200, 110 110, 200 20, 20 20, 110 110, 200 200, 200 130, 
+    110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.13-5-2: a point on a closed non-simple LineString's closing point with crossing line segments [dim(0){A.P.Int = B.nsL.Int.CPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 20 130, 20 200, 200 20, 20 20, 200 200, 200 130, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.14-5-1: a point on a closed non-simple LineString's closing point with crossing line segments [dim(0){A.P.Int = B.nsL.Int.CPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 80 200, 20 200, 110 110, 200 20, 20 20, 110 110, 200 200, 140 200, 
+    110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.14-5-2: a point on a closed non-simple LineString's closing point with crossing line segments [dim(0){A.P.Int = B.nsL.Int.CPx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 110, 80 200, 20 200, 200 20, 20 20, 200 200, 140 200, 110 110)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.15-5-1: a point on a closed non-simple LineString's interior at a non-vertex with crossing line segments [dim(0){A.P.Int = B.nsL.Int.NVx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(200 200, 20 20, 200 20, 20 200, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.15-5-2: a point on a closed non-simple LineString's interior at a vertex with crossing line segments [dim(0){A.P.Int = B.nsL.Int.Vx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(200 200, 110 110, 20 20, 200 20, 110 110, 20 200, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.15-5-3: a point on a closed non-simple LineString's interior at a vertex with crossing line segments [dim(0){A.P.Int = B.nsL.Int.Vx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(200 200, 110 110, 200 20, 20 20, 110 110, 20 200, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.16-5-1: a point on a closed non-simple LineString's closing point with crossing line segments [dim(0){A.P.Int = B.nsL.Int.CPx}]</desc>
+  <a>
+    POINT(90 130)
+  </a>
+  <b>
+    LINESTRING(90 130, 20 130, 20 200, 90 130, 110 110, 200 20, 20 20, 110 110, 200 200, 
+    90 130)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.16-5-2: a point on a closed non-simple LineString's closing point with crossing line segments [dim(0){A.P.Int = B.nsL.Int.CPx}]</desc>
+  <a>
+    POINT(90 130)
+  </a>
+  <b>
+    LINESTRING(90 130, 20 130, 20 200, 110 110, 200 20, 20 20, 110 110, 200 200, 90 130)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.17-5-1: a point on a closed non-simple LineString's closing point with crossing line segments [dim(0){A.P.Int = B.nsL.Int.CPx}]</desc>
+  <a>
+    POINT(90 130)
+  </a>
+  <b>
+    LINESTRING(90 130, 90 200, 20 200, 90 130, 110 110, 200 20, 20 20, 110 110, 200 200, 
+    90 130)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.17-5-2: a point on a closed non-simple LineString's closing point with crossing line segments [dim(0){A.P.Int = B.nsL.Int.CPx}]</desc>
+  <a>
+    POINT(90 130)
+  </a>
+  <b>
+    LINESTRING(90 130, 90 200, 20 200, 200 20, 20 20, 200 200, 90 130)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.17-5-3: a point on a closed non-simple LineString's closing point with crossing line segments [dim(0){A.P.Int = B.nsL.Int.CPx}]</desc>
+  <a>
+    POINT(90 130)
+  </a>
+  <b>
+    LINESTRING(90 130, 90 200, 20 200, 110 110, 200 20, 20 20, 110 110, 200 200, 90 130)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.17-5-4: a point on a closed non-simple LineString's closing point with crossing line segments [dim(0){A.P.Int = B.nsL.Int.CPx}]</desc>
+  <a>
+    POINT(90 130)
+  </a>
+  <b>
+    LINESTRING(90 130, 90 200, 20 200, 200 20, 20 20, 200 200, 90 130)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.17-5-5: a point on a closed non-simple LineString's interior at a non-vertex with crossing line segments [dim(0){A.P.Int = B.nsL.Int.NVx}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(90 130, 90 200, 20 200, 200 20, 20 20, 200 200, 90 130)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.18-5-1: a point on a non-simple LineString's start point with both crossing and overlapping line segments [dim(0){A.P.Int = B.nsL.Bdy.SPb)}]</desc>
+  <a>
+    POINT(110 200)
+  </a>
+  <b>
+    LINESTRING(110 200, 110 110, 20 20, 200 20, 110 110, 110 200, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F0FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/nsL.18-5-2: a point on a non-simple LineString's interior at a non-vertex with overlapping line segments [dim(0){A.P.Int = B.nsL.Int.NVo}]</desc>
+  <a>
+    POINT(110 150)
+  </a>
+  <b>
+    LINESTRING(110 200, 110 110, 20 20, 200 20, 110 110, 110 200, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.18-5-3: a point on a non-simple LineString's interior at a vertex with both crossing and overlapping line segments [dim(0){A.P.Int = B.nsL.Int.Vb}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 200, 110 110, 20 20, 200 20, 110 110, 110 200, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.19-5-1: a point on a non-simple LineString's closing point with overlapping line segments [dim(0){A.P.Int = B.nsL.Int.CPo}]</desc>
+  <a>
+    POINT(110 200)
+  </a>
+  <b>
+    LINESTRING(110 200, 110 110, 20 20, 200 20, 110 110, 110 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.19-5-2: a point on a non-simple LineString's interior at a non-vertex overlapping line segments [dim(0){A.P.Int = B.nsL.Int.NVo}]</desc>
+  <a>
+    POINT(110 150)
+  </a>
+  <b>
+    LINESTRING(110 200, 110 110, 20 20, 200 20, 110 110, 110 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.19-5-3: a point on a non-simple LineString interior at a vertex with both crossing and overlapping line segments [dim(0){A.P.Int = B.nsL.Int.Vb}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(110 200, 110 110, 20 20, 200 20, 110 110, 110 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.20-5-1: a point on a non-simple LineString's interior at a non-vertex with overlapping line segments [dim(0){A.P.Int = B.nsL.Int.NVo}]</desc>
+  <a>
+    POINT(110 150)
+  </a>
+  <b>
+    LINESTRING(20 200, 110 200, 110 110, 20 20, 200 20, 110 110, 110 200, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsL.20-5-2: a point on a non-simple LineString's interior at a vertex with both crossing and overlapping line segments [dim(0){A.P.Int = B.nsL.Int.Vb}]</desc>
+  <a>
+    POINT(110 110)
+  </a>
+  <b>
+    LINESTRING(20 200, 110 200, 110 110, 20 20, 200 20, 110 110, 110 200, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/nsl.20-5-3: a point on a non-simple LineString's interior at a vertex with both crossing and overlapping line segments [dim(0){A.P.Int = B.nsL.Int.Vb}]</desc>
+  <a>
+    POINT(110 200)
+  </a>
+  <b>
+    LINESTRING(20 200, 110 200, 110 110, 20 20, 200 20, 110 110, 110 200, 200 200)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mP/L-2-1: MultiPoint and a line disjoint (points on one side of the line) [dim(0){A.3P.Int = B.L.Ext}]</desc>
+  <a>
+    MULTIPOINT((50 250), (90 220), (130 190))
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/L-2-2: MultiPoint and a line disjoint (points over the line but no intersection) [dim(0){A.3P.Int = B.L.Ext}]</desc>
+  <a>
+    MULTIPOINT((180 180), (230 130), (280 80))
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/L-3-1: one of the points intersecting the start point of a line [dim(0){A.3P2.Int = B.L.Bdy.SP}]</desc>
+  <a>
+    MULTIPOINT((50 120), (90 80), (130 40))
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F00FFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/L-3-2: one of the points intersecting the end point of a line [dim(0){A.3P2 = B.L.Bdy.EP}]</desc>
+  <a>
+    MULTIPOINT((300 280), (340 240), (380 200))
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="F00FFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">true</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/L-4-1: one of the points intersecting the interior of a line at a non-vertex (points on one side of the line) [dim(0){A.3P1.Int = B.L.Int.NV]</desc>
+  <a>
+    MULTIPOINT((230 150), (260 120), (290 90))
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F0FFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/L-4-2: one of the points intersecting the interior of a line at a non-vertex (points over the line) [dim(0){A.3P2.Int = B.L.Int.NV]</desc>
+  <a>
+    MULTIPOINT((200 190), (240 150), (270 110))
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F0FFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/L-4-3: one of the points intersecting the interior of a line at a vertex (points on one side of the line) [dim(0){A.3P1.Int = B.L.Int.V]</desc>
+  <a>
+    MULTIPOINT((160 150), (190 120), (220 90))
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F0FFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/L-4-4: one of the points intersecting the interior of a line at a vertex (points over the line) [dim(0){A.3P2.Int = B.L.Int.V]</desc>
+  <a>
+    MULTIPOINT((120 190), (160 150), (200 110))
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F0FFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">true</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/L-5-1: all the points on a line [dim(0){A.3P1.Int = B.L.Bdy.SP}, dim(0){A.3P2.Int = B.L.Int.V}, dim(0){A.3P3.Int = B.Bdy.EP}]</desc>
+  <a>
+    MULTIPOINT((90 80), (160 150), (340 240))
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="00FFFF1F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mP/L-5-2: all the points on a line [dim(0){A.3P1.Int = B.L.Bdy.SP}, dim(0){A.3P2.Int = B.L.Int.V}, dim(0){A.3P3.Int = B.Int.V}]</desc>
+  <a>
+    MULTIPOINT((90 80), (160 150), (300 150))
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="00FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mP/L-5-3: all the points on a line [dim(0){A.3P1.Int = B.L.Bdy.SP}, dim(0){A.3P2.Int = B.L.Int.V}, dim(0){A.3P3.Int = B.Int.NV}]</desc>
+  <a>
+    MULTIPOINT((90 80), (160 150), (240 150))
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="00FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mP/L-5-4: all the points on a line [dim(0){A.3P1.Int = B.L.Bdy.SP}, dim(0){A.3P2.Int = B.L.Int.NV}, dim(0){A.3P3.Int = B.Int.NV}]</desc>
+  <a>
+    MULTIPOINT((90 80), (130 120), (210 150))
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="00FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mP/L-5-5: all the points on a line [dim(0){A.3P1.Int = B.L.Int.NV}, dim(0){A.3P2.Int = B.L.Int.NV}, dim(0){A.3P3.Int = B.Int.NV}]</desc>
+  <a>
+    MULTIPOINT((130 120), (210 150), (340 200))
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mP/L-5-6: all the points on a line [dim(0){A.3P1.Int = B.L.Int.V}, dim(0){A.3P2.Int = B.L.Int.V}, dim(0){A.3P3.Int = B.Int.NV}]</desc>
+  <a>
+    MULTIPOINT((160 150), (240 150), (340 210))
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mP/L-5-7: all the points on a line [dim(0){A.3P1.Int = B.L.Int.V}, dim(0){A.3P2.Int = B.L.Int.V}, dim(0){A.3P3.Int = B.Int.V}]</desc>
+  <a>
+    MULTIPOINT((160 150), (300 150), (340 150))
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mP/L-5-8: all the points on a line [dim(0){A.3P1.Int = B.L.Int.V}, dim(0){A.3P2.Int = B.L.Int.NV}, dim(0){A.3P3.Int = B.Bdy.EP}]</desc>
+  <a>
+    MULTIPOINT((160 150), (240 150), (340 240))
+  </a>
+  <b>
+    LINESTRING(90 80, 160 150, 300 150, 340 150, 340 240)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="00FFFF102">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+</run>
diff --git a/tests/xmltester/tests/validate/TestRelatePP.xml b/tests/xmltester/tests/validate/TestRelatePP.xml
new file mode 100644
index 0000000..847908e
--- /dev/null
+++ b/tests/xmltester/tests/validate/TestRelatePP.xml
@@ -0,0 +1,303 @@
+<run>
+<precisionModel type="FLOATING"/>
+
+<case>
+<desc>P/P: same point [dim(0){A.P.Int = B.P.Int}]</desc>
+  <a>
+    POINT(20 20)
+  </a>
+  <b>
+    POINT(20 20)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFFFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>P/P: different point [dim(0){A.P.Int = B.P.Ext}]</desc>
+  <a>
+    POINT(20 20)
+  </a>
+  <b>
+    POINT(40 60)
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF0F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/mP: different points [dim(0){A.P.Int = B.3P.Ext}]</desc>
+  <a>
+    POINT(40 40)
+  </a>
+  <b>
+    MULTIPOINT((20 20), (80 80), (20 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF0F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>P/mP: point A within one of B points [dim(0){A.P.Int = B.3P1.Int}]</desc>
+  <a>
+    POINT(20 20)
+  </a>
+  <b>
+    MULTIPOINT((20 20), (80 80), (20 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFF0F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mP/mP-1-1: same points [dim(0){A.3P1.Int = B.3P1.Int}, dim(0){A.3P2.Int = B.3P2.Int}, dim(0){A.3P3.Int = B.3P3.Int}]</desc>
+  <a>
+    MULTIPOINT((40 40), (80 60), (120 100))
+  </a>
+  <b>
+    MULTIPOINT((40 40), (80 60), (120 100))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFFFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mP/mP-1-2: same but different sequence of points [dim(0){A.3P1.Int = B.3P1.Int}, dim(0){A.3P1.Int = B.3P3.Int}, dim(0){A.3P3.Int = B.3P2.Int}]</desc>
+  <a>
+    MULTIPOINT((40 40), (80 60), (120 100))
+  </a>
+  <b>
+    MULTIPOINT((40 40), (120 100), (80 60))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFFFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mP/mP-2: different points [dim(0){A.4P.Int = B.4P.Ext}]</desc>
+  <a>
+    MULTIPOINT((40 40), (60 100), (100 60), (120 120))
+  </a>
+  <b>
+    MULTIPOINT((20 120), (60 60), (100 100), (140 40))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="FF0FFF0F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">true</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">false</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/mP-5-1: same points [dim(0){A.4P.Int = B.4P.Int}]</desc>
+  <a>
+    MULTIPOINT((20 20), (80 70), (140 120), (200 170))
+  </a>
+  <b>
+    MULTIPOINT((20 20), (80 70), (140 120), (200 170))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFFFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mP/mP-5-2: same points but different sequence [dim(0){A.4P.Int = B.4P.Int}]</desc>
+  <a>
+    MULTIPOINT((20 20), (140 120), (80 70), (200 170))
+  </a>
+  <b>
+    MULTIPOINT((80 70), (20 20), (200 170), (140 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0FFFFFFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">true</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">true</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">true</op></test>
+</case>
+
+<case>
+<desc>mP/mP-5-3: some points same [dim(0){A.4P2.Int = B.2P1.Int}, dim(0){A.4P3.Int = B.2P2.Int}]</desc>
+  <a>
+    MULTIPOINT((20 20), (80 70), (140 120), (200 170))
+  </a>
+  <b>
+    MULTIPOINT((80 70), (140 120))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F0FFFFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/mP-5-4: some points same, in a different sequence [dim(0){A.4P1.Int = B.2P2.Int}, dim(0){A.4P4.Int = B.2P1.Int}]</desc>
+  <a>
+    MULTIPOINT((80 70), (20 200), (200 170), (140 120))
+  </a>
+  <b>
+    MULTIPOINT((140 120), (80 70))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F0FFFFF2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">true</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">true</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">false</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/mP-6-1: some points same, some different [dim(0){A.4P4.Int = B.3P2.Int}]</desc>
+  <a>
+    MULTIPOINT((80 70), (20 20), (200 170), (140 120))
+  </a>
+  <b>
+    MULTIPOINT((80 170), (140 120), (200 80))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F0FFF0F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+<case>
+<desc>mP/mP-6-2: dim(0){A.4P1.Int = B.4P4.Int}, dim(0){A.4P4.Int = B.4P2.Int}</desc>
+  <a>
+    MULTIPOINT((80 70), (20 20), (200 170), (140 120))
+  </a>
+  <b>
+    MULTIPOINT((80 170), (140 120), (200 80), (80 70))
+  </b>
+  <test>
+    <op name="relate" arg1="A" arg2="B" arg3="0F0FFF0F2">true</op>
+  </test>
+  <test><op name="contains"   arg1="A" arg2="B">false</op></test>
+  <test><op name="coveredBy"  arg1="A" arg2="B">false</op></test>
+  <test><op name="covers"     arg1="A" arg2="B">false</op></test>
+  <test><op name="crosses"    arg1="A" arg2="B">false</op></test>
+  <test><op name="disjoint"   arg1="A" arg2="B">false</op></test>
+  <test><op name="equalsTopo" arg1="A" arg2="B">false</op></test>
+  <test><op name="intersects" arg1="A" arg2="B">true</op></test>
+  <test><op name="overlaps"   arg1="A" arg2="B">true</op></test>
+  <test><op name="touches"    arg1="A" arg2="B">false</op></test>
+  <test><op name="within"     arg1="A" arg2="B">false</op></test>
+</case>
+
+</run>

-----------------------------------------------------------------------

Summary of changes:
 tests/xmltester/CMakeLists.txt                     |    9 +
 tests/xmltester/Makefile.am                        |  104 +-
 tests/xmltester/XMLTester.cpp                      |   72 +
 .../xmltester/tests/validate/TestRelateAA-big.xml  |   34 +
 tests/xmltester/tests/validate/TestRelateAA.xml    | 2833 ++++++++++++++++
 tests/xmltester/tests/validate/TestRelateAC.xml    |   36 +
 tests/xmltester/tests/validate/TestRelateLA.xml    | 1932 +++++++++++
 tests/xmltester/tests/validate/TestRelateLC.xml    |   57 +
 tests/xmltester/tests/validate/TestRelateLL.xml    | 3388 ++++++++++++++++++++
 tests/xmltester/tests/validate/TestRelatePA.xml    | 1018 ++++++
 tests/xmltester/tests/validate/TestRelatePL.xml    | 2286 +++++++++++++
 tests/xmltester/tests/validate/TestRelatePP.xml    |  303 ++
 12 files changed, 12025 insertions(+), 47 deletions(-)
 create mode 100644 tests/xmltester/tests/validate/TestRelateAA-big.xml
 create mode 100644 tests/xmltester/tests/validate/TestRelateAA.xml
 create mode 100644 tests/xmltester/tests/validate/TestRelateAC.xml
 create mode 100644 tests/xmltester/tests/validate/TestRelateLA.xml
 create mode 100644 tests/xmltester/tests/validate/TestRelateLC.xml
 create mode 100644 tests/xmltester/tests/validate/TestRelateLL.xml
 create mode 100644 tests/xmltester/tests/validate/TestRelatePA.xml
 create mode 100644 tests/xmltester/tests/validate/TestRelatePL.xml
 create mode 100644 tests/xmltester/tests/validate/TestRelatePP.xml


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list