[jts] 13/23: Imported Upstream version 1.13+ds

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Wed Aug 5 14:12:56 UTC 2015


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository jts.

commit 3b2a938a1a385d7fe031ad5218bde86f78d2f8ef
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Tue Aug 4 23:51:39 2015 +0200

    Imported Upstream version 1.13+ds
---
 bin/test_stmlf.bat                                 |    2 +-
 bin/testbuilder.bat                                |    4 +-
 bin/testbuilder.command                            |    7 +
 bin/testbuilder.sh                                 |   16 +-
 doc/JTS Version History.html                       |  158 ++-
 src/com/vividsolutions/jts/JTSVersion.java         |   37 +-
 src/com/vividsolutions/jts/algorithm/Angle.java    |    6 +-
 .../jts/algorithm/BoundaryNodeRule.java            |   21 +-
 .../vividsolutions/jts/algorithm/CGAlgorithms.java |  617 +++++----
 .../jts/algorithm/CGAlgorithms3D.java              |  182 +++
 .../jts/algorithm/CGAlgorithmsDD.java              |  206 +++
 .../jts/algorithm/CentralEndpointIntersector.java  |    5 +-
 .../vividsolutions/jts/algorithm/ConvexHull.java   |    5 +-
 .../jts/algorithm/InteriorPointArea.java           |    9 +-
 .../jts/algorithm/LineIntersector.java             |   34 +-
 .../jts/algorithm/MinimumBoundingCircle.java       |   67 +-
 .../jts/algorithm/MinimumDiameter.java             |    1 -
 .../jts/algorithm/NonRobustCGAlgorithms.java       |  100 ++
 .../jts/algorithm/RayCrossingCounter.java          |   24 +
 .../jts/algorithm/RectangleLineIntersector.java    |  165 +++
 .../jts/algorithm/RobustDeterminant.java           |   46 +
 .../jts/algorithm/RobustLineIntersector.java       |   12 +-
 .../jts/algorithm/match/AreaSimilarityMeasure.java |   33 +
 .../match/HausdorffSimilarityMeasure.java          |   33 +
 .../jts/algorithm/match/SimilarityMeasure.java     |   33 +
 .../algorithm/match/SimilarityMeasureCombiner.java |   33 +
 .../vividsolutions/jts/awt/FontGlyphReader.java    |   33 +
 src/com/vividsolutions/jts/awt/PolygonShape.java   |    1 +
 src/com/vividsolutions/jts/awt/ShapeReader.java    |   33 +
 src/com/vividsolutions/jts/awt/ShapeWriter.java    |  176 ++-
 src/com/vividsolutions/jts/geom/Coordinate.java    |   56 +-
 .../vividsolutions/jts/geom/CoordinateArrays.java  |   23 +
 .../jts/geom/CoordinateSequenceComparator.java     |   33 +
 .../jts/geom/CoordinateSequences.java              |   28 +-
 .../jts/geom/DefaultCoordinateSequence.java        |    5 +-
 src/com/vividsolutions/jts/geom/Dimension.java     |   54 +-
 src/com/vividsolutions/jts/geom/Envelope.java      |    6 +-
 src/com/vividsolutions/jts/geom/Geometry.java      |  322 +++--
 .../vividsolutions/jts/geom/GeometryFactory.java   |   81 +-
 .../jts/geom/IntersectionMatrix.java               |  131 +-
 src/com/vividsolutions/jts/geom/LineSegment.java   |   14 +-
 src/com/vividsolutions/jts/geom/Lineal.java        |   33 +
 src/com/vividsolutions/jts/geom/LinearRing.java    |   14 +-
 src/com/vividsolutions/jts/geom/MultiPolygon.java  |    4 +-
 src/com/vividsolutions/jts/geom/Point.java         |   10 +-
 src/com/vividsolutions/jts/geom/Polygon.java       |   36 +-
 src/com/vividsolutions/jts/geom/Polygonal.java     |   33 +
 .../vividsolutions/jts/geom/PrecisionModel.java    |   11 +-
 src/com/vividsolutions/jts/geom/Puntal.java        |   33 +
 src/com/vividsolutions/jts/geom/Triangle.java      |  590 +++++---
 .../jts/geom/impl/CoordinateArraySequence.java     |   59 +-
 .../geom/impl/CoordinateArraySequenceFactory.java  |    2 +-
 .../jts/geom/impl/PackedCoordinateSequence.java    |   20 +
 .../jts/geom/prep/PreparedGeometry.java            |    4 +
 .../jts/geom/prep/PreparedLineString.java          |    4 +-
 .../geom/prep/PreparedLineStringIntersects.java    |   14 +-
 .../jts/geom/prep/PreparedPoint.java               |    2 +
 .../jts/geom/prep/PreparedPolygon.java             |   11 +-
 .../jts/geom/prep/PreparedPolygonIntersects.java   |    9 +-
 .../jts/geom/prep/PreparedPolygonPredicate.java    |   33 +
 .../jts/geom/util/AffineTransformation.java        |   33 +
 .../jts/geom/util/AffineTransformationBuilder.java |   33 +
 .../jts/geom/util/AffineTransformationFactory.java |   33 +
 .../jts/geom/util/GeometryCollectionMapper.java    |   38 +-
 .../jts/geom/util/GeometryCombiner.java            |   33 +
 .../jts/geom/util/GeometryEditor.java              |   92 +-
 .../jts/geom/util/GeometryMapper.java              |    4 +-
 .../jts/geom/util/GeometryTransformer.java         |   35 +-
 .../jts/geom/util/LinearComponentExtracter.java    |    2 +
 .../util/NoninvertibleTransformationException.java |   33 +
 .../geom/util/ShortCircuitedGeometryVisitor.java   |   39 +-
 .../jts/geom/util/SineStarFactory.java             |   33 +
 src/com/vividsolutions/jts/geomgraph/Edge.java     |   12 +
 src/com/vividsolutions/jts/geomgraph/EdgeEnd.java  |    8 +
 .../vividsolutions/jts/geomgraph/EdgeEndStar.java  |   13 +
 .../jts/geomgraph/EdgeIntersection.java            |    4 +
 .../jts/geomgraph/GeometryGraph.java               |    3 +-
 src/com/vividsolutions/jts/geomgraph/Node.java     |    2 +
 .../vividsolutions/jts/index/ArrayListVisitor.java |   35 +-
 src/com/vividsolutions/jts/index/ItemVisitor.java  |   35 +-
 .../jts/index/chain/MonotoneChain.java             |    6 +
 .../jts/index/chain/MonotoneChainSelectAction.java |   14 +-
 .../intervalrtree/SortedPackedIntervalRTree.java   |    9 +-
 .../vividsolutions/jts/index/kdtree/KdTree.java    |   49 +-
 .../vividsolutions/jts/index/quadtree/Node.java    |   35 +-
 .../jts/index/quadtree/NodeBase.java               |   40 +-
 .../jts/index/quadtree/Quadtree.java               |   47 +-
 .../vividsolutions/jts/index/quadtree/Root.java    |    2 +-
 .../jts/index/strtree/AbstractNode.java            |   49 +-
 .../jts/index/strtree/AbstractSTRtree.java         |   99 +-
 .../jts/index/strtree/Boundable.java               |    1 -
 .../jts/index/strtree/BoundablePair.java           |    1 -
 .../jts/index/strtree/GeometryItemDistance.java    |   33 +
 .../jts/index/strtree/ItemBoundable.java           |    4 +-
 .../jts/index/strtree/ItemDistance.java            |   33 +
 .../vividsolutions/jts/index/strtree/STRtree.java  |   72 +-
 .../jts/io/ByteOrderDataInStream.java              |    4 +-
 src/com/vividsolutions/jts/io/InStream.java        |    2 +-
 src/com/vividsolutions/jts/io/OutStream.java       |    2 +-
 .../{WKTFileReader.java => WKBHexFileReader.java}  |   70 +-
 src/com/vividsolutions/jts/io/WKBReader.java       |   42 +-
 src/com/vividsolutions/jts/io/WKBWriter.java       |    8 +-
 src/com/vividsolutions/jts/io/WKTFileReader.java   |   33 +
 src/com/vividsolutions/jts/io/WKTReader.java       |   29 +-
 src/com/vividsolutions/jts/io/WKTWriter.java       |   19 +-
 src/com/vividsolutions/jts/io/gml2/GMLHandler.java |    4 +-
 src/com/vividsolutions/jts/io/gml2/GMLWriter.java  |    7 +-
 .../jts/linearref/ExtractLineByLocation.java       |   37 +-
 .../jts/linearref/LengthIndexOfPoint.java          |   38 +-
 .../jts/linearref/LengthIndexedLine.java           |   69 +-
 .../jts/linearref/LengthLocationMap.java           |  113 +-
 .../jts/linearref/LinearGeometryBuilder.java       |   39 +-
 .../jts/linearref/LinearIterator.java              |   42 +-
 .../jts/linearref/LinearLocation.java              |   77 +-
 .../jts/linearref/LocationIndexOfLine.java         |   35 +-
 .../jts/linearref/LocationIndexOfPoint.java        |   40 +-
 .../jts/linearref/LocationIndexedLine.java         |   47 +-
 src/com/vividsolutions/jts/math/DD.java            |  113 +-
 src/com/vividsolutions/jts/math/MathUtil.java      |   53 +
 src/com/vividsolutions/jts/math/Matrix.java        |    2 +-
 src/com/vividsolutions/jts/math/Plane3D.java       |  112 ++
 src/com/vividsolutions/jts/math/Vector2D.java      |   17 +-
 src/com/vividsolutions/jts/math/Vector3D.java      |  182 +++
 .../jts/noding/BasicSegmentString.java             |    6 +
 .../jts/noding/FastNodingValidator.java            |   14 +-
 .../noding/FastSegmentSetIntersectionFinder.java   |   33 +
 .../jts/noding/InteriorIntersectionFinder.java     |    2 +-
 .../jts/noding/IntersectionAdder.java              |    4 +-
 .../jts/noding/IntersectionFinderAdder.java        |    2 +-
 .../vividsolutions/jts/noding/IteratedNoder.java   |    1 -
 .../vividsolutions/jts/noding/MCIndexNoder.java    |    6 +-
 .../noding/MCIndexSegmentSetMutualIntersector.java |   13 +-
 .../jts/noding/NodableSegmentString.java           |   33 +
 .../jts/noding/NodedSegmentString.java             |    2 +
 src/com/vividsolutions/jts/noding/Octant.java      |   35 +-
 .../jts/noding/OrientedCoordinateArray.java        |    8 +-
 src/com/vividsolutions/jts/noding/ScaledNoder.java |   55 +-
 .../jts/noding/SegmentIntersectionDetector.java    |    2 +-
 .../jts/noding/SegmentIntersector.java             |    4 +-
 src/com/vividsolutions/jts/noding/SegmentNode.java |   16 +-
 .../vividsolutions/jts/noding/SegmentNodeList.java |    6 +-
 .../jts/noding/SegmentPointComparator.java         |   41 +-
 .../jts/noding/SegmentSetMutualIntersector.java    |    4 +-
 .../jts/noding/SegmentStringUtil.java              |   33 +
 .../vividsolutions/jts/noding/SinglePassNoder.java |    4 +
 .../jts/noding/snapround/GeometryNoder.java        |   43 +-
 .../jts/noding/snapround/HotPixel.java             |   43 +-
 .../jts/noding/snapround/MCIndexPointSnapper.java  |   82 +-
 .../jts/noding/snapround/MCIndexSnapRounder.java   |   12 +-
 .../vividsolutions/jts/operation/IsSimpleOp.java   |   94 +-
 .../jts/operation/buffer/BufferBuilder.java        |    9 +
 .../buffer/BufferInputLineSimplifier.java          |    2 +-
 .../jts/operation/buffer/BufferOp.java             |   29 +-
 .../jts/operation/buffer/BufferParameters.java     |   23 +-
 .../operation/buffer/OLDOffsetCurveBuilder.java    |  862 ------------
 .../jts/operation/buffer/OffsetCurveBuilder.java   |   13 +-
 .../operation/buffer/OffsetCurveSetBuilder.java    |    4 +
 .../operation/buffer/OffsetSegmentGenerator.java   |   10 +-
 .../jts/operation/buffer/SubgraphDepthLocater.java |    2 +-
 .../buffer/validate/BufferDistanceValidator.java   |    2 +-
 .../buffer/validate/BufferResultValidator.java     |    4 +-
 .../jts/operation/distance/DistanceOp.java         |    2 +-
 .../jts/operation/distance/FacetSequence.java      |   33 +
 .../distance/FacetSequenceTreeBuilder.java         |   35 +-
 .../operation/distance/IndexedFacetDistance.java   |   39 +-
 .../distance3d/AxisPlaneCoordinateSequence.java    |  159 +++
 .../jts/operation/distance3d/Distance3DOp.java     |  583 ++++++++
 .../jts/operation/distance3d/PlanarPolygon3D.java  |  195 +++
 .../operation/linemerge/LineMergeDirectedEdge.java |    2 +-
 .../jts/operation/linemerge/LineSequencer.java     |    2 +-
 .../overlay/ConsistentPolygonRingChecker.java      |   35 +-
 .../jts/operation/overlay/OverlayOp.java           |   40 +-
 .../jts/operation/overlay/PolygonBuilder.java      |    4 +-
 .../operation/overlay/snap/GeometrySnapper.java    |   36 +-
 .../operation/overlay/snap/LineStringSnapper.java  |   39 +-
 .../overlay/snap/SnapIfNeededOverlayOp.java        |   37 +-
 .../jts/operation/overlay/snap/SnapOverlayOp.java  |   35 +-
 .../overlay/validate/FuzzyPointLocator.java        |   35 +-
 .../overlay/validate/OffsetPointGenerator.java     |   35 +-
 .../jts/operation/polygonize/EdgeRing.java         |   35 +-
 .../jts/operation/polygonize/PolygonizeGraph.java  |    2 +-
 .../jts/operation/predicate/RectangleContains.java |   35 +-
 .../operation/predicate/RectangleIntersects.java   |  291 ++--
 .../predicate/SegmentIntersectionTester.java       |  100 --
 .../jts/operation/relate/RelateOp.java             |   14 +-
 .../jts/operation/union/CascadedPolygonUnion.java  |   67 +-
 .../jts/operation/union/PointGeometryUnion.java    |   33 +
 .../jts/operation/union/UnaryUnionOp.java          |   12 +-
 .../jts/operation/union/UnionInteracting.java      |   33 +
 .../jts/operation/valid/IsValidOp.java             |   14 +
 .../jts/planargraph/PlanarGraph.java               |    2 +-
 .../vividsolutions/jts/planargraph/Subgraph.java   |   35 +-
 .../algorithm/ConnectedSubgraphFinder.java         |   35 +-
 .../CoordinatePrecisionReducerFilter.java          |   33 +
 .../jts/precision/GeometryPrecisionReducer.java    |   24 +-
 .../jts/precision/MinimumClearance.java            |    6 +-
 .../jts/shape/GeometricShapeBuilder.java           |   33 +
 .../jts/shape/fractal/KochSnowflakeBuilder.java    |   33 +
 .../jts/shape/fractal/SierpinskiCarpetBuilder.java |   33 +
 .../jts/shape/random/RandomPointsBuilder.java      |   35 +-
 .../shape/random/RandomPointsInGridBuilder.java    |   71 +-
 .../jts/simplify/DouglasPeuckerLineSimplifier.java |   33 +
 .../jts/simplify/DouglasPeuckerSimplifier.java     |   38 +
 .../jts/simplify/LineSegmentIndex.java             |   33 +
 .../jts/simplify/TaggedLineSegment.java            |   35 +-
 .../jts/simplify/TaggedLineString.java             |   36 +-
 .../jts/simplify/TaggedLineStringSimplifier.java   |   47 +-
 .../jts/simplify/TaggedLinesSimplifier.java        |   43 +-
 .../jts/simplify/TopologyPreservingSimplifier.java |  104 +-
 .../ConformingDelaunayTriangulationBuilder.java    |   21 +-
 .../ConformingDelaunayTriangulator.java            |    4 +-
 .../triangulate/DelaunayTriangulationBuilder.java  |   11 +-
 .../NonEncroachingSplitPointFinder.java            |    2 +-
 .../VertexTaggedGeometryDataMapper.java            |   35 +-
 .../jts/triangulate/VoronoiDiagramBuilder.java     |    2 +-
 .../jts/triangulate/quadedge/QuadEdge.java         |    2 +-
 .../triangulate/quadedge/QuadEdgeSubdivision.java  |   22 +-
 .../jts/triangulate/quadedge/QuadEdgeTriangle.java |    6 +-
 .../triangulate/quadedge/TrianglePredicate.java    |   43 +-
 .../jts/triangulate/quadedge/Vertex.java           |   28 +-
 .../vividsolutions/jts/util/CollectionUtil.java    |   35 +-
 .../jts/util/GeometricShapeFactory.java            |    8 +-
 src/com/vividsolutions/jts/util/Memory.java        |    2 +-
 src/com/vividsolutions/jts/util/PriorityQueue.java |    3 +-
 testxml/external/GEOSBuffer.xml                    |   12 +
 testxml/external/TestBufferJagged.xml              |   75 +
 testxml/external/TestValid.xml                     |   26 +
 testxml/failure/TestBufferInsideNonEmpty.xml       |   22 +
 testxml/failure/TestOverlay.xml                    |   27 +
 .../{TestOverlay.xml => TestOverlayFailure.xml}    |   63 +
 testxml/general/TestCentroid.xml                   |   36 +-
 testxml/general/TestConvexHull.xml                 |   13 +-
 testxml/general/TestFunctionLA.xml                 |    2 +-
 testxml/general/TestFunctionLL.xml                 |    6 +-
 testxml/general/TestFunctionPP.xml                 |   14 +-
 testxml/general/TestInteriorPoint.xml              |   13 +
 testxml/general/TestOverlayEmpty.xml               | 1021 ++++++++++++++
 testxml/general/TestRectanglePredicate.xml         |  145 +-
 testxml/general/TestSimple.xml                     |   85 +-
 testxml/general/TestUnaryUnion.xml                 |   15 +-
 testxml/general/TestUnaryUnionFloating.xml         |   20 +
 testxml/robust/ExternalRobustness.xml              |   18 +-
 testxml/robust/TestRobustBuffer.xml                |   20 +
 testxml/validate/TestRelateAA.xml                  | 1070 +++++++++++++++
 testxml/validate/TestRelateAC.xml                  |   10 +
 testxml/validate/TestRelateLA.xml                  |  770 +++++++++++
 testxml/validate/TestRelateLC.xml                  |   20 +
 testxml/validate/TestRelateLL.xml                  | 1442 +++++++++++++++++++-
 testxml/validate/TestRelatePA.xml                  |  412 +++++-
 testxml/validate/TestRelatePL.xml                  |  982 ++++++++++++-
 testxml/validate/TestRelatePP.xml                  |  132 +-
 251 files changed, 14381 insertions(+), 2587 deletions(-)

diff --git a/bin/test_stmlf.bat b/bin/test_stmlf.bat
index 62dd5d4..1335594 100644
--- a/bin/test_stmlf.bat
+++ b/bin/test_stmlf.bat
@@ -13,7 +13,7 @@ for %%i in (..\lib\*.*) do (
  call :setclass
 )  
 
-java com.vividsolutions.jtstest.testrunner.TopologyTestApp -Files ..\testxml\stmlf -geomop com.vividsolutions.jtstest.testrunner.geomop.OverlayValidatedGeometryOperation
+java com.vividsolutions.jtstest.testrunner.TopologyTestApp -Files ..\testxml\stmlf -geomop com.vividsolutions.jtstest.geomop.OverlayValidatedGeometryOperation
 pause
 
 goto :eof
diff --git a/bin/testbuilder.bat b/bin/testbuilder.bat
index 52fed11..cf0a6ed 100644
--- a/bin/testbuilder.bat
+++ b/bin/testbuilder.bat
@@ -13,7 +13,9 @@ for %%i in (..\lib\*.*) do (
  call :setclass
 )  
 
-start javaw com.vividsolutions.jtstest.testbuilder.JTSTestBuilder
+set MEMSIZE=256
+
+start javaw -Xmx%MEMSIZE%M com.vividsolutions.jtstest.testbuilder.JTSTestBuilder
 
 goto :eof
 
diff --git a/bin/testbuilder.command b/bin/testbuilder.command
new file mode 100644
index 0000000..2940141
--- /dev/null
+++ b/bin/testbuilder.command
@@ -0,0 +1,7 @@
+#/bin/sh
+
+CDIR=`dirname "$0"`
+
+## run the basic script
+. "$CDIR/testbuilder.sh"
+
diff --git a/bin/testbuilder.sh b/bin/testbuilder.sh
index eba464f..a4f7a61 100644
--- a/bin/testbuilder.sh
+++ b/bin/testbuilder.sh
@@ -1,5 +1,13 @@
 #!/bin/sh
 
+#to change L&F if desired.  Blank is default
+JAVA_LOOKANDFEEL="-Dswing.defaultlaf=javax.swing.plaf.metal.MetalLookAndFeel"
+#JAVA_LOOKANDFEEL=""
+
+JAVA_OPTS="-Xms256M -Xmx1024M"
+
+APP_OPTS=""
+
 if test "x$JTS_LIB_DIR" = "x"; then
         JTS_LIB_DIR=`dirname $0`/../lib/
 fi
@@ -7,14 +15,14 @@ fi
 #---------------------------------#
 # dynamically build the classpath #
 #---------------------------------#
-THE_CLASSPATH=
+CP=
 for i in `ls ${JTS_LIB_DIR}/*.jar`
 do
-  THE_CLASSPATH=${THE_CLASSPATH}:${i}
+  CP=${CP}:${i}
 done
 
 #---------------------------#
 # run the program           #
 #---------------------------#
-java -cp ".:${THE_CLASSPATH}" \
-com.vividsolutions.jtstest.testbuilder.JTSTestBuilder
+MAIN=com.vividsolutions.jtstest.testbuilder.JTSTestBuilder
+java -cp ".:${CP}" $JAVA_OPTS  $JAVA_LOOKANDFEEL $MAIN $APP_OPTS
diff --git a/doc/JTS Version History.html b/doc/JTS Version History.html
index 50e1451..46d2f52 100644
--- a/doc/JTS Version History.html	
+++ b/doc/JTS Version History.html	
@@ -23,6 +23,160 @@ The current and archived JTS distributions can be obtained at the
 
 <!-- ================================================================ -->
 <hr size='4' color='darkblue'>
+<h2>Version 1.13</h2>
+
+<i>Release Date:  ????</i>
+
+<h3>Functionality Improvements</h3>
+<ul>
+<li>Changed <tt>GeometryFactory.createGeometry()</tt> to make a deep copy of the argument Geometry,
+using the CoordinateSequenceFactory of the factory
+<li>Added ability to specify a dimension in <tt>CoordinateArraySequence</tt>
+<li>Changed <tt>Geometry.getEnvelopeInternal()</tt> to return a copy of the cached envelope, to prevent modification
+<li>Added <tt>GeometryEditor.CoordinateSequenceOperation</tt> to allow easy editing of constituent CoordinateSequences
+<li>Added <tt>GeometryFactory.createPolygon</tt> convenience methods which do not require holes to be specified
+<li><tt>Geometry</tt> overlay methods now return empty results as atomic types of appropriate dimension
+<li>Added <tt>RectangleLineIntersector</tt> to provide efficient rectangle-line intersection testing
+<li>Added <tt>getOrdinate</tt> and <tt>setOrdinate</tt> to <tt>Coordinate</tt>
+<li><tt>Quadtree</tt> is <tt>Serializable</tt>
+<li><tt>STRtree</tt> is <tt>Serializable</tt>
+<li>Added <tt>max</tt>, <tt>average</tt> and <tt>wrap</tt> functions to </tt>MathUtil</tt>
+<li>Improved <tt>WKTReader</tt> parse error reporting to report input line of error
+<li>Improved <code>WKBReader</code> to repair structurally-invalid input
+<li>Made <tt>TopologyPreservingSimplifier</tt> thread-safe
+<li>Added <tt>AbstractSTRtree.isEmpty()</tt> method
+<li>Added <tt>QuadTree.isEmpty()</tt> method
+<li>Added <tt>KdTree.isEmpty()</tt> method
+<li>Added decimation and duplicate point removal to </tt>ShapeWriter<tt>.
+<li><tt>ScaledNoder</tt> now preserves Z values of input
+<li>Added instance methods for all <t>Triangle</tt> static methods
+<li>Added <tt>CGAlgorithmsDD</tt> containing high-precision versions of some basic CG algorithms
+<li>Added <tt>IntersectionMatrix.isTrue()</tt> method for testing IM pattern matches
+<li>Added <code>getRawCoordinates</code> methods to <code>PackedCoordinateSequence</code> concrete classes
+<li>Modified <code>Geometry.isSimple()</code> to explicity check for simplicity for all types,
+and support <code>GeometryCollections</code>
+<li>Improved <code>MCIndexSnapRounder</code> to add nodes only where they are necessary
+<li>Added <code>CoordinateArrays.removeNull()</code> method
+<li>Enhanced <code>GeometryEditor</code> to handle null geometries returned from operation
+<li>Added <code>WKBHExFileReader</code>
+<li>Added <code>Distance3D</code> operation
+</ul>
+
+<h3>Performance Improvements</h3>
+<ul>
+<li>Simplified & improved performance of <tt>RectangleIntersects</tt> by using new <tt>RectangleLineIntersector</tt>
+<li>In <tt>RandomPointsInGridBuilder</tt> eliminated redundant <tt>ArrayList</tt> usage
+<li>In <tt>PreparedPolygonIntersects</tt> and <tt>PreparedLineStringIntersects</tt> added check
+to avoid creating segment index if all test inputs are points
+<li>In <tt>AbstractSTRtree</tt> switched to using indexed list access for better performance than using iterators
+<li>In <tt>AbstractSTRtree</tt> freed inserted item array after index is built
+<li>Improved performance of <tt>Polygonizer</tt> for cases with many potential holes
+<li>Improved performance for some <tt>DD</tt> methods by making them <tt>final</tt>
+<li>Added fast filter for <tt>CGAlgorithmsDD.orientationIndex</tt>, and switched to self-operations for DD determinant
+<li>Changed <code>STRtree.createNode()</code> to use a static class for nodes
+<li>Changed <code>QuadTree Node</code> to use scalar x and y variables rather than a <code>Coordinate</code> to reduce memory allocation
+<li>Fixed <code>PreparedGeometry</code> concrete classes to be thread-safe.
+<li>Fixed <code>SortedPackedIntervalRTree</code> so that it is thread-safe.
+</ul>
+
+<h3>Robustness Improvements</h3>
+<ul>
+<li>Switched to using DD extended-precision arithmetic to compute orientation predicate
+<li><code>CGAlgorithms.distanceLineLine()</code> improved to be more robust and performant
+<li>Fixed robustness issue causing <tt>Empty Stack</tt> failure
+in <tt>ConvexHull</tt> for some nearly collinear inputs
+<li><tt>CGAlgorithms.signedArea()</tt> uses a more accurate algorithm
+</ul>
+
+<h3>Bug Fixes</h3>
+<ul>
+<li>Fixed <tt>Geometry.equalsExact()</tt> to avoid NPE when comparing empty and non-empty <tt>Point</tt>s
+<li>Fixed <tt>CascadedPolygonUnion</tt> to discard non-polygonal components created during unioning,
+to avoid failures and provide more desirable behaviour
+<li>Fixed <tt>CentralEndpointIntersector</tt> to initialize result correctly
+<li>Fixed <tt>DelaunayTriangulationBuilder.extractUniqueCoordinates(Geometry)</tt>
+to avoid mutating the vertex order of the input Geometry
+<li>Fixed <tt>ConformingDelaunayTriangulationBuilder</tt> to allow
+non-disjoint site and constraint vertex sets
+<li>Fixed <tt>RandomPointsInGridBuilder</tt> point generation to use circle constraint correctly
+<li>Fixed Linear Referencing API to handle MultiLineStrings consistently,
+by always using the lowest possible index value, and by trimming zero-length components from results
+<li>Fixed bug in <tt>LocationIndexedLine</tt> and <tt>LengthIndexLine</tt> which was
+causing an assertion failure when the indexOfAfter() method was called with a constraint location
+which is at the end of the line
+<li>Fixed bug in <tt>STRtree.query(Envelope, ItemVisitor)</tt> causing an NPE when tree is empty
+<li>Fixed issue with creating zero-length edges during buffer topology building under fixed precision, by:
+adding filter to remove zero-length edges;
+using a better estimate of scale factor for reducing to fixed precision after initial failure.
+<li>Fixed <tt>TopologyPreservingSimplifier</tt> to return a valid result
+for closed <tt>LineString</tt>s with large distance tolerances
+<li>Fixed <tt>TopologyPreservingSimplifier</tt> to return an empty result for an empty input
+<li>Fixed <tt>DouglasPeuckerSimplifier</tt> to return an empty result for an empty input
+<li>Fixed <tt>MinimumBoundingCircle</tt> to correctly compute circle for obtuse triangles.
+<li>Fixd <tt>GeometryPrecisionReducer</tt> to use input GeometryFactory when polygon topology is fixed
+<li>Fixed <tt>GeometryNoder</tt> bug that was failing to snap to end vertices of lines
+<li>Fixed <tt>Geometry.getCentroid()</tt> and <tt>Geometry.getInteriorPoint()</tt> to return <tt>POINT EMPTY</tt> for empty inputs
+<li>Fixed <tt>DelaunayTriangulationBuilder</tt> to correctly extract unique points
+<li>Fixed <tt>KdTree</tt> to correctly handle inserting duplicate points into an empty tree
+<li>Fixed <tt>LineSegment.projectionFactor()</tt> to handle zero-length lines (by returning Double.POSITIVE_INFINITY)
+<li>Fixed <tt>LocationIndexedLine</tt> to handle locations on zero-length lines
+<li>Fixed <code>LengthIndexedLine</code> and <code>LocationIndexedLine</code> to handle <code>indexOfAfter()</code> correctly
+<li>Fixed <code>WKBReader</code> to handle successive geometrys with different endianness
+<li>Fixed <code>GeometricShapeFactory</code> to correctly handle setting the centre point
+<li>Fixed <code>GeometryFactory.createMultiPoint(CoordinateSequence)</code> to handle sequences of dimension > 3
+</ul>
+
+<h3>API Changes</h3>
+<ul>
+<li>Changed visibility of <tt>TaggedLineStringSimplifier</tt> back to <tt>public</tt> due to user demand
+</ul>
+
+<h3>Testing</h3>
+<ul>
+<li>Added Performance Testing framework (<tt>PerformanceTestRunner</tt>
+and <tt>PerformanceTestCase</tt>)
+<li>Added named predicate tests to all Relate test cases
+</ul>
+
+<h3>Contributors</h3>
+<ul>
+<li>Peter Hopfgartner - improved area computation
+<li>Michael Michaud - snap-rounding improvements
+</ul>
+
+
+<!------- TestBuilder -------------------->
+<hr size='0' color='darkblue'>
+<h3 style='font-family:sans-serif; color:darkblue'>JTS TestBuilder</h3>
+
+<h3>Functionality Improvements</h3>
+<ul>
+<li>Added segment index visualization styling
+<li>Improved <b>Geometry Inspector</b>
+<li>Added stream digitizing for Polygon and LineString tools
+<li>Added output of Test Case XML with WKB
+<li>Added Extract Component tool
+<li>Added Delete Vertices Or Components tool
+<li>Added Geometry Edit Panel pop-up menu, with operations
+<li>Added Halton sequence functions
+<li>Added sorting functions
+<li>Added function for selection of first N components
+<li>Added CGAlgorithms functions
+<li>Added ability to paste and load multiple WKBHex geometries
+</ul>
+
+<h3>Performance Improvements</h3>
+<ul>
+<li>Using decimation substantially improves rendering time for large geometries.
+</ul>
+
+<h3>Bug Fixes</h3>
+<ul>
+<li>Fixed bug in saving XML test files
+</ul>
+
+<!-- ================================================================ -->
+<hr size='4' color='darkblue'>
 <h2>Version 1.12</h2>
 
 <i>Release Date:  June 30, 2011</i>
@@ -30,7 +184,6 @@ The current and archived JTS distributions can be obtained at the
 <h3>Functionality Improvements</h3>
 <ul>
 <li>Added new names for methods for computing <tt>Geometry</tt> equality:
-<ul>
 <li><tt>equals(Object)</tt> is a synonym for <tt>equalsExact(Geometry)</tt>
 <li><tt>equalsNorm(Geometry)</tt> automatically normalizes the operands
 <li><tt>equalsTopo(Geometry)</tt> computes topological equality,
@@ -71,7 +224,7 @@ and is a synonym for the original <tt>equals(Geometry)</tt>
 <ul>
 <li>Delaunay triangulation uses more robust formulation for the inCircle test
 <li>Voronoi computation now uses more robust formulation for the circumcentre computation
-<li>Force RectangleIntersects to always use segment-scanning to improve robustness
+<li>Force <code>RectangleIntersects</code> to always use segment-scanning to improve robustness
 </ul>
 
 <h3>API Changes</h3>
@@ -122,6 +275,7 @@ to correctly handle the case where a hole touches all the vertices of another ho
 <li>Better startup script, with auto-home directory detection
 and JTS_LIB_DIR environment variable (thanks to strk)
 <li>Added logging Info window behaviour
+<li>Improved saving PNG to allow specifying file name
 </ul>
 
 <h3>Bug Fixes</h3>
diff --git a/src/com/vividsolutions/jts/JTSVersion.java b/src/com/vividsolutions/jts/JTSVersion.java
index 7d5372d..fe752e5 100644
--- a/src/com/vividsolutions/jts/JTSVersion.java
+++ b/src/com/vividsolutions/jts/JTSVersion.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts;
 
 /**
@@ -24,7 +57,7 @@ public class JTSVersion {
   /**
    * The minor version number.
    */
-  public static final int MINOR = 12;
+  public static final int MINOR = 13;
 
   /**
    * The patch version number.
@@ -83,4 +116,4 @@ public class JTSVersion {
     return ver;
   }
 
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/algorithm/Angle.java b/src/com/vividsolutions/jts/algorithm/Angle.java
index fd4d9f8..6c56e21 100644
--- a/src/com/vividsolutions/jts/algorithm/Angle.java
+++ b/src/com/vividsolutions/jts/algorithm/Angle.java
@@ -161,9 +161,11 @@ public class Angle
   /**
    * Returns the oriented smallest angle between two vectors.
    * The computed angle will be in the range (-Pi, Pi].
-   * A positive result corresponds to a counterclockwise rotation
+   * A positive result corresponds to a counterclockwise
+   * (CCW) rotation
    * from v1 to v2;
-   * a negative result corresponds to a clockwise rotation.
+   * a negative result corresponds to a clockwise (CW) rotation;
+   * a zero result corresponds to no rotation.
    *
    * @param tip1 the tip of v1
    * @param tail the tail of each vector
diff --git a/src/com/vividsolutions/jts/algorithm/BoundaryNodeRule.java b/src/com/vividsolutions/jts/algorithm/BoundaryNodeRule.java
index 6c83ae9..631a73a 100644
--- a/src/com/vividsolutions/jts/algorithm/BoundaryNodeRule.java
+++ b/src/com/vividsolutions/jts/algorithm/BoundaryNodeRule.java
@@ -43,13 +43,30 @@ import com.vividsolutions.jts.geom.*;
  * However, other kinds of Boundary Node Rules are appropriate
  * in specific situations (for instance, linear network topology
  * usually follows the {@link EndPointBoundaryNodeRule}.)
- * Some JTS operations allow the BoundaryNodeRule to be specified,
- * and respect this rule when computing the results of the operation.
+ * Some JTS operations 
+ * (such as {@link RelateOp}, {@link BoundaryOp} and {@link IsSimpleOp})
+ * allow the BoundaryNodeRule to be specified,
+ * and respect the supplied rule when computing the results of the operation.
+ * <p>
+ * An example use case for a non-SFS-standard Boundary Node Rule is
+ * that of checking that a set of {@link LineString}s have 
+ * valid linear network topology, when turn-arounds are represented
+ * as closed rings.  In this situation, the entry road to the
+ * turn-around is only valid when it touches the turn-around ring
+ * at the single (common) endpoint.  This is equivalent 
+ * to requiring the set of <tt>LineString</tt>s to be 
+ * <b>simple</b> under the {@link EndPointBoundaryNodeRule}.
+ * The SFS-standard {@link Mod2BoundaryNodeRule} is not 
+ * sufficient to perform this test, since it
+ * states that closed rings have <b>no</b> boundary points.
+ * <p>
+ * This interface and its subclasses follow the <tt>Strategy</tt> design pattern.
  *
  * @author Martin Davis
  * @version 1.7
  *
  * @see RelateOp
+ * @see BoundaryOp
  * @see IsSimpleOp
  * @see PointLocator
  */
diff --git a/src/com/vividsolutions/jts/algorithm/CGAlgorithms.java b/src/com/vividsolutions/jts/algorithm/CGAlgorithms.java
index e891f1a..bf97351 100644
--- a/src/com/vividsolutions/jts/algorithm/CGAlgorithms.java
+++ b/src/com/vividsolutions/jts/algorithm/CGAlgorithms.java
@@ -34,12 +34,15 @@ package com.vividsolutions.jts.algorithm;
 
 import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.Envelope;
 import com.vividsolutions.jts.geom.Location;
+import com.vividsolutions.jts.math.MathUtil;
 
 /**
- * Specifies and implements various fundamental Computational Geometric algorithms.
- * The algorithms supplied in this class are robust for double-precision floating point.
- *
+ * Specifies and implements various fundamental Computational Geometric
+ * algorithms. The algorithms supplied in this class are robust for
+ * double-precision floating point.
+ * 
  * @version 1.7
  */
 public class CGAlgorithms
@@ -48,117 +51,131 @@ public class CGAlgorithms
   /**
    * A value that indicates an orientation of clockwise, or a right turn.
    */
-  public static final int CLOCKWISE     = -1;
-  public static final int RIGHT         = CLOCKWISE;
+  public static final int CLOCKWISE = -1;
+
+  /**
+   * A value that indicates an orientation of clockwise, or a right turn.
+   */
+  public static final int RIGHT = CLOCKWISE;
+
+  /**
+   * A value that indicates an orientation of counterclockwise, or a left turn.
+   */
+  public static final int COUNTERCLOCKWISE = 1;
+
   /**
    * A value that indicates an orientation of counterclockwise, or a left turn.
    */
-  public static final int COUNTERCLOCKWISE  = 1;
-  public static final int LEFT              = COUNTERCLOCKWISE;
+  public static final int LEFT = COUNTERCLOCKWISE;
+
+  /**
+   * A value that indicates an orientation of collinear, or no turn (straight).
+   */
+  public static final int COLLINEAR = 0;
+
   /**
    * A value that indicates an orientation of collinear, or no turn (straight).
    */
-  public static final int COLLINEAR         = 0;
-  public static final int STRAIGHT          = COLLINEAR;
+  public static final int STRAIGHT = COLLINEAR;
 
   /**
-   * Returns the index of the direction of the point <code>q</code>
-   * relative to a
-   * vector specified by <code>p1-p2</code>.
-   *
+   * Returns the index of the direction of the point <code>q</code> relative to
+   * a vector specified by <code>p1-p2</code>.
+   * 
    * @param p1 the origin point of the vector
    * @param p2 the final point of the vector
    * @param q the point to compute the direction to
-   *
+   * 
    * @return 1 if q is counter-clockwise (left) from p1-p2
    * @return -1 if q is clockwise (right) from p1-p2
    * @return 0 if q is collinear with p1-p2
    */
-  public static int orientationIndex(Coordinate p1, Coordinate p2, Coordinate q) 
+  public static int orientationIndex(Coordinate p1, Coordinate p2, Coordinate q)
   {
-  	/**
-  	 * MD - 9 Aug 2010
-  	 * It seems that the basic algorithm is slightly orientation dependent,
-  	 * when computing the orientation of a point very close to a line.
-  	 * This is possibly due to the arithmetic in the translation to the origin.
-  	 * 
-  	 * For instance, the following situation produces identical results 
-  	 * in spite of the inverse orientation of the line segment:
-  	 * 
-  	 * Coordinate p0 = new Coordinate(219.3649559090992, 140.84159161824724);
-  	 * Coordinate p1 = new Coordinate(168.9018919682399, -5.713787599646864);
-  	 * 
-  	 * Coordinate p = new Coordinate(186.80814046338352, 46.28973405831556);
-  	 * int orient = orientationIndex(p0, p1, p);
-  	 * int orientInv = orientationIndex(p1, p0, p);
-
-  	 * A way to force consistent results is to normalize the orientation of the vector
-  	 * using the following code.
-  	 * However, this may make the results of orientationIndex inconsistent
-  	 * through the triangle of points, so it's not clear this is 
-  	 * an appropriate patch.
-  	 * 
-  	 */
-  	/*
-  	 // Normalize orientation of vector to provide consistent results
-    // This produces repeatable results for single cases, but does not fully solve robustness issues
- 	   if (p2.x < p1.x || (p2.x == p1.x && p2.y < p1.y))
-			return -orientationIndex(p2, p1, q);
-	  //*/
-    double dx1 = p2.x - p1.x;
-    double dy1 = p2.y - p1.y;
-    double dx2 = q.x - p2.x;
-    double dy2 = q.y - p2.y;
-    return RobustDeterminant.signOfDet2x2(dx1, dy1, dx2, dy2);
+    /**
+     * MD - 9 Aug 2010 It seems that the basic algorithm is slightly orientation
+     * dependent, when computing the orientation of a point very close to a
+     * line. This is possibly due to the arithmetic in the translation to the
+     * origin.
+     * 
+     * For instance, the following situation produces identical results in spite
+     * of the inverse orientation of the line segment:
+     * 
+     * Coordinate p0 = new Coordinate(219.3649559090992, 140.84159161824724);
+     * Coordinate p1 = new Coordinate(168.9018919682399, -5.713787599646864);
+     * 
+     * Coordinate p = new Coordinate(186.80814046338352, 46.28973405831556); int
+     * orient = orientationIndex(p0, p1, p); int orientInv =
+     * orientationIndex(p1, p0, p);
+     * 
+     * A way to force consistent results is to normalize the orientation of the
+     * vector using the following code. However, this may make the results of
+     * orientationIndex inconsistent through the triangle of points, so it's not
+     * clear this is an appropriate patch.
+     * 
+     */
+    return CGAlgorithmsDD.orientationIndex(p1, p2, q);
+    // testing only
+    //return ShewchuksDeterminant.orientationIndex(p1, p2, q);
+    // previous implementation - not quite fully robust
+    //return RobustDeterminant.orientationIndex(p1, p2, q);
+    
   }
 
-  public CGAlgorithms() {
+  public CGAlgorithms()
+  {
   }
 
   /**
-   * Tests whether a point lies inside or on a ring.
-   * The ring may be oriented in either direction.
-   * A point lying exactly on the ring boundary is considered to be inside the ring.
+   * Tests whether a point lies inside or on a ring. The ring may be oriented in
+   * either direction. A point lying exactly on the ring boundary is considered
+   * to be inside the ring.
    * <p>
-   * This method does <i>not</i> first check the point against the envelope
-   * of the ring.
-   *
-   * @param p point to check for ring inclusion
-   * @param ring an array of coordinates representing the ring (which must have first point identical to last point)
+   * This method does <i>not</i> first check the point against the envelope of
+   * the ring.
+   * 
+   * @param p
+   *          point to check for ring inclusion
+   * @param ring
+   *          an array of coordinates representing the ring (which must have
+   *          first point identical to last point)
    * @return true if p is inside ring
    * 
    * @see locatePointInRing
    */
-  public static boolean isPointInRing(Coordinate p, Coordinate[] ring) {
-  	return locatePointInRing(p, ring) != Location.EXTERIOR;
+  public static boolean isPointInRing(Coordinate p, Coordinate[] ring)
+  {
+    return locatePointInRing(p, ring) != Location.EXTERIOR;
   }
-  
 
   /**
-   * Determines whether a point lies in the interior, on the boundary, or in the exterior
-   * of a ring.
-   * The ring may be oriented in either direction.
+   * Determines whether a point lies in the interior, on the boundary, or in the
+   * exterior of a ring. The ring may be oriented in either direction.
    * <p>
-   * This method does <i>not</i> first check the point against the envelope
-   * of the ring.
-   *
-   * @param p point to check for ring inclusion
-   * @param ring an array of coordinates representing the ring (which must have first point identical to last point)
+   * This method does <i>not</i> first check the point against the envelope of
+   * the ring.
+   * 
+   * @param p
+   *          point to check for ring inclusion
+   * @param ring
+   *          an array of coordinates representing the ring (which must have
+   *          first point identical to last point)
    * @return the {@link Location} of p relative to the ring
    */
-  public static int locatePointInRing(Coordinate p, Coordinate[] ring) 
+  public static int locatePointInRing(Coordinate p, Coordinate[] ring)
   {
     return RayCrossingCounter.locatePointInRing(p, ring);
   }
-  
+
   /**
-   * Tests whether a point lies on the line segments defined by a
-   * list of coordinates.
-   *
-   * @return true if the point is a vertex of the line 
-   * or lies in the interior of a line segment in the linestring
+   * Tests whether a point lies on the line segments defined by a list of
+   * coordinates.
+   * 
+   * @return true if the point is a vertex of the line or lies in the interior
+   *         of a line segment in the linestring
    */
-  public static boolean isOnLine(Coordinate p, Coordinate[] pt) {
+  public static boolean isOnLine(Coordinate p, Coordinate[] pt)
+  {
     LineIntersector lineIntersector = new RobustLineIntersector();
     for (int i = 1; i < pt.length; i++) {
       Coordinate p0 = pt[i - 1];
@@ -178,21 +195,25 @@ public class CGAlgorithms
    * <li>The list of points is assumed to have the first and last points equal.
    * <li>This will handle coordinate lists which contain repeated points.
    * </ul>
-   * This algorithm is <b>only</b> guaranteed to work with valid rings.
-   * If the ring is invalid (e.g. self-crosses or touches),
-   * the computed result may not be correct.
-   *
-   * @param ring an array of Coordinates forming a ring
+   * This algorithm is <b>only</b> guaranteed to work with valid rings. If the
+   * ring is invalid (e.g. self-crosses or touches), the computed result may not
+   * be correct.
+   * 
+   * @param ring
+   *          an array of Coordinates forming a ring
    * @return true if the ring is oriented counter-clockwise.
-   * @throws IllegalArgumentException if there are too few points to determine orientation (< 3)
+   * @throws IllegalArgumentException
+   *           if there are too few points to determine orientation (< 3)
    */
-  public static boolean isCCW(Coordinate[] ring) {
+  public static boolean isCCW(Coordinate[] ring)
+  {
     // # of points without closing endpoint
     int nPts = ring.length - 1;
     // sanity check
     if (nPts < 3)
-    	throw new IllegalArgumentException("Ring has fewer than 3 points, so orientation cannot be determined");
-    
+      throw new IllegalArgumentException(
+          "Ring has fewer than 3 points, so orientation cannot be determined");
+
     // find highest point
     Coordinate hiPt = ring[0];
     int hiIndex = 0;
@@ -208,7 +229,8 @@ public class CGAlgorithms
     int iPrev = hiIndex;
     do {
       iPrev = iPrev - 1;
-      if (iPrev < 0) iPrev = nPts;
+      if (iPrev < 0)
+        iPrev = nPts;
     } while (ring[iPrev].equals2D(hiPt) && iPrev != hiIndex);
 
     // find distinct point after highest point
@@ -221,10 +243,10 @@ public class CGAlgorithms
     Coordinate next = ring[iNext];
 
     /**
-     * This check catches cases where the ring contains an A-B-A configuration of points.
-     * This can happen if the ring does not contain 3 distinct points
-     * (including the case where the input array has fewer than 4 elements),
-     * or it contains coincident line segments.
+     * This check catches cases where the ring contains an A-B-A configuration
+     * of points. This can happen if the ring does not contain 3 distinct points
+     * (including the case where the input array has fewer than 4 elements), or
+     * it contains coincident line segments.
      */
     if (prev.equals2D(hiPt) || next.equals2D(hiPt) || prev.equals2D(next))
       return false;
@@ -232,13 +254,13 @@ public class CGAlgorithms
     int disc = computeOrientation(prev, hiPt, next);
 
     /**
-     *  If disc is exactly 0, lines are collinear.  There are two possible cases:
-     *  (1) the lines lie along the x axis in opposite directions
-     *  (2) the lines lie on top of one another
-     *
-     *  (1) is handled by checking if next is left of prev ==> CCW
-     *  (2) will never happen if the ring is valid, so don't check for it
-     *  (Might want to assert this)
+     * If disc is exactly 0, lines are collinear. There are two possible cases:
+     * (1) the lines lie along the x axis in opposite directions (2) the lines
+     * lie on top of one another
+     * 
+     * (1) is handled by checking if next is left of prev ==> CCW (2) will never
+     * happen if the ring is valid, so don't check for it (Might want to assert
+     * this)
      */
     boolean isCCW = false;
     if (disc == 0) {
@@ -256,261 +278,302 @@ public class CGAlgorithms
    * Computes the orientation of a point q to the directed line segment p1-p2.
    * The orientation of a point relative to a directed line segment indicates
    * which way you turn to get to q after travelling from p1 to p2.
-   *
+   * 
    * @return 1 if q is counter-clockwise from p1-p2
    * @return -1 if q is clockwise from p1-p2
    * @return 0 if q is collinear with p1-p2
    */
-  public static int computeOrientation(Coordinate p1, Coordinate p2, Coordinate q) {
+  public static int computeOrientation(Coordinate p1, Coordinate p2,
+      Coordinate q)
+  {
     return orientationIndex(p1, p2, q);
   }
 
-
   /**
    * Computes the distance from a point p to a line segment AB
-   *
+   * 
    * Note: NON-ROBUST!
-   *
-   * @param p the point to compute the distance for
-   * @param A one point of the line
-   * @param B another point of the line (must be different to A)
+   * 
+   * @param p
+   *          the point to compute the distance for
+   * @param A
+   *          one point of the line
+   * @param B
+   *          another point of the line (must be different to A)
    * @return the distance from p to line segment AB
    */
-  public static double distancePointLine(Coordinate p, Coordinate A, Coordinate B)
+  public static double distancePointLine(Coordinate p, Coordinate A,
+      Coordinate B)
   {
     // if start = end, then just compute distance to one of the endpoints
-    if (  A.x == B.x && A.y == B.y ) return p.distance(A);
+    if (A.x == B.x && A.y == B.y)
+      return p.distance(A);
 
     // otherwise use comp.graphics.algorithms Frequently Asked Questions method
-    /*(1)     	      AC dot AB
-                   r = ---------
-                         ||AB||^2
-		r has the following meaning:
-		r=0 P = A
-		r=1 P = B
-		r<0 P is on the backward extension of AB
-		r>1 P is on the forward extension of AB
-		0<r<1 P is interior to AB
-	*/
-
-    double r = ( (p.x - A.x) * (B.x - A.x) + (p.y - A.y) * (B.y - A.y) )
-              /
-            ( (B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y) );
-
-    if (r <= 0.0) return p.distance(A);
-    if (r >= 1.0) return p.distance(B);
-
-
-    /*(2)
-		     (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
-		s = -----------------------------
-		             	L^2
-
-		Then the distance from C to P = |s|*L.
-	*/
-
-    double s = ((A.y - p.y) *(B.x - A.x) - (A.x - p.x)*(B.y - A.y) )
-              /
-            ((B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y) );
-
-    return
-      Math.abs(s) *
-      Math.sqrt(((B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y)));
+    /*
+     * (1) r = AC dot AB 
+     *         --------- 
+     *         ||AB||^2 
+     *         
+     * r has the following meaning: 
+     *   r=0 P = A 
+     *   r=1 P = B 
+     *   r<0 P is on the backward extension of AB 
+     *   r>1 P is on the forward extension of AB 
+     *   0<r<1 P is interior to AB
+     */
+
+    double len2 = (B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y);
+    double r = ((p.x - A.x) * (B.x - A.x) + (p.y - A.y) * (B.y - A.y))
+        / len2;
+
+    if (r <= 0.0)
+      return p.distance(A);
+    if (r >= 1.0)
+      return p.distance(B);
+
+    /*
+     * (2) s = (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay) 
+     *         ----------------------------- 
+     *                    L^2
+     * 
+     * Then the distance from C to P = |s|*L.
+     * 
+     * This is the same calculation as {@link #distancePointLinePerpendicular}.
+     * Unrolled here for performance.
+     */
+    double s = ((A.y - p.y) * (B.x - A.x) - (A.x - p.x) * (B.y - A.y))
+        / len2;
+    return Math.abs(s) * Math.sqrt(len2);
   }
-  
+
   /**
-   * Computes the perpendicular distance from a point p
-   * to the (infinite) line containing the points AB
-   *
-   * @param p the point to compute the distance for
-   * @param A one point of the line
-   * @param B another point of the line (must be different to A)
+   * Computes the perpendicular distance from a point p to the (infinite) line
+   * containing the points AB
+   * 
+   * @param p
+   *          the point to compute the distance for
+   * @param A
+   *          one point of the line
+   * @param B
+   *          another point of the line (must be different to A)
    * @return the distance from p to line AB
    */
-  public static double distancePointLinePerpendicular(Coordinate p, Coordinate A, Coordinate B)
+  public static double distancePointLinePerpendicular(Coordinate p,
+      Coordinate A, Coordinate B)
   {
     // use comp.graphics.algorithms Frequently Asked Questions method
-    /*(2)
-                     (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
-                s = -----------------------------
-                                     L^2
-
-                Then the distance from C to P = |s|*L.
-        */
-
-    double s = ((A.y - p.y) *(B.x - A.x) - (A.x - p.x)*(B.y - A.y) )
-              /
-            ((B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y) );
+    /*
+     * (2) s = (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay) 
+     *         ----------------------------- 
+     *                    L^2
+     * 
+     * Then the distance from C to P = |s|*L.
+     */
+    double len2 = (B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y);
+    double s = ((A.y - p.y) * (B.x - A.x) - (A.x - p.x) * (B.y - A.y))
+        / len2;
 
-    return
-      Math.abs(s) *
-      Math.sqrt(((B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y)));
+    return Math.abs(s) * Math.sqrt(len2);
   }
 
   /**
-   * Computes the distance from a point to a sequence
-   * of line segments.
+   * Computes the distance from a point to a sequence of line segments.
    * 
-   * @param p a point
-   * @param line a sequence of contiguous line segments defined by their vertices
+   * @param p
+   *          a point
+   * @param line
+   *          a sequence of contiguous line segments defined by their vertices
    * @return the minimum distance between the point and the line segments
    */
-	public static double distancePointLine(Coordinate p, Coordinate[] line)
-	{
-		if (line.length == 0) 
-			throw new IllegalArgumentException("Line array must contain at least one vertex");
-		// this handles the case of length = 1
-		double minDistance = p.distance(line[0]);
-		for (int i = 0; i < line.length - 1; i++) {
-			double dist = CGAlgorithms.distancePointLine(p, line[i], line[i+1]);
-			if (dist < minDistance) {
-				minDistance = dist;
-			}
-		}
-		return minDistance;
-	}
-	
+  public static double distancePointLine(Coordinate p, Coordinate[] line)
+  {
+    if (line.length == 0)
+      throw new IllegalArgumentException(
+          "Line array must contain at least one vertex");
+    // this handles the case of length = 1
+    double minDistance = p.distance(line[0]);
+    for (int i = 0; i < line.length - 1; i++) {
+      double dist = CGAlgorithms.distancePointLine(p, line[i], line[i + 1]);
+      if (dist < minDistance) {
+        minDistance = dist;
+      }
+    }
+    return minDistance;
+  }
+
   /**
    * Computes the distance from a line segment AB to a line segment CD
-   *
+   * 
    * Note: NON-ROBUST!
-   *
-   * @param A a point of one line
-   * @param B the second point of  (must be different to A)
-   * @param C one point of the line
-   * @param D another point of the line (must be different to A)
+   * 
+   * @param A
+   *          a point of one line
+   * @param B
+   *          the second point of (must be different to A)
+   * @param C
+   *          one point of the line
+   * @param D
+   *          another point of the line (must be different to A)
    */
-  public static double distanceLineLine(Coordinate A, Coordinate B, Coordinate C, Coordinate D)
+  public static double distanceLineLine(Coordinate A, Coordinate B,
+      Coordinate C, Coordinate D)
   {
     // check for zero-length segments
-    if (  A.equals(B) )	return distancePointLine(A,C,D);
-    if (  C.equals(D) )	return distancePointLine(D,A,B);
+    if (A.equals(B))
+      return distancePointLine(A, C, D);
+    if (C.equals(D))
+      return distancePointLine(D, A, B);
 
     // AB and CD are line segments
-    /* from comp.graphics.algo
-
-	Solving the above for r and s yields
-				(Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy)
-	           r = ----------------------------- (eqn 1)
-				(Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
-
-		 	(Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
-		s = ----------------------------- (eqn 2)
-			(Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
-	Let P be the position vector of the intersection point, then
-		P=A+r(B-A) or
-		Px=Ax+r(Bx-Ax)
-		Py=Ay+r(By-Ay)
-	By examining the values of r & s, you can also determine some other
-limiting conditions:
-		If 0<=r<=1 & 0<=s<=1, intersection exists
-		r<0 or r>1 or s<0 or s>1 line segments do not intersect
-		If the denominator in eqn 1 is zero, AB & CD are parallel
-		If the numerator in eqn 1 is also zero, AB & CD are collinear.
-
-	*/
-    double r_top = (A.y-C.y)*(D.x-C.x) - (A.x-C.x)*(D.y-C.y) ;
-    double r_bot = (B.x-A.x)*(D.y-C.y) - (B.y-A.y)*(D.x-C.x) ;
-
-    double s_top = (A.y-C.y)*(B.x-A.x) - (A.x-C.x)*(B.y-A.y);
-    double s_bot = (B.x-A.x)*(D.y-C.y) - (B.y-A.y)*(D.x-C.x);
-
-    if  ( (r_bot==0) || (s_bot == 0) ) {
-      return
-        Math.min(distancePointLine(A,C,D),
-	  Math.min(distancePointLine(B,C,D),
-	    Math.min(distancePointLine(C,A,B),
-	      distancePointLine(D,A,B)    ) ) );
+    /*
+     * from comp.graphics.algo
+     * 
+     * Solving the above for r and s yields 
+     * 
+     *     (Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy) 
+     * r = ----------------------------- (eqn 1) 
+     *     (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
+     * 
+     *     (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)  
+     * s = ----------------------------- (eqn 2)
+     *     (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx) 
+     *     
+     * Let P be the position vector of the
+     * intersection point, then 
+     *   P=A+r(B-A) or 
+     *   Px=Ax+r(Bx-Ax) 
+     *   Py=Ay+r(By-Ay) 
+     * By examining the values of r & s, you can also determine some other limiting
+     * conditions: 
+     *   If 0<=r<=1 & 0<=s<=1, intersection exists 
+     *      r<0 or r>1 or s<0 or s>1 line segments do not intersect 
+     *   If the denominator in eqn 1 is zero, AB & CD are parallel 
+     *   If the numerator in eqn 1 is also zero, AB & CD are collinear.
+     */
 
+    boolean noIntersection = false;
+    if (! Envelope.intersects(A, B, C, D)) {
+      noIntersection = true;
+    }
+    else {
+      double denom = (B.x - A.x) * (D.y - C.y) - (B.y - A.y) * (D.x - C.x);
+      
+      if (denom == 0) {
+        noIntersection = true;
+      }
+      else {
+        double r_num = (A.y - C.y) * (D.x - C.x) - (A.x - C.x) * (D.y - C.y);
+        double s_num = (A.y - C.y) * (B.x - A.x) - (A.x - C.x) * (B.y - A.y);
+        
+        double s = s_num / denom;
+        double r = r_num / denom;
+  
+        if ((r < 0) || (r > 1) || (s < 0) || (s > 1)) {
+          noIntersection = true;
+        }
+      }
     }
-    double s = s_top/s_bot;
-    double r=  r_top/r_bot;
-
-    if ((r < 0) || ( r > 1) || (s < 0) || (s > 1) )	{
-      //no intersection
-      return
-        Math.min(distancePointLine(A,C,D),
-	  Math.min(distancePointLine(B,C,D),
-	    Math.min(distancePointLine(C,A,B),
-	      distancePointLine(D,A,B)    ) ) );
+    if (noIntersection) {
+      return MathUtil.min(
+            distancePointLine(A, C, D),
+            distancePointLine(B, C, D),
+            distancePointLine(C, A, B),
+            distancePointLine(D, A, B));
     }
-    return 0.0; //intersection exists
+    // segments intersect
+    return 0.0; 
   }
 
   /**
-   * Computes the signed area for a ring.      
-   * The signed area is positive if
-   * the ring is oriented CW, negative if the ring is oriented CCW,
-   * and zero if the ring is degenerate or flat. 
+   * Computes the signed area for a ring. The signed area is positive if the
+   * ring is oriented CW, negative if the ring is oriented CCW, and zero if the
+   * ring is degenerate or flat.
    * 
-   * @param ring the coordinates forming the ring
+   * @param ring
+   *          the coordinates forming the ring
    * @return the signed area of the ring
    */
   public static double signedArea(Coordinate[] ring)
   {
-    if (ring.length < 3) return 0.0;
+    if (ring.length < 3)
+      return 0.0;
     double sum = 0.0;
-    for (int i = 0; i < ring.length - 1; i++) {
-      double bx = ring[i].x;
-      double by = ring[i].y;
-      double cx = ring[i + 1].x;
-      double cy = ring[i + 1].y;
-      sum += (bx + cx) * (cy - by);
+    /**
+     * Based on the Shoelace formula.
+     * http://en.wikipedia.org/wiki/Shoelace_formula
+     */
+    double x0 = ring[0].x;
+    for (int i = 1; i < ring.length - 1; i++) {
+      double x = ring[i].x - x0;
+      double y1 = ring[i + 1].y;
+      double y2 = ring[i - 1].y;
+      sum += x * (y2 - y1);
     }
-    return -sum  / 2.0;
+    return sum / 2.0;
   }
 
   /**
-   * Computes the signed area for a ring.      
-   * The signed area is:
+   * Computes the signed area for a ring. The signed area is:
    * <ul>
    * <li>positive if the ring is oriented CW
    * <li>negative if the ring is oriented CCW
    * <li>zero if the ring is degenerate or flat
-   * </ul> 
+   * </ul>
    * 
-   * @param ring the coordinates forming the ring
+   * @param ring
+   *          the coordinates forming the ring
    * @return the signed area of the ring
    */
   public static double signedArea(CoordinateSequence ring)
   {
     int n = ring.size();
-    if (n < 3) return 0.0;
+    if (n < 3)
+      return 0.0;
+    /**
+     * Based on the Shoelace formula.
+     * http://en.wikipedia.org/wiki/Shoelace_formula
+     */
+    Coordinate p0 = new Coordinate();
+    Coordinate p1 = new Coordinate();
+    Coordinate p2 = new Coordinate();
+    ring.getCoordinate(0, p1);
+    ring.getCoordinate(1, p2);
+    double x0 = p1.x;
+    p2.x -= x0;
     double sum = 0.0;
-    Coordinate p = new Coordinate();
-    ring.getCoordinate(0, p);
-    double bx = p.x;
-    double by = p.y;
-    for (int i = 1; i < n; i++) {
-      ring.getCoordinate(i, p);
-      double cx = p.x;
-      double cy = p.y;
-      sum += (bx + cx) * (cy - by);
-      bx = cx;
-      by = cy;
+    for (int i = 1; i < n - 1; i++) {
+      p0.y = p1.y;
+      p1.x = p2.x;
+      p1.y = p2.y;
+      ring.getCoordinate(i + 1, p2);
+      p2.x -= x0;
+      sum += p1.x * (p0.y - p2.y);
     }
-    return -sum  / 2.0;
-  } 
-  
+    return sum / 2.0;
+  }
+
   /**
    * Computes the length of a linestring specified by a sequence of points.
-   *
-   * @param pts the points specifying the linestring
+   * 
+   * @param pts
+   *          the points specifying the linestring
    * @return the length of the linestring
    */
-  public static double length(CoordinateSequence pts) 
+  public static double length(CoordinateSequence pts)
   {
     // optimized for processing CoordinateSequences
     int n = pts.size();
-    if (n <= 1) return 0.0;
-    
+    if (n <= 1)
+      return 0.0;
+
     double len = 0.0;
-    
+
     Coordinate p = new Coordinate();
     pts.getCoordinate(0, p);
     double x0 = p.x;
     double y0 = p.y;
-    
+
     for (int i = 1; i < n; i++) {
       pts.getCoordinate(i, p);
       double x1 = p.x;
@@ -519,7 +582,7 @@ limiting conditions:
       double dy = y1 - y0;
 
       len += Math.sqrt(dx * dx + dy * dy);
-      
+
       x0 = x1;
       y0 = y1;
     }
diff --git a/src/com/vividsolutions/jts/algorithm/CGAlgorithms3D.java b/src/com/vividsolutions/jts/algorithm/CGAlgorithms3D.java
new file mode 100644
index 0000000..33cb223
--- /dev/null
+++ b/src/com/vividsolutions/jts/algorithm/CGAlgorithms3D.java
@@ -0,0 +1,182 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
+package com.vividsolutions.jts.algorithm;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.math.Vector3D;
+
+/**
+ * Basic computational geometry algorithms 
+ * for geometry and coordinates defined in 3-dimensional Cartesian space.
+ * 
+ * @author mdavis
+ *
+ */
+public class CGAlgorithms3D 
+{
+	public static double distance(Coordinate p0, Coordinate p1)
+	{
+		// default to 2D distance if either Z is not set
+		if (Double.isNaN(p0.z) || Double.isNaN(p1.z))
+			return p0.distance(p1);
+		
+	    double dx = p0.x - p1.x;
+	    double dy = p0.y - p1.y;
+	    double dz = p0.z - p1.z;
+	    return Math.sqrt(dx * dx + dy * dy + dz * dz);
+	}
+
+	public static double distancePointSegment(Coordinate p,
+			Coordinate A, Coordinate B) {
+	    // if start = end, then just compute distance to one of the endpoints
+	    if (A.equals3D(B))
+	      return distance(p, A);
+
+	    // otherwise use comp.graphics.algorithms Frequently Asked Questions method
+	    /*
+	     * (1) r = AC dot AB 
+	     *         --------- 
+	     *         ||AB||^2 
+	     *         
+	     * r has the following meaning: 
+	     *   r=0 P = A 
+	     *   r=1 P = B 
+	     *   r<0 P is on the backward extension of AB 
+	     *   r>1 P is on the forward extension of AB 
+	     *   0<r<1 P is interior to AB
+	     */
+
+	    double len2 = (B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y) + (B.z - A.z) * (B.z - A.z);
+	    if (Double.isNaN(len2))
+	    	throw new IllegalArgumentException("Ordinates must not be NaN");
+	    double r = ((p.x - A.x) * (B.x - A.x) + (p.y - A.y) * (B.y - A.y) + (p.z - A.z) * (B.z - A.z))
+	        / len2;
+
+	    if (r <= 0.0)
+	      return distance(p, A);
+	    if (r >= 1.0)
+	      return distance(p, B);
+
+	    // compute closest point q on line segment
+	    double qx = A.x + r * (B.x - A.x);
+	    double qy = A.y + r * (B.y - A.y);
+	    double qz = A.z + r * (B.z - A.z);
+	    // result is distance from p to q
+	    double dx = p.x - qx;
+	    double dy = p.y - qy;
+	    double dz = p.z - qz;
+	    return Math.sqrt(dx*dx + dy*dy + dz*dz);
+	}
+	
+
+	/**
+	 * Computes the distance between two 3D segments.
+	 * 
+	 * @param A the start point of the first segment
+	 * @param B the end point of the first segment
+	 * @param C the start point of the second segment
+	 * @param D the end point of the second segment
+	 * @return the distance between the segments
+	 */
+	public static double distanceSegmentSegment(
+			Coordinate A, Coordinate B, Coordinate C, Coordinate D) 
+	{
+		/**
+		 * This calculation is susceptible to roundoff errors when 
+		 * passed large ordinate values.
+		 * It may be possible to improve this by using {@link DD} arithmetic.
+		 */
+	    if (A.equals3D(B))
+		      return distancePointSegment(A, C, D);
+	    if (C.equals3D(B))
+		      return distancePointSegment(C, A, B);
+	    
+	    /**
+	     * Algorithm derived from http://softsurfer.com/Archive/algorithm_0106/algorithm_0106.htm
+	     */
+		double a = Vector3D.dot(A, B, A, B);
+		double b = Vector3D.dot(A, B, C, D);
+		double c = Vector3D.dot(C, D, C, D);
+		double d = Vector3D.dot(A, B, C, A);
+		double e = Vector3D.dot(C, D, C, A);
+		
+		double denom = a*c - b*b;
+	    if (Double.isNaN(denom))
+	    	throw new IllegalArgumentException("Ordinates must not be NaN");
+		
+		double s;
+		double t;
+		if (denom <= 0.0) {
+			/**
+			 * The lines are parallel. 
+			 * In this case solve for the parameters s and t by assuming s is 0.
+			 */
+			s = 0;
+			// choose largest denominator for optimal numeric conditioning
+			if (b > c)
+				t = d/b;
+			else 
+				t = e/c;
+		}
+		else {
+			s = (b*e - c*d) / denom;
+			t = (a*e - b*d) / denom;
+		}
+		if (s < 0) 
+			return distancePointSegment(A, C, D);
+		else if (s > 1)
+			return distancePointSegment(B, C, D);
+		else if (t < 0)	
+			return distancePointSegment(C, A, B);
+		else if(t > 1) {
+			return distancePointSegment(D, A, B);
+		}
+		/**
+		 * The closest points are in interiors of segments,
+		 * so compute them directly
+		 */
+		double x1 = A.x + s * (B.x - A.x);
+		double y1 = A.y + s * (B.y - A.y);
+		double z1 = A.z + s * (B.z - A.z);
+
+		double x2 = C.x + t * (D.x - C.x);
+		double y2 = C.y + t * (D.y - C.y);
+		double z2 = C.z + t * (D.z - C.z);
+		
+		// length (p1-p2)
+		return distance(new Coordinate(x1, y1, z1), new Coordinate(x2, y2, z2));
+	}
+
+	
+}
diff --git a/src/com/vividsolutions/jts/algorithm/CGAlgorithmsDD.java b/src/com/vividsolutions/jts/algorithm/CGAlgorithmsDD.java
new file mode 100644
index 0000000..f27f2ef
--- /dev/null
+++ b/src/com/vividsolutions/jts/algorithm/CGAlgorithmsDD.java
@@ -0,0 +1,206 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.math.DD;
+
+/**
+ * Implements basic computational geometry algorithms using {@link DD} arithmetic.
+ * 
+ * @author Martin Davis
+ *
+ */
+public class CGAlgorithmsDD
+{
+  /**
+   * Returns the index of the direction of the point <code>q</code> relative to
+   * a vector specified by <code>p1-p2</code>.
+   * 
+   * @param p1 the origin point of the vector
+   * @param p2 the final point of the vector
+   * @param q the point to compute the direction to
+   * 
+   * @return 1 if q is counter-clockwise (left) from p1-p2
+   * @return -1 if q is clockwise (right) from p1-p2
+   * @return 0 if q is collinear with p1-p2
+   */
+  public static int orientationIndex(Coordinate p1, Coordinate p2, Coordinate q)
+  {
+    // fast filter for orientation index
+    // avoids use of slow extended-precision arithmetic in many cases
+    int index = orientationIndexFilter(p1, p2, q);
+    if (index <= 1) return index;
+    
+    // normalize coordinates
+    DD dx1 = DD.valueOf(p2.x).selfAdd(-p1.x);
+    DD dy1 = DD.valueOf(p2.y).selfAdd(-p1.y);
+    DD dx2 = DD.valueOf(q.x).selfAdd(-p2.x);
+    DD dy2 = DD.valueOf(q.y).selfAdd(-p2.y);
+
+    // sign of determinant - unrolled for performance
+    return dx1.selfMultiply(dy2).selfSubtract(dy1.selfMultiply(dx2)).signum();
+  }
+  
+  /**
+   * Computes the sign of the determinant of the 2x2 matrix
+   * with the given entries.
+   * 
+   * @return -1 if the determinant is negative,
+   * @return  1 if the determinant is positive,
+   * @return  0 if the determinant is 0.
+   */
+  public static int signOfDet2x2(DD x1, DD y1, DD x2, DD y2)
+  {
+    DD det = x1.multiply(y2).selfSubtract(y1.multiply(x2));
+    return det.signum();
+  }
+
+  /**
+   * A value which is safely greater than the
+   * relative round-off error in double-precision numbers
+   */
+  private static final double DP_SAFE_EPSILON = 1e-15;
+
+  /**
+   * A filter for computing the orientation index of three coordinates.
+   * <p>
+   * If the orientation can be computed safely using standard DP
+   * arithmetic, this routine returns the orientation index.
+   * Otherwise, a value i > 1 is returned.
+   * In this case the orientation index must 
+   * be computed using some other more robust method.
+   * The filter is fast to compute, so can be used to 
+   * avoid the use of slower robust methods except when they are really needed,
+   * thus providing better average performance.
+   * <p>
+   * Uses an approach due to Jonathan Shewchuk, which is in the public domain.
+   * 
+   * @param pa a coordinate
+   * @param pb a coordinate
+   * @param pc a coordinate
+   * @return the orientation index if it can be computed safely
+   * @return i > 1 if the orientation index cannot be computed safely
+   */
+  private static int orientationIndexFilter(Coordinate pa, Coordinate pb, Coordinate pc)
+  {
+    double detsum;
+
+    double detleft = (pa.x - pc.x) * (pb.y - pc.y);
+    double detright = (pa.y - pc.y) * (pb.x - pc.x);
+    double det = detleft - detright;
+
+    if (detleft > 0.0) {
+      if (detright <= 0.0) {
+        return signum(det);
+      }
+      else {
+        detsum = detleft + detright;
+      }
+    }
+    else if (detleft < 0.0) {
+      if (detright >= 0.0) {
+        return signum(det);
+      }
+      else {
+        detsum = -detleft - detright;
+      }
+    }
+    else {
+      return signum(det);
+    }
+
+    double errbound = DP_SAFE_EPSILON * detsum;
+    if ((det >= errbound) || (-det >= errbound)) {
+      return signum(det);
+    }
+
+    return 2;
+  }
+
+  private static int signum(double x)
+  {
+    if (x > 0) return 1;
+    if (x < 0) return -1;
+    return 0;
+  }
+
+  /**
+   * Computes an intersection point between two lines
+   * using DD arithmetic.
+   * Currently does not handle case of parallel lines.
+   * 
+   * @param p1
+   * @param p2
+   * @param q1
+   * @param q2
+   * @return
+   */
+  public static Coordinate intersection(
+      Coordinate p1, Coordinate p2,
+      Coordinate q1, Coordinate q2)
+  {
+    DD denom1 = DD.valueOf(q2.y).selfSubtract(q1.y)
+    .selfMultiply(DD.valueOf(p2.x).selfSubtract(p1.x));
+    DD denom2 = DD.valueOf(q2.x).selfSubtract(q1.x)
+    .selfMultiply(DD.valueOf(p2.y).selfSubtract(p1.y));
+    DD denom = denom1.subtract(denom2);
+    
+    /**
+     * Cases:
+     * - denom is 0 if lines are parallel
+     * - intersection point lies within line segment p if fracP is between 0 and 1
+     * - intersection point lies within line segment q if fracQ is between 0 and 1
+     */
+    
+    DD numx1 = DD.valueOf(q2.x).selfSubtract(q1.x)
+    .selfMultiply(DD.valueOf(p1.y).selfSubtract(q1.y));
+    DD numx2 = DD.valueOf(q2.y).selfSubtract(q1.y)
+    .selfMultiply(DD.valueOf(p1.x).selfSubtract(q1.x));
+    DD numx = numx1.subtract(numx2);
+    double fracP = numx.selfDivide(denom).doubleValue();
+    
+    double x = DD.valueOf(p1.x).selfAdd(DD.valueOf(p2.x).selfSubtract(p1.x).selfMultiply(fracP)).doubleValue();
+    
+    DD numy1 = DD.valueOf(p2.x).selfSubtract(p1.x)
+    .selfMultiply(DD.valueOf(p1.y).selfSubtract(q1.y));
+    DD numy2 = DD.valueOf(p2.y).selfSubtract(p1.y)
+    .selfMultiply(DD.valueOf(p1.x).selfSubtract(q1.x));
+    DD numy = numy1.subtract(numy2);
+    double fracQ = numy.selfDivide(denom).doubleValue();
+    
+    double y = DD.valueOf(p1.y).selfAdd(DD.valueOf(p2.y).selfSubtract(p1.y).selfMultiply(fracQ)).doubleValue();
+
+    return new Coordinate(x,y);
+  }
+}
diff --git a/src/com/vividsolutions/jts/algorithm/CentralEndpointIntersector.java b/src/com/vividsolutions/jts/algorithm/CentralEndpointIntersector.java
index 0f94363..56c29ce 100644
--- a/src/com/vividsolutions/jts/algorithm/CentralEndpointIntersector.java
+++ b/src/com/vividsolutions/jts/algorithm/CentralEndpointIntersector.java
@@ -75,7 +75,7 @@ public class CentralEndpointIntersector
 	private void compute() 
 	{
 		Coordinate centroid = average(pts);
-		intPt = findNearestPoint(centroid, pts);
+		intPt = new Coordinate(findNearestPoint(centroid, pts));
 	}
 
 	public Coordinate getIntersection() {
@@ -113,7 +113,8 @@ public class CentralEndpointIntersector
   	Coordinate result = null;
   	for (int i = 0; i < pts.length; i++) {
   		double dist = p.distance(pts[i]);
-  		if (dist < minDist) {
+  		// always initialize the result
+  		if (i == 0 || dist < minDist) {
   			minDist = dist;
   			result = pts[i];
   		}
diff --git a/src/com/vividsolutions/jts/algorithm/ConvexHull.java b/src/com/vividsolutions/jts/algorithm/ConvexHull.java
index 7ddc3c8..5c63ee0 100644
--- a/src/com/vividsolutions/jts/algorithm/ConvexHull.java
+++ b/src/com/vividsolutions/jts/algorithm/ConvexHull.java
@@ -235,7 +235,10 @@ public class ConvexHull
     p = (Coordinate) ps.push(c[2]);
     for (int i = 3; i < c.length; i++) {
       p = (Coordinate) ps.pop();
-      while (CGAlgorithms.computeOrientation((Coordinate) ps.peek(), p, c[i]) > 0) {
+      // check for empty stack to guard against robustness problems
+      while (
+          ! ps.empty() && 
+          CGAlgorithms.computeOrientation((Coordinate) ps.peek(), p, c[i]) > 0) {
         p = (Coordinate) ps.pop();
       }
       p = (Coordinate) ps.push(p);
diff --git a/src/com/vividsolutions/jts/algorithm/InteriorPointArea.java b/src/com/vividsolutions/jts/algorithm/InteriorPointArea.java
index 531c028..cc94adb 100644
--- a/src/com/vividsolutions/jts/algorithm/InteriorPointArea.java
+++ b/src/com/vividsolutions/jts/algorithm/InteriorPointArea.java
@@ -46,11 +46,12 @@ import com.vividsolutions.jts.geom.*;
  *       will be lines and points)
  * </ul>
  *
- * <b>
- * Note: If a fixed precision model is used,
+ * <h3>KNOWN BUGS</h3>
+ * <ul>
+ * <li>If a fixed precision model is used,
  * in some cases this method may return a point
  * which does not lie in the interior.
- * </b>
+ * </ul>
  *
  * @version 1.7
  */
@@ -98,8 +99,6 @@ public class InteriorPointArea {
   /**
    * Finds a reasonable point at which to label a Geometry.
    * @param geometry the geometry to analyze
-   * @return the midpoint of the largest intersection between the geometry and
-   * a line halfway down its envelope
    */
   public void addPolygon(Geometry geometry) {
       LineString bisector = horizontalBisector(geometry);
diff --git a/src/com/vividsolutions/jts/algorithm/LineIntersector.java b/src/com/vividsolutions/jts/algorithm/LineIntersector.java
index 1b8a52e..0b6c1eb 100644
--- a/src/com/vividsolutions/jts/algorithm/LineIntersector.java
+++ b/src/com/vividsolutions/jts/algorithm/LineIntersector.java
@@ -1,6 +1,3 @@
-
-
-
 /*
  * The JTS Topology Suite is a collection of Java classes that
  * implement the fundamental operations required to validate a given
@@ -43,13 +40,30 @@ import com.vividsolutions.jts.util.*;
 import com.vividsolutions.jts.io.WKTWriter;
 
 /**
- * A LineIntersector is an algorithm that can both test whether
- * two line segments intersect and compute the intersection point
+ * A <code>LineIntersector</code> is an algorithm that can both test whether
+ * two line segments intersect and compute the intersection point(s)
  * if they do.
- * The intersection point may be computed in a precise or non-precise manner.
- * Computing it precisely involves rounding it to an integer.  (This assumes
- * that the input coordinates have been made precise by scaling them to
- * an integer grid.)
+ * <p>
+ * There are three possible outcomes when determining whether two line segments intersect:
+ * <ul>
+ * <li>{@link #NO_INTERSECTION} - the segments do not intersect
+ * <li>{@link #POINT_INTERSECTION - the segments intersect in a single point
+ * <li>{@link #COLLINEAR_INTERSECTION - the segments are collinear and they intersect in a line segment
+ * </ul>
+ * For segments which intersect in a single point, the point may be either an endpoint
+ * or in the interior of each segment.  
+ * If the point lies in the interior of both segments, 
+ * this is termed a <i>proper intersection</i>.
+ * The method {@link #isProper()} test for this situation.
+ * <p>
+ * The intersection point(s) may be computed in a precise or non-precise manner.
+ * Computing an intersection point precisely involves rounding it 
+ * via a supplied {@link PrecisionModel}.  
+ * <p>
+ * LineIntersectors do not perform an initial envelope intersection test 
+ * to determine if the segments are disjoint.
+ * This is because this class is likely to be used in a context where 
+ * envelope overlap is already known to occur (or be likely).
  *
  * @version 1.7
  */
@@ -280,6 +294,8 @@ public abstract class LineIntersector
 
   /**
    * Returns the number of intersection points found.  This will be either 0, 1 or 2.
+   * 
+   * @return the number of intersection points found (0, 1, or 2)
    */
   public int getIntersectionNum() { return result; }
 
diff --git a/src/com/vividsolutions/jts/algorithm/MinimumBoundingCircle.java b/src/com/vividsolutions/jts/algorithm/MinimumBoundingCircle.java
index 24eed22..462b1dc 100644
--- a/src/com/vividsolutions/jts/algorithm/MinimumBoundingCircle.java
+++ b/src/com/vividsolutions/jts/algorithm/MinimumBoundingCircle.java
@@ -1,18 +1,51 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.algorithm;
 
 import com.vividsolutions.jts.geom.*;
 import com.vividsolutions.jts.util.*;
 
 /**
- * Computes the Minimum Bounding Circle (MBC)
+ * Computes the <b>Minimum Bounding Circle</b> (MBC)
  * for the points in a {@link Geometry}.
- * The MBC is the smallest circle which contains
+ * The MBC is the smallest circle which <tt>cover</tt>s
  * all the input points 
- * (this is sometimes known as the Smallest Enclosing Circle).
+ * (this is also known as the <b>Smallest Enclosing Circle</b>).
  * This is equivalent to computing the Maximum Diameter 
  * of the input point set.
  * <p>
- * The geometric circle can be specified in two equivalent ways,
+ * The computed circle can be specified in two equivalent ways,
  * both of which are provide as output by this class:
  * <ul>
  * <li>As a centre point and a radius
@@ -20,15 +53,19 @@ import com.vividsolutions.jts.util.*;
  * Depending on the number of points in the input
  * and their relative positions, this
  * will be specified by anywhere from 0 to 3 points. 
- * 0 or 1 points indicate an empty or trivial input point arrangment.
- * 2 or 3 points define a circle which contains 
+ * <ul>
+ * <li>0 or 1 points indicate an empty or trivial input point arrangement.
+ * <li>2 or 3 points define a circle which contains 
  * all the input points.
  * </ul>
- * The class also provides a Geometry which approximates the
+ * </ul>
+ * The class can also output a {@link Geometry} which approximates the
  * shape of the MBC (although as an approximation 
  * it is <b>not</b> guaranteed to <tt>cover</tt> all the input points.)
  * 
  * @author Martin Davis
+ * 
+ * @see MinimumDiameter
  *
  */
 public class MinimumBoundingCircle 
@@ -149,7 +186,7 @@ public class MinimumBoundingCircle
 	
 	private void computeCirclePoints()
 	{
-		// handle degenerate cases
+		// handle degenerate or trivial cases
 		if (input.isEmpty()) {
 			extremalPts = new Coordinate[0];
 			return;
@@ -160,13 +197,12 @@ public class MinimumBoundingCircle
 			return;
 		}
 		
-		Geometry convexHull = input.convexHull();
-		
 		/**
-		 * Computing the convex hull also have the effect of eliminating duplicate points
+		 * The problem is simplified by reducing to the convex hull.
+		 * Computing the convex hull also has the useful effect of eliminating duplicate points
 		 */
+		Geometry convexHull = input.convexHull();
 		
-		// check for degenerate or trivial cases
 		Coordinate[] hullPts = convexHull.getCoordinates();
 		
 		// strip duplicate final point, if any
@@ -176,7 +212,10 @@ public class MinimumBoundingCircle
 			CoordinateArrays.copyDeep(hullPts, 0, pts, 0, hullPts.length - 1);
 		}
 		
-		if (pts.length <= 3) {
+		/**
+		 * Optimization for the trivial case where the CH has fewer than 3 points
+		 */
+		if (pts.length <= 2) {
 			extremalPts = CoordinateArrays.copyDeep(pts);
 			return;
 		}
@@ -216,7 +255,7 @@ public class MinimumBoundingCircle
 			extremalPts = new Coordinate[] { new Coordinate(P), new Coordinate(Q), new Coordinate(R) };
 			return;
 		}
-		Assert.shouldNeverReachHere("Logic failure in Minimum Bounding Circle algorithm"); 
+		Assert.shouldNeverReachHere("Logic failure in Minimum Bounding Circle algorithm!"); 
 	}
 	
 	private static Coordinate lowestPoint(Coordinate[] pts)
diff --git a/src/com/vividsolutions/jts/algorithm/MinimumDiameter.java b/src/com/vividsolutions/jts/algorithm/MinimumDiameter.java
index ad9443d..758cfdc 100644
--- a/src/com/vividsolutions/jts/algorithm/MinimumDiameter.java
+++ b/src/com/vividsolutions/jts/algorithm/MinimumDiameter.java
@@ -196,7 +196,6 @@ public class MinimumDiameter
    * Leaves the width information in the instance variables.
    *
    * @param pts
-   * @return
    */
   private void computeConvexRingMinDiameter(Coordinate[] pts)
   {
diff --git a/src/com/vividsolutions/jts/algorithm/NonRobustCGAlgorithms.java b/src/com/vividsolutions/jts/algorithm/NonRobustCGAlgorithms.java
index 35ba295..6c31f2e 100644
--- a/src/com/vividsolutions/jts/algorithm/NonRobustCGAlgorithms.java
+++ b/src/com/vividsolutions/jts/algorithm/NonRobustCGAlgorithms.java
@@ -168,7 +168,36 @@ public class NonRobustCGAlgorithms
     }
   }
 
+  /**
+   * Computes the orientation of a point q to the directed line segment p1-p2.
+   * The orientation of a point relative to a directed line segment indicates
+   * which way you turn to get to q after travelling from p1 to p2.
+   * 
+   * @return 1 if q is counter-clockwise from p1-p2
+   * @return -1 if q is clockwise from p1-p2
+   * @return 0 if q is collinear with p1-p2
+   */
   public static int computeOrientation(Coordinate p1, Coordinate p2, Coordinate q) {
+    return orientationIndex(p1, p2, q);
+  }
+  
+  /**
+   * Returns the index of the direction of the point <code>q</code> relative to
+   * a vector specified by <code>p1-p2</code>.
+   * 
+   * @param p1
+   *          the origin point of the vector
+   * @param p2
+   *          the final point of the vector
+   * @param q
+   *          the point to compute the direction to
+   * 
+   * @return 1 if q is counter-clockwise (left) from p1-p2
+   * @return -1 if q is clockwise (right) from p1-p2
+   * @return 0 if q is collinear with p1-p2
+   */
+  public static int orientationIndex(Coordinate p1, Coordinate p2, Coordinate q)
+  {
         double dx1 = p2.x - p1.x;
         double dy1 = p2.y - p1.y;
         double dx2 = q.x - p2.x;
@@ -179,4 +208,75 @@ public class NonRobustCGAlgorithms
         return 0;
   }
 
+  /**
+   * Computes the distance from a line segment AB to a line segment CD
+   * 
+   * Note: NON-ROBUST!
+   * 
+   * @param A
+   *          a point of one line
+   * @param B
+   *          the second point of (must be different to A)
+   * @param C
+   *          one point of the line
+   * @param D
+   *          another point of the line (must be different to A)
+   */
+  public static double distanceLineLine(Coordinate A, Coordinate B,
+      Coordinate C, Coordinate D)
+  {
+    // check for zero-length segments
+    if (A.equals(B))
+      return distancePointLine(A, C, D);
+    if (C.equals(D))
+      return distancePointLine(D, A, B);
+
+    // AB and CD are line segments
+    /*
+     * from comp.graphics.algo
+     * 
+     * Solving the above for r and s yields (Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy) r =
+     * ----------------------------- (eqn 1) (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
+     * 
+     * (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay) s = ----------------------------- (eqn 2)
+     * (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx) Let P be the position vector of the
+     * intersection point, then P=A+r(B-A) or Px=Ax+r(Bx-Ax) Py=Ay+r(By-Ay) By
+     * examining the values of r & s, you can also determine some other limiting
+     * conditions: If 0<=r<=1 & 0<=s<=1, intersection exists r<0 or r>1 or s<0
+     * or s>1 line segments do not intersect If the denominator in eqn 1 is
+     * zero, AB & CD are parallel If the numerator in eqn 1 is also zero, AB &
+     * CD are collinear.
+     */
+    double r_top = (A.y - C.y) * (D.x - C.x) - (A.x - C.x) * (D.y - C.y);
+    double r_bot = (B.x - A.x) * (D.y - C.y) - (B.y - A.y) * (D.x - C.x);
+
+    double s_top = (A.y - C.y) * (B.x - A.x) - (A.x - C.x) * (B.y - A.y);
+    double s_bot = (B.x - A.x) * (D.y - C.y) - (B.y - A.y) * (D.x - C.x);
+
+    if ((r_bot == 0) || (s_bot == 0)) {
+      return Math
+          .min(
+              distancePointLine(A, C, D),
+              Math.min(
+                  distancePointLine(B, C, D),
+                  Math.min(distancePointLine(C, A, B),
+                      distancePointLine(D, A, B))));
+
+    }
+    double s = s_top / s_bot;
+    double r = r_top / r_bot;
+
+    if ((r < 0) || (r > 1) || (s < 0) || (s > 1)) {
+      // no intersection
+      return Math
+          .min(
+              distancePointLine(A, C, D),
+              Math.min(
+                  distancePointLine(B, C, D),
+                  Math.min(distancePointLine(C, A, B),
+                      distancePointLine(D, A, B))));
+    }
+    return 0.0; // intersection exists
+  }
+
 }
diff --git a/src/com/vividsolutions/jts/algorithm/RayCrossingCounter.java b/src/com/vividsolutions/jts/algorithm/RayCrossingCounter.java
index 76f88d5..4ad30fc 100644
--- a/src/com/vividsolutions/jts/algorithm/RayCrossingCounter.java
+++ b/src/com/vividsolutions/jts/algorithm/RayCrossingCounter.java
@@ -84,6 +84,30 @@ public class RayCrossingCounter
     return counter.getLocation();
 	}
 	
+	 /**
+   * Determines the {@link Location} of a point in a ring. 
+   * 
+   * @param p
+   *            the point to test
+   * @param ring
+   *            a coordinate sequence forming a ring
+   * @return the location of the point in the ring
+   */
+  public static int locatePointInRing(Coordinate p, CoordinateSequence ring) {
+    RayCrossingCounter counter = new RayCrossingCounter(p);
+
+    Coordinate p1 = new Coordinate();
+    Coordinate p2 = new Coordinate();
+    for (int i = 1; i < ring.size(); i++) {
+      ring.getCoordinate(i, p1);
+      ring.getCoordinate(i - 1, p2);
+      counter.countSegment(p1, p2);
+      if (counter.isOnSegment())
+        return counter.getLocation();
+    }
+    return counter.getLocation();
+  }
+
 	private Coordinate p;
 	private int crossingCount = 0;
 	// true if the test point lies on an input segment
diff --git a/src/com/vividsolutions/jts/algorithm/RectangleLineIntersector.java b/src/com/vividsolutions/jts/algorithm/RectangleLineIntersector.java
new file mode 100644
index 0000000..baec3a3
--- /dev/null
+++ b/src/com/vividsolutions/jts/algorithm/RectangleLineIntersector.java
@@ -0,0 +1,165 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm;
+
+import com.vividsolutions.jts.geom.*;
+
+/**
+ * Computes whether a rectangle intersects line segments.
+ * <p>
+ * Rectangles contain a large amount of inherent symmetry
+ * (or to put it another way, although they contain four
+ * coordinates they only actually contain 4 ordinates
+ * worth of information).
+ * The algorithm used takes advantage of the symmetry of 
+ * the geometric situation 
+ * to optimize performance by minimizing the number
+ * of line intersection tests.
+ * 
+ * @author Martin Davis
+ *
+ */
+public class RectangleLineIntersector
+{
+  // for intersection testing, don't need to set precision model
+  private LineIntersector li = new RobustLineIntersector();
+
+  private Envelope rectEnv;
+  
+  private Coordinate diagUp0;
+  private Coordinate diagUp1;
+  private Coordinate diagDown0;
+  private Coordinate diagDown1;
+  
+  /**
+   * Creates a new intersector for the given query rectangle,
+   * specified as an {@link Envelope}.
+   * 
+   * 
+   * @param rectEnv the query rectangle, specified as an Envelope
+   */
+  public RectangleLineIntersector(Envelope rectEnv)
+  {
+    this.rectEnv = rectEnv;
+    
+    /**
+     * Up and Down are the diagonal orientations
+     * relative to the Left side of the rectangle.
+     * Index 0 is the left side, 1 is the right side.
+     */
+    diagUp0 = new Coordinate(rectEnv.getMinX(), rectEnv.getMinY());
+    diagUp1 = new Coordinate(rectEnv.getMaxX(), rectEnv.getMaxY());
+    diagDown0 = new Coordinate(rectEnv.getMinX(), rectEnv.getMaxY());
+    diagDown1 = new Coordinate(rectEnv.getMaxX(), rectEnv.getMinY());
+  }
+  
+  /**
+   * Tests whether the query rectangle intersects a 
+   * given line segment.
+   * 
+   * @param p0 the first endpoint of the segment
+   * @param p1 the second endpoint of the segment
+   * @return true if the rectangle intersects the segment
+   */
+  public boolean intersects(Coordinate p0, Coordinate p1)
+  {
+    // TODO: confirm that checking envelopes first is faster
+
+    /**
+     * If the segment envelope is disjoint from the
+     * rectangle envelope, there is no intersection
+     */
+    Envelope segEnv = new Envelope(p0, p1);
+    if (! rectEnv.intersects(segEnv))
+      return false;
+    
+    /**
+     * If either segment endpoint lies in the rectangle,
+     * there is an intersection.
+     */
+    if (rectEnv.intersects(p0)) return true;
+    if (rectEnv.intersects(p1)) return true;
+    
+    /**
+     * Normalize segment.
+     * This makes p0 less than p1,
+     * so that the segment runs to the right,
+     * or vertically upwards.
+     */
+    if (p0.compareTo(p1) > 0) {
+      Coordinate tmp = p0;
+      p0 = p1;
+      p1 = tmp;
+    }
+    /**
+     * Compute angle of segment.
+     * Since the segment is normalized to run left to right,
+     * it is sufficient to simply test the Y ordinate.
+     * "Upwards" means relative to the left end of the segment.
+     */
+    boolean isSegUpwards = false;
+    if (p1.y > p0.y)
+      isSegUpwards = true;
+    
+    /**
+     * Since we now know that neither segment endpoint
+     * lies in the rectangle, there are two possible 
+     * situations:
+     * 1) the segment is disjoint to the rectangle
+     * 2) the segment crosses the rectangle completely.
+     * 
+     * In the case of a crossing, the segment must intersect 
+     * a diagonal of the rectangle.
+     * 
+     * To distinguish these two cases, it is sufficient 
+     * to test intersection with 
+     * a single diagonal of the rectangle,
+     * namely the one with slope "opposite" to the slope
+     * of the segment.
+     * (Note that if the segment is axis-parallel,
+     * it must intersect both diagonals, so this is
+     * still sufficient.)  
+     */
+    if (isSegUpwards) {
+      li.computeIntersection(p0, p1, diagDown0, diagDown1);
+    }
+    else {
+      li.computeIntersection(p0, p1, diagUp0, diagUp1);      
+    }
+    if (li.hasIntersection())
+      return true;
+    return false;
+
+      
+  }
+}
diff --git a/src/com/vividsolutions/jts/algorithm/RobustDeterminant.java b/src/com/vividsolutions/jts/algorithm/RobustDeterminant.java
index bf49d4b..d6967ac 100644
--- a/src/com/vividsolutions/jts/algorithm/RobustDeterminant.java
+++ b/src/com/vividsolutions/jts/algorithm/RobustDeterminant.java
@@ -34,6 +34,8 @@
  */
 package com.vividsolutions.jts.algorithm;
 
+import com.vividsolutions.jts.geom.Coordinate;
+
 /**
  * @version 1.7
  */
@@ -50,6 +52,10 @@ package com.vividsolutions.jts.algorithm;
  * Author : Olivier Devillers
  * Olivier.Devillers at sophia.inria.fr
  * http:/www.inria.fr:/prisme/personnel/devillers/anglais/determinant.html
+ * 
+ * Olivier Devillers has allowed the code to be distributed under
+ * the LGPL (2012-02-16) saying "It is ok for LGPL distribution."
+ * 
  **************************************************************************
  *
  **************************************************************************
@@ -375,4 +381,44 @@ public class RobustDeterminant {
 
   }
 
+   /**
+    * Returns the index of the direction of the point <code>q</code> relative to
+    * a vector specified by <code>p1-p2</code>.
+    * 
+    * @param p1 the origin point of the vector
+    * @param p2 the final point of the vector
+    * @param q the point to compute the direction to
+    * 
+    * @return 1 if q is counter-clockwise (left) from p1-p2
+    * @return -1 if q is clockwise (right) from p1-p2
+    * @return 0 if q is collinear with p1-p2
+    */
+   public static int orientationIndex(Coordinate p1, Coordinate p2, Coordinate q)
+   {
+     /**
+      * MD - 9 Aug 2010 It seems that the basic algorithm is slightly orientation
+      * dependent, when computing the orientation of a point very close to a
+      * line. This is possibly due to the arithmetic in the translation to the
+      * origin.
+      * 
+      * For instance, the following situation produces identical results in spite
+      * of the inverse orientation of the line segment:
+      * 
+      * Coordinate p0 = new Coordinate(219.3649559090992, 140.84159161824724);
+      * Coordinate p1 = new Coordinate(168.9018919682399, -5.713787599646864);
+      * 
+      * Coordinate p = new Coordinate(186.80814046338352, 46.28973405831556); int
+      * orient = orientationIndex(p0, p1, p); int orientInv =
+      * orientationIndex(p1, p0, p);
+      * 
+      * 
+      */
+     
+     double dx1 = p2.x - p1.x;
+     double dy1 = p2.y - p1.y;
+     double dx2 = q.x - p2.x;
+     double dy2 = q.y - p2.y;
+     return signOfDet2x2(dx1, dy1, dx2, dy2);
+   }
+
 }
diff --git a/src/com/vividsolutions/jts/algorithm/RobustLineIntersector.java b/src/com/vividsolutions/jts/algorithm/RobustLineIntersector.java
index cde9cc6..753a659 100644
--- a/src/com/vividsolutions/jts/algorithm/RobustLineIntersector.java
+++ b/src/com/vividsolutions/jts/algorithm/RobustLineIntersector.java
@@ -221,9 +221,15 @@ public class RobustLineIntersector
     Coordinate p1, Coordinate p2, Coordinate q1, Coordinate q2)
   {
     Coordinate intPt = intersectionWithNormalization(p1, p2, q1, q2);
-  	// testing only
-//    Coordinate intPt = safeHCoordinateIntersection(p1, p2, q1, q2);
-
+    
+    /*
+    // TESTING ONLY
+    Coordinate intPtDD = CGAlgorithmsDD.intersection(p1, p2, q1, q2);
+    double dist = intPt.distance(intPtDD);
+    System.out.println(intPt + " - " + intPtDD + " dist = " + dist);
+    //intPt = intPtDD;
+    */
+    
     /**
      * Due to rounding it can happen that the computed intersection is
      * outside the envelopes of the input segments.  Clearly this
diff --git a/src/com/vividsolutions/jts/algorithm/match/AreaSimilarityMeasure.java b/src/com/vividsolutions/jts/algorithm/match/AreaSimilarityMeasure.java
index 381cb07..67ea103 100644
--- a/src/com/vividsolutions/jts/algorithm/match/AreaSimilarityMeasure.java
+++ b/src/com/vividsolutions/jts/algorithm/match/AreaSimilarityMeasure.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.algorithm.match;
 
 import com.vividsolutions.jts.geom.*;
diff --git a/src/com/vividsolutions/jts/algorithm/match/HausdorffSimilarityMeasure.java b/src/com/vividsolutions/jts/algorithm/match/HausdorffSimilarityMeasure.java
index 238404a..89b6bdc 100644
--- a/src/com/vividsolutions/jts/algorithm/match/HausdorffSimilarityMeasure.java
+++ b/src/com/vividsolutions/jts/algorithm/match/HausdorffSimilarityMeasure.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.algorithm.match;
 
 import com.vividsolutions.jts.geom.*;
diff --git a/src/com/vividsolutions/jts/algorithm/match/SimilarityMeasure.java b/src/com/vividsolutions/jts/algorithm/match/SimilarityMeasure.java
index bbdddb8..76a4cda 100644
--- a/src/com/vividsolutions/jts/algorithm/match/SimilarityMeasure.java
+++ b/src/com/vividsolutions/jts/algorithm/match/SimilarityMeasure.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.algorithm.match;
 
 import com.vividsolutions.jts.geom.*;
diff --git a/src/com/vividsolutions/jts/algorithm/match/SimilarityMeasureCombiner.java b/src/com/vividsolutions/jts/algorithm/match/SimilarityMeasureCombiner.java
index cb88f6d..c4fad0a 100644
--- a/src/com/vividsolutions/jts/algorithm/match/SimilarityMeasureCombiner.java
+++ b/src/com/vividsolutions/jts/algorithm/match/SimilarityMeasureCombiner.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.algorithm.match;
 
 /**
diff --git a/src/com/vividsolutions/jts/awt/FontGlyphReader.java b/src/com/vividsolutions/jts/awt/FontGlyphReader.java
index b169373..c26272b 100644
--- a/src/com/vividsolutions/jts/awt/FontGlyphReader.java
+++ b/src/com/vividsolutions/jts/awt/FontGlyphReader.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.awt;
 
 import java.util.*;
diff --git a/src/com/vividsolutions/jts/awt/PolygonShape.java b/src/com/vividsolutions/jts/awt/PolygonShape.java
index c2aaaa3..7087f6e 100644
--- a/src/com/vividsolutions/jts/awt/PolygonShape.java
+++ b/src/com/vividsolutions/jts/awt/PolygonShape.java
@@ -91,6 +91,7 @@ public class PolygonShape implements Shape
     
     void endRing()
     {
+      ringPath.closePath();
     	if (polygonPath == null) {
     		polygonPath = ringPath;
     	}
diff --git a/src/com/vividsolutions/jts/awt/ShapeReader.java b/src/com/vividsolutions/jts/awt/ShapeReader.java
index 359793b..85f868c 100644
--- a/src/com/vividsolutions/jts/awt/ShapeReader.java
+++ b/src/com/vividsolutions/jts/awt/ShapeReader.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.awt;
 
 import java.awt.Shape;
diff --git a/src/com/vividsolutions/jts/awt/ShapeWriter.java b/src/com/vividsolutions/jts/awt/ShapeWriter.java
index 0c9e5a8..4acb572 100644
--- a/src/com/vividsolutions/jts/awt/ShapeWriter.java
+++ b/src/com/vividsolutions/jts/awt/ShapeWriter.java
@@ -42,6 +42,28 @@ import com.vividsolutions.jts.geom.*;
 
 /**
  * Writes {@link Geometry}s into Java2D {@link Shape} objects
+ * of the appropriate type.
+ * This supports rendering geometries using Java2D.
+ * The ShapeWriter allows supplying a {@link PointTransformation}
+ * class, to transform coordinates from model space into view space.
+ * This is useful if a client is providing its own transformation
+ * logic, rather than relying on Java2D <tt>AffineTransform</tt>s.
+ * <p>
+ * The writer supports removing duplicate consecutive points
+ * (via the {@link #setRemoveDuplicatePoints(boolean)} method) 
+ * as well as true <b>decimation</b>
+ * (via the {@link #setDecimation(double)} method. 
+ * Enabling one of these strategies can substantially improve 
+ * rendering speed for large geometries.
+ * It is only necessary to enable one strategy.
+ * Using decimation is preferred, but this requires 
+ * determining a distance below which input geometry vertices
+ * can be considered unique (which may not always be feasible).
+ * If neither strategy is enabled, all vertices
+ * of the input <tt>Geometry</tt>
+ * will be represented in the output <tt>Shape</tt>.
+ * <p>
+ * 
  */
 public class ShapeWriter 
 {
@@ -64,6 +86,15 @@ public class ShapeWriter
 	private Point2D transPoint = new Point2D.Double();
 
 	/**
+	 * If true, decimation will be used to reduce the number of vertices
+	 * by removing consecutive duplicates.
+	 * 
+	 */
+	private boolean doRemoveDuplicatePoints = false;
+	
+	private double decimationDistance = 0;
+	
+	/**
 	 * Creates a new ShapeWriter with a specified point transformation
 	 * and point shape factory.
 	 * 
@@ -97,6 +128,43 @@ public class ShapeWriter
 	}
 
 	/**
+	 * Sets whether duplicate consecutive points should be eliminated.
+	 * This can reduce the size of the generated Shapes
+	 * and improve rendering speed, especially in situations
+	 * where a transform reduces the extent of the geometry.
+	 * <p>
+	 * The default is <tt>false</tt>.
+	 * 
+	 * @param doDecimation whether decimation is to be used
+	 */
+  public void setRemoveDuplicatePoints(boolean doRemoveDuplicatePoints)
+  {
+    this.doRemoveDuplicatePoints = doRemoveDuplicatePoints;
+  }
+  
+  /**
+   * Sets the decimation distance used to determine
+   * whether vertices of the input geometry are 
+   * considered to be duplicate and thus removed.
+   * The distance is axis distance, not Euclidean distance.
+   * The distance is specified in the input geometry coordinate system
+   * (NOT the transformed output coordinate system).
+   * <p>
+   * When rendering to a screen image, a suitably small distance should be used
+   * to avoid obvious rendering defects.  
+   * A distance equivalent to the equivalent of 1.5 pixels or less is recommended
+   * (and perhaps even smaller to avoid any chance of visible artifacts).
+   * <p>
+   * The default distance is 0.0, which disables decimation.
+   * 
+   * @param decimationDistance the distance below which vertices are considered to be duplicates
+   */
+  public void setDecimation(double decimationDistance)
+  {
+    this.decimationDistance = decimationDistance;
+  }
+  
+	/**
 	 * Creates a {@link Shape} representing a {@link Geometry}, 
 	 * according to the specified PointTransformation
 	 * and PointShapeFactory (if relevant).
@@ -129,53 +197,53 @@ public class ShapeWriter
 	{
 		PolygonShape poly = new PolygonShape();
 		
-		append(poly, p.getExteriorRing().getCoordinates());
+		appendRing(poly, p.getExteriorRing().getCoordinates());
 		for (int j = 0; j < p.getNumInteriorRing(); j++) {
-			append(poly, p.getInteriorRingN(j).getCoordinates());
+		  appendRing(poly, p.getInteriorRingN(j).getCoordinates());
 		}
 
 		return poly;
 	}
 
-	private void append(PolygonShape poly, Coordinate[] coords) 
+	private void appendRing(PolygonShape poly, Coordinate[] coords) 
 	{
-		for (int i = 0; i < coords.length; i++) {
+    double prevx = Double.NaN;
+    double prevy = Double.NaN;
+    Coordinate prev = null;
+    
+    int n = coords.length - 1;
+    /**
+     * Don't include closing point.
+     * Ring path will be closed explicitly, which provides a 
+     * more accurate path representation.
+     */
+		for (int i = 0; i < n; i++) {
+		  
+		  if (decimationDistance > 0.0) {
+		    boolean isDecimated = prev != null 
+		      && Math.abs(coords[i].x - prev.x) < decimationDistance
+		      && Math.abs(coords[i].y - prev.y) < decimationDistance;
+		    if (i < n && isDecimated) 
+		      continue;
+		    prev = coords[i];
+		  }
+		  
 			transformPoint(coords[i], transPoint);
+			
+			if (doRemoveDuplicatePoints) {
+        // skip duplicate points (except the last point)
+			  boolean isDup = transPoint.getX() == prevx && transPoint.getY() == prevy;
+        if (i < n && isDup)
+          continue;
+        prevx = transPoint.getX();
+        prevy = transPoint.getY();
+			}
 			poly.addToRing(transPoint);
 		}
+		// handle closing point
 		poly.endRing();
 	}
 	
-	/*
-	 // Obsolete (slower code)
-	private Shape OLDtoShape(Polygon p) 
-	{
-		ArrayList holeVertexCollection = new ArrayList();
-
-		for (int j = 0; j < p.getNumInteriorRing(); j++) {
-			holeVertexCollection.add(
-				toViewCoordinates(p.getInteriorRingN(j).getCoordinates()));
-		}
-
-		return new PolygonShape(
-			toViewCoordinates(p.getExteriorRing().getCoordinates()),
-			holeVertexCollection);
-	}
-
-	
-	private Coordinate[] toViewCoordinates(Coordinate[] modelCoordinates)
-	{
-		Coordinate[] viewCoordinates = new Coordinate[modelCoordinates.length];
-
-		for (int i = 0; i < modelCoordinates.length; i++) {
-			Point2D point2D = toPoint(modelCoordinates[i]);
-			viewCoordinates[i] = new Coordinate(point2D.getX(), point2D.getY());
-		}
-
-		return viewCoordinates;
-	}
-*/
-	
 	private Shape toShape(GeometryCollection gc)
 	{
 		GeometryCollectionShape shape = new GeometryCollectionShape();
@@ -202,13 +270,41 @@ public class ShapeWriter
 	{
 		GeneralPath shape = new GeneralPath();
 		
-		transformPoint(lineString.getCoordinateN(0), transPoint);
+    Coordinate prev = lineString.getCoordinateN(0);
+    transformPoint(prev, transPoint);
 		shape.moveTo((float) transPoint.getX(), (float) transPoint.getY());
 
-		for (int i = 1; i < lineString.getNumPoints(); i++) {
-			transformPoint(lineString.getCoordinateN(i), transPoint);
+    double prevx = (double) transPoint.getX();
+    double prevy = (double) transPoint.getY();
+    
+    int n = lineString.getNumPoints() - 1;
+    //int count = 0;
+    for (int i = 1; i <= n; i++) {
+      Coordinate currentCoord = lineString.getCoordinateN(i);
+      if (decimationDistance > 0.0) {
+        boolean isDecimated = prev != null
+            && Math.abs(currentCoord.x - prev.x) < decimationDistance
+            && Math.abs(currentCoord.y - prev.y) < decimationDistance;
+        if (i < n && isDecimated) {
+          continue;
+        }
+        prev = currentCoord;
+      }
+
+      transformPoint(currentCoord, transPoint);
+
+			if (doRemoveDuplicatePoints) {
+  			// skip duplicate points (except the last point)
+			  boolean isDup = transPoint.getX() == prevx && transPoint.getY() == prevy;
+  			if (i < n && isDup)
+  			  continue;
+  			prevx = transPoint.getX();
+  			prevy = transPoint.getY();
+  			//count++;
+			}
 			shape.lineTo((float) transPoint.getX(), (float) transPoint.getY());
 		}
+		//System.out.println(count);
 		return shape;
 	}
 
@@ -224,12 +320,6 @@ public class ShapeWriter
   
   private Point2D transformPoint(Coordinate model, Point2D view) {
 		pointTransformer.transform(model, view);
-		/**
-		 * Do the rounding now instead of relying on Java 2D rounding. Java2D seems
-		 * to do rounding differently for drawing and filling, resulting in the draw
-		 * being a pixel off from the fill sometimes.
-		 */
-		view.setLocation(Math.round(view.getX()), Math.round(view.getY()));
 		return view;
 	}
 }
diff --git a/src/com/vividsolutions/jts/geom/Coordinate.java b/src/com/vividsolutions/jts/geom/Coordinate.java
index 6888eb4..1678749 100644
--- a/src/com/vividsolutions/jts/geom/Coordinate.java
+++ b/src/com/vividsolutions/jts/geom/Coordinate.java
@@ -64,6 +64,14 @@ public class Coordinate implements Comparable, Cloneable, Serializable {
    * greater than the defined dimension of a coordinate.
    */
   public static final double NULL_ORDINATE = Double.NaN;
+  
+  /**
+   * Standard ordinate index values
+   */
+  public static final int X = 0;
+  public static final int Y = 1;
+  public static final int Z = 2;
+
   /**
    *  The x-coordinate.
    */
@@ -117,8 +125,6 @@ public class Coordinate implements Comparable, Cloneable, Serializable {
     this(x, y, NULL_ORDINATE);
   }
 
-
-
   /**
    *  Sets this <code>Coordinate</code>s (x,y,z) values to that of <code>other</code>.
    *
@@ -131,6 +137,52 @@ public class Coordinate implements Comparable, Cloneable, Serializable {
   }
 
   /**
+   * Gets the ordinate value for the given index.
+   * The supported values for the index are 
+   * {@link X}, {@link Y}, and {@link Z}.
+   * 
+   * @param ordinateIndex the ordinate index
+   * @return the value of the ordinate
+   * @throws IllegalArgumentException if the index is not valid
+   */
+  public double getOrdinate(int ordinateIndex)
+  {
+    switch (ordinateIndex) {
+    case X: return x;
+    case Y: return y;
+    case Z: return z;
+    }
+    throw new IllegalArgumentException("Invalid ordinate index: " + ordinateIndex);
+  }
+  
+  /**
+   * Sets the ordinate for the given index
+   * to a given value.
+   * The supported values for the index are 
+   * {@link X}, {@link Y}, and {@link Z}.
+   * 
+   * @param ordinateIndex the ordinate index
+   * @param value the value to set
+   * @throws IllegalArgumentException if the index is not valid
+   */
+  public void setOrdinate(int ordinateIndex, double value)
+  {
+    switch (ordinateIndex) {
+      case X:
+        x = value;
+        break;
+      case Y:
+        y = value;
+        break;
+      case Z:
+        z = value;
+        break;
+      default:
+        throw new IllegalArgumentException("Invalid ordinate index: " + ordinateIndex);
+    }
+  }
+
+  /**
    *  Returns whether the planar projections of the two <code>Coordinate</code>s
    *  are equal.
    *
diff --git a/src/com/vividsolutions/jts/geom/CoordinateArrays.java b/src/com/vividsolutions/jts/geom/CoordinateArrays.java
index 4f67692..f4e38cb 100644
--- a/src/com/vividsolutions/jts/geom/CoordinateArrays.java
+++ b/src/com/vividsolutions/jts/geom/CoordinateArrays.java
@@ -296,6 +296,29 @@ public class CoordinateArrays {
   }
 
   /**
+   * Collapses a coordinate array to remove all null elements.
+   * 
+   * @param coord the coordinate array to collapse
+   * @return an array containing only non-null elements
+   */
+  public static Coordinate[] removeNull(Coordinate[] coord)
+  {
+    int nonNull = 0;
+    for (int i = 0; i < coord.length; i++) {
+      if (coord[i] != null) nonNull++;
+    }
+    Coordinate[] newCoord = new Coordinate[nonNull];
+    // empty case
+    if (nonNull == 0) return newCoord;
+    
+    int j = 0;
+    for (int i = 0; i < coord.length; i++) {
+      if (coord[i] != null) newCoord[j++] = coord[i];
+    }
+    return newCoord;
+  }
+  
+  /**
    * Reverses the coordinates in an array in-place.
    */
   public static void reverse(Coordinate[] coord)
diff --git a/src/com/vividsolutions/jts/geom/CoordinateSequenceComparator.java b/src/com/vividsolutions/jts/geom/CoordinateSequenceComparator.java
index de2985a..e78f528 100644
--- a/src/com/vividsolutions/jts/geom/CoordinateSequenceComparator.java
+++ b/src/com/vividsolutions/jts/geom/CoordinateSequenceComparator.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.geom;
 
 import java.util.Comparator;
diff --git a/src/com/vividsolutions/jts/geom/CoordinateSequences.java b/src/com/vividsolutions/jts/geom/CoordinateSequences.java
index 8056f80..30a6873 100644
--- a/src/com/vividsolutions/jts/geom/CoordinateSequences.java
+++ b/src/com/vividsolutions/jts/geom/CoordinateSequences.java
@@ -140,6 +140,7 @@ public class CoordinateSequences {
   public static CoordinateSequence ensureValidRing(CoordinateSequenceFactory fact, CoordinateSequence seq)
   {
   	int n = seq.size();
+  	// empty sequence is valid
   	if (n == 0) return seq; 
   	// too short - make a new one
   	if (n <= 3) 
@@ -154,13 +155,26 @@ public class CoordinateSequences {
   
   private static CoordinateSequence createClosedRing(CoordinateSequenceFactory fact, CoordinateSequence seq, int size)
   {
-  	CoordinateSequence newseq = fact.create(size, seq.getDimension());
-  	int n = seq.size();
-  	copy(seq, 0, newseq, 0, n);
-  	// fill remaining coordinates with start point
-  	for (int i = n; i < size; i++)
-  		copy(seq, 0, newseq, i, 1);
-  	return newseq;
+    CoordinateSequence newseq = fact.create(size, seq.getDimension());
+    int n = seq.size();
+    copy(seq, 0, newseq, 0, n);
+    // fill remaining coordinates with start point
+    for (int i = n; i < size; i++)
+      copy(seq, 0, newseq, i, 1);
+    return newseq;
+  }
+  
+  public static CoordinateSequence extend(CoordinateSequenceFactory fact, CoordinateSequence seq, int size)
+  {
+    CoordinateSequence newseq = fact.create(size, seq.getDimension());
+    int n = seq.size();
+    copy(seq, 0, newseq, 0, n);
+    // fill remaining coordinates with end point, if it exists
+    if (n > 0) {
+      for (int i = n; i < size; i++)
+        copy(seq, n-1, newseq, i, 1);
+    }
+    return newseq;
   }
   
 }
\ No newline at end of file
diff --git a/src/com/vividsolutions/jts/geom/DefaultCoordinateSequence.java b/src/com/vividsolutions/jts/geom/DefaultCoordinateSequence.java
index 292d186..9faa258 100644
--- a/src/com/vividsolutions/jts/geom/DefaultCoordinateSequence.java
+++ b/src/com/vividsolutions/jts/geom/DefaultCoordinateSequence.java
@@ -64,10 +64,9 @@ class DefaultCoordinateSequence
   }
 
   /**
-   * Constructs a DefaultCoordinateSequence based on the given array (the
-   * array is not copied).
+   * Creates a new sequence based on a deep copy of the given {@link CoordinateSequence}.
    *
-   * @param coordinates the coordinate array that will be referenced.
+   * @param coordSeq the coordinate sequence that will be copied.
    */
   public DefaultCoordinateSequence(CoordinateSequence coordSeq) {
     coordinates = new Coordinate[coordSeq.size()];
diff --git a/src/com/vividsolutions/jts/geom/Dimension.java b/src/com/vividsolutions/jts/geom/Dimension.java
index 5e60451..7c51238 100644
--- a/src/com/vividsolutions/jts/geom/Dimension.java
+++ b/src/com/vividsolutions/jts/geom/Dimension.java
@@ -75,6 +75,36 @@ public class Dimension {
   public final static int DONTCARE = -3;
 
   /**
+   * Symbol for the FALSE pattern matrix entry
+   */
+  public final static char SYM_FALSE = 'F';
+  
+  /**
+   * Symbol for the TRUE pattern matrix entry
+   */
+  public final static char SYM_TRUE = 'T';
+  
+  /**
+   * Symbol for the DONTCARE pattern matrix entry
+   */
+  public final static char SYM_DONTCARE = '*';
+  
+  /**
+   * Symbol for the P (dimension 0) pattern matrix entry
+   */
+  public final static char SYM_P = '0';
+  
+  /**
+   * Symbol for the L (dimension 1) pattern matrix entry
+   */
+  public final static char SYM_L = '1';
+  
+  /**
+   * Symbol for the A (dimension 2) pattern matrix entry
+   */
+  public final static char SYM_A = '2';
+  
+  /**
    *  Converts the dimension value to a dimension symbol, for example, <code>TRUE => 'T'</code>
    *  .
    *
@@ -87,17 +117,17 @@ public class Dimension {
   public static char toDimensionSymbol(int dimensionValue) {
     switch (dimensionValue) {
       case FALSE:
-        return 'F';
+        return SYM_FALSE;
       case TRUE:
-        return 'T';
+        return SYM_TRUE;
       case DONTCARE:
-        return '*';
+        return SYM_DONTCARE;
       case P:
-        return '0';
+        return SYM_P;
       case L:
-        return '1';
+        return SYM_L;
       case A:
-        return '2';
+        return SYM_A;
     }
     throw new IllegalArgumentException("Unknown dimension value: " + dimensionValue);
   }
@@ -114,17 +144,17 @@ public class Dimension {
    */
   public static int toDimensionValue(char dimensionSymbol) {
     switch (Character.toUpperCase(dimensionSymbol)) {
-      case 'F':
+      case SYM_FALSE:
         return FALSE;
-      case 'T':
+      case SYM_TRUE:
         return TRUE;
-      case '*':
+      case SYM_DONTCARE:
         return DONTCARE;
-      case '0':
+      case SYM_P:
         return P;
-      case '1':
+      case SYM_L:
         return L;
-      case '2':
+      case SYM_A:
         return A;
     }
     throw new IllegalArgumentException("Unknown dimension symbol: " + dimensionSymbol);
diff --git a/src/com/vividsolutions/jts/geom/Envelope.java b/src/com/vividsolutions/jts/geom/Envelope.java
index 0a67a6f..f251e2c 100644
--- a/src/com/vividsolutions/jts/geom/Envelope.java
+++ b/src/com/vividsolutions/jts/geom/Envelope.java
@@ -83,8 +83,10 @@ public class Envelope
   }
 
   /**
-   * Test the envelope defined by p1-p2 for intersection
-   * with the envelope defined by q1-q2
+   * Tests whether the envelope defined by p1-p2
+   * and the envelope defined by q1-q2
+   * intersect.
+   * 
    * @param p1 one extremal point of the envelope P
    * @param p2 another extremal point of the envelope P
    * @param q1 one extremal point of the envelope Q
diff --git a/src/com/vividsolutions/jts/geom/Geometry.java b/src/com/vividsolutions/jts/geom/Geometry.java
index bab0eff..ba0357f 100644
--- a/src/com/vividsolutions/jts/geom/Geometry.java
+++ b/src/com/vividsolutions/jts/geom/Geometry.java
@@ -58,25 +58,25 @@ import com.vividsolutions.jts.util.Assert;
  *  <H3>Binary Predicates</H3>
  * Because it is not clear at this time
  * what semantics for spatial
- *  analysis methods involving <code>GeometryCollection</code>s would be useful,
- *  <code>GeometryCollection</code>s are not supported as arguments to binary
- *  predicates (other than <code>convexHull</code>) or the <code>relate</code>
- *  method.
+ * analysis methods involving <code>GeometryCollection</code>s would be useful,
+ * <code>GeometryCollection</code>s are not supported as arguments to binary
+ * predicates or the <code>relate</code>
+ * method.
  *
- *  <H3>Overlay Methods</H3>
+ * <H3>Overlay Methods</H3>
  *
- *  The overlay methods 
- *  return the most specific class possible to represent the result. If the
- *  result is homogeneous, a <code>Point</code>, <code>LineString</code>, or
- *  <code>Polygon</code> will be returned if the result contains a single
- *  element; otherwise, a <code>MultiPoint</code>, <code>MultiLineString</code>,
- *  or <code>MultiPolygon</code> will be returned. If the result is
- *  heterogeneous a <code>GeometryCollection</code> will be returned. <P>
+ * The overlay methods 
+ * return the most specific class possible to represent the result. If the
+ * result is homogeneous, a <code>Point</code>, <code>LineString</code>, or
+ * <code>Polygon</code> will be returned if the result contains a single
+ * element; otherwise, a <code>MultiPoint</code>, <code>MultiLineString</code>,
+ * or <code>MultiPolygon</code> will be returned. If the result is
+ * heterogeneous a <code>GeometryCollection</code> will be returned. <P>
  *
- *  Because it is not clear at this time what semantics for set-theoretic
- *  methods involving <code>GeometryCollection</code>s would be useful,
+ * Because it is not clear at this time what semantics for set-theoretic
+ * methods involving <code>GeometryCollection</code>s would be useful,
  * <code>GeometryCollections</code>
- *  are not supported as arguments to the set-theoretic methods.
+ * are not supported as arguments to the set-theoretic methods.
  *
  *  <H4>Representation of Computed Geometries </H4>
  *
@@ -126,7 +126,7 @@ import com.vividsolutions.jts.util.Assert;
  *
  * <h3>Geometry Equality</h3>
  * 
- * JTS provides two ways of comparing geometries for equality: 
+ * There are two ways of comparing geometries for equality: 
  * <b>structural equality</b> and <b>topological equality</b>.
  * 
  * <h4>Structural Equality</h4>
@@ -153,20 +153,17 @@ import com.vividsolutions.jts.util.Assert;
  * 
  * <h4>Topological Equality</h4>
  * 
- * Topological Equality 
- * implements the SFS definition of point-set equality
+ * Topological Equality is provided by the 
+ * {@link #equalsTopo(Geometry)} method. 
+ * It implements the SFS definition of point-set equality
  * defined in terms of the DE-9IM matrix.
- * It is is provided by the 
- * {@link #equalsTopo(Geometry)}
- * method.  
  * To support the SFS naming convention, the method
- *  {@link #equals(Geometry)} is also provided as a synonym.  
- *  However, due to the potential for confusion with {@link #equals(Geometry)}
- *  its use is discouraged.
+ * {@link #equals(Geometry)} is also provided as a synonym.  
+ * However, due to the potential for confusion with {@link #equals(Object)}
+ * its use is discouraged.
  * <p>
- *  Since #equals(Object) and #hashCode are overridden, 
- *  Geometries can be used effectively in 
- *  Java collections.
+ * Since {@link #equals(Object)} and {@link #hashCode()} are overridden, 
+ * Geometries can be used effectively in Java collections.
  *
  *@version 1.7
  */
@@ -205,7 +202,7 @@ public abstract class Geometry
   private Object userData = null;
 
   /**
-   * Creates a new <tt>Geometry</tt> via the specified GeometryFactory.
+   * Creates a new <code>Geometry</code> via the specified GeometryFactory.
    *
    * @param factory
    */
@@ -215,16 +212,14 @@ public abstract class Geometry
   }
 
   /**
-   *  Returns the name of this object's <code>com.vivid.jts.geom</code>
-   *  interface.
+   * Returns the name of this Geometry's actual class.
    *
-   *@return    the name of this <code>Geometry</code>s most specific <code>com.vividsolutions.jts.geom</code>
-   *      interface
+   *@return the name of this <code>Geometry</code>s actual class
    */
   public abstract String getGeometryType();
 
   /**
-   *  Returns true if the array contains any non-empty <code>Geometry</code>s.
+   * Returns true if the array contains any non-empty <code>Geometry</code>s.
    *
    *@param  geometries  an array of <code>Geometry</code>s; no elements may be
    *      <code>null</code>
@@ -396,39 +391,40 @@ public abstract class Geometry
 
   /**
    * Tests whether this {@link Geometry} is simple.
-   * In general, the SFS specification of simplicity
-   * follows the rule:
-   *  <UL>
-   *    <LI> A Geometry is simple iff the only self-intersections are at
-   *    boundary points.
-   *  </UL>
+   * The SFS definition of simplicity
+   * follows the general rule that a Geometry is simple if it has no points of
+   * self-tangency, self-intersection or other anomalous points.
+   * <p>
    * Simplicity is defined for each {@link Geometry} subclass as follows:
    * <ul>
-   * <li>Valid polygonal geometries are simple by definition, so
-   * <code>isSimple</code> trivially returns true.
+   * <li>Valid polygonal geometries are simple, since their rings
+   * must not self-intersect.  <code>isSimple</code>
+   * tests for this condition and reports <code>false</code> if it is not met.
+   * (This is a looser test than checking for validity).
+   * <li>Linear rings have the same semantics.
    * <li>Linear geometries are simple iff they do not self-intersect at points
    * other than boundary points.
    * <li>Zero-dimensional geometries (points) are simple iff they have no
    * repeated points.
-   * <li>Empty <code>Geometry</code>s are always simple
+   * <li>Empty <code>Geometry</code>s are always simple.
    * <ul>
    *
-   * @return    <code>true</code> if this <code>Geometry</code> has any points of
-   *      self-tangency, self-intersection or other anomalous points
+   * @return <code>true</code> if this <code>Geometry</code> is simple
    * @see #isValid
    */
   public boolean isSimple()
   {
-    checkNotGeometryCollection(this);
     IsSimpleOp op = new IsSimpleOp(this);
     return op.isSimple();
   }
 
   /**
-   *  Tests the validity of this <code>Geometry</code>.
-   *  Subclasses provide their own definition of "valid".
+   * Tests whether this <code>Geometry</code>
+   * is topologically valid, according to the OGC SFS specification.
+   * <p>
+   * For validity rules see the Javadoc for the specific Geometry subclass.
    *
-   *@return    <code>true</code> if this <code>Geometry</code> is valid
+   *@return <code>true</code> if this <code>Geometry</code> is valid
    *
    * @see IsValidOp
    */
@@ -438,19 +434,18 @@ public abstract class Geometry
   }
 
   /**
-   *  Returns whether or not the set of points in this <code>Geometry</code> is
-   *  empty.
+   * Tests whether the set of points covered by this <code>Geometry</code> is
+   * empty.
    *
-   *@return    <code>true</code> if this <code>Geometry</code> equals the empty
-   *      geometry
+   *@return <code>true</code> if this <code>Geometry</code> does not cover any points
    */
   public abstract boolean isEmpty();
 
   /**
    *  Returns the minimum distance between this <code>Geometry</code>
-   *  and the <code>Geometry</code> g
+   *  and another <code>Geometry</code>.
    *
-   * @param  g  the <code>Geometry</code> from which to compute the distance
+   * @param  g the <code>Geometry</code> from which to compute the distance
    * @return the distance between the geometries
    * @return 0 if either input geometry is empty
    * @throws IllegalArgumentException if g is null
@@ -520,13 +515,16 @@ public abstract class Geometry
    * The centroid
    * is equal to the centroid of the set of component Geometries of highest
    * dimension (since the lower-dimension geometries contribute zero
-   * "weight" to the centroid)
+   * "weight" to the centroid).
+   * <p>
+   * The centroid of an empty geometry is <code>POINT EMPTY</code>.
    *
    * @return a {@link Point} which is the centroid of this Geometry
    */
   public Point getCentroid()
   {
-    if (isEmpty()) { return null; }
+    if (isEmpty()) 
+      return factory.createPoint((Coordinate) null);
     Coordinate centPt = null;
     int dim = getDimension();
     if (dim == 0) {
@@ -553,11 +551,15 @@ public abstract class Geometry
    * An interior point is guaranteed to lie in the interior of the Geometry,
    * if it possible to calculate such a point exactly. Otherwise,
    * the point may lie on the boundary of the geometry.
+   * <p>
+   * The interior point of an empty geometry is <code>POINT EMPTY</code>.
    *
    * @return a {@link Point} which is in the interior of this Geometry
    */
   public Point getInteriorPoint()
   {
+    if (isEmpty()) 
+      return factory.createPoint((Coordinate) null);
     Coordinate interiorPt = null;
     int dim = getDimension();
     if (dim == 0) {
@@ -614,32 +616,46 @@ public abstract class Geometry
   public abstract int getBoundaryDimension();
 
   /**
-   *  Returns this <code>Geometry</code>s bounding box. If this <code>Geometry</code>
-   *  is the empty geometry, returns an empty <code>Point</code>. If the <code>Geometry</code>
-   *  is a point, returns a non-empty <code>Point</code>. Otherwise, returns a
-   *  <code>Polygon</code> whose points are (minx, miny), (maxx, miny), (maxx,
-   *  maxy), (minx, maxy), (minx, miny).
+   *  Gets a Geometry representing the envelope (bounding box) of 
+   *  this <code>Geometry</code>. 
+   *  <p>
+   *  If this <code>Geometry</code> is:
+   *  <ul>
+   *  <li>empty, returns an empty <code>Point</code>. 
+   *  <li>a point, returns a <code>Point</code>.
+   *  <li>a line parallel to an axis, a two-vertex <code>LineString</code> 
+   *  <li>otherwise, returns a
+   *  <code>Polygon</code> whose vertices are (minx miny, maxx miny, 
+   *  maxx maxy, minx maxy, minx miny).
+   *  </ul>
    *
-   *@return    an empty <code>Point</code> (for empty <code>Geometry</code>s), a
-   *      <code>Point</code> (for <code>Point</code>s) or a <code>Polygon</code>
-   *      (in all other cases)
+   *@return a Geometry representing the envelope of this Geometry
+   *      
+   * @see GeometryFactory#toGeometry(Envelope) 
    */
   public Geometry getEnvelope() {
     return getFactory().toGeometry(getEnvelopeInternal());
   }
 
   /**
-   *  Returns the minimum and maximum x and y values in this <code>Geometry</code>
-   *  , or a null <code>Envelope</code> if this <code>Geometry</code> is empty.
+   * Gets an {@link Envelope} containing 
+   * the minimum and maximum x and y values in this <code>Geometry</code>.
+   * If the geometry is empty, an empty <code>Envelope</code> 
+   * is returned.
+   * <p>
+   * The returned object is a copy of the one maintained internally,
+   * to avoid aliasing issues.  
+   * For best performance, clients which access this
+   * envelope frequently should cache the return value.
    *
-   *@return    this <code>Geometry</code>s bounding box; if the <code>Geometry</code>
-   *      is empty, <code>Envelope#isNull</code> will return <code>true</code>
+   *@return the envelope of this <code>Geometry</code>.
+   *@return an empty Envelope if this Geometry is empty
    */
   public Envelope getEnvelopeInternal() {
     if (envelope == null) {
       envelope = computeEnvelopeInternal();
     }
-    return envelope;
+    return new Envelope(envelope);
   }
 
   /**
@@ -647,6 +663,7 @@ public abstract class Geometry
    * party (for example, via a {@link CoordinateFilter}). 
    * When this method is called the geometry will flush
    * and/or update any derived information it has cached (such as its {@link Envelope} ).
+   * The operation is applied to all component Geometries.
    */
   public void geometryChanged() {
     apply(geometryChangedFilter);
@@ -656,6 +673,7 @@ public abstract class Geometry
    * Notifies this Geometry that its Coordinates have been changed by an external
    * party. When #geometryChanged is called, this method will be called for
    * this Geometry and its component Geometries.
+   * 
    * @see #apply(GeometryComponentFilter)
    */
   protected void geometryChangedAction() {
@@ -916,10 +934,10 @@ public abstract class Geometry
    * <li><code>g.coveredBy(this) = true</code>
    * <br>(<code>covers</code> is the converse of {@link #coveredBy})
    * </ul>
-   * If either geometry is empty, the value of this predicate is <tt>false</tt>.
+   * If either geometry is empty, the value of this predicate is <code>false</code>.
    * <p>
    * This predicate is similar to {@link #contains},
-   * but is more inclusive (i.e. returns <tt>true</tt> for more cases).
+   * but is more inclusive (i.e. returns <code>true</code> for more cases).
    * In particular, unlike <code>contains</code> it does not distinguish between
    * points in the boundary and in the interior of geometries.
    * For most situations, <code>covers</code> should be used in preference to <code>contains</code>.
@@ -962,10 +980,10 @@ public abstract class Geometry
    * <li><code>g.covers(this) = true</code>
    * <br>(<code>coveredBy</code> is the converse of {@link #covers})
    * </ul>
-   * If either geometry is empty, the value of this predicate is <tt>false</tt>.
+   * If either geometry is empty, the value of this predicate is <code>false</code>.
    * <p>
    * This predicate is similar to {@link #within},
-   * but is more inclusive (i.e. returns <tt>true</tt> for more cases).
+   * but is more inclusive (i.e. returns <code>true</code> for more cases).
    *
    *@param  g  the <code>Geometry</code> with which to compare this <code>Geometry</code>
    *@return        <code>true</code> if this <code>Geometry</code> is covered by <code>g</code>
@@ -1040,14 +1058,14 @@ public abstract class Geometry
 
   /**
    * Tests whether this geometry is topologically equal to the argument geometry
-   * as defined by the SFS <tt>equals</tt> predicate.
+   * as defined by the SFS <code>equals</code> predicate.
    * <p>
    * The SFS <code>equals</code> predicate has the following equivalent definitions:
    * <ul>
    * <li>The two geometries have at least one point in common,
    * and no point of either geometry lies in the exterior of the other geometry.
    * <li>The DE-9IM Intersection Matrix for the two geometries matches
-   * the pattern <tt>T*F**FFF*</tt> 
+   * the pattern <code>T*F**FFF*</code> 
    * <pre>
    * T*F
    * **F
@@ -1072,9 +1090,9 @@ public abstract class Geometry
   
   /**
    * Tests whether this geometry is structurally and numerically equal
-   * to a given <tt>Object</tt>.
-   * If the argument <tt>Object</tt> is not a <tt>Geometry</tt>, 
-   * the result is <tt>false</tt>.
+   * to a given <code>Object</code>.
+   * If the argument <code>Object</code> is not a <code>Geometry</code>, 
+   * the result is <code>false</code>.
    * Otherwise, the result is computed using
    * {@link #equalsExact(Geometry)}.
    * <p>
@@ -1083,7 +1101,7 @@ public abstract class Geometry
    * In conjunction with {@link #hashCode()} 
    * it provides semantics which are most useful 
    * for using
-   * <tt>Geometry</tt>s as keys and values in Java collections.
+   * <code>Geometry</code>s as keys and values in Java collections.
    * <p>
    * Note that to produce the expected result the input geometries
    * should be in normal form.  It is the caller's 
@@ -1106,6 +1124,11 @@ public abstract class Geometry
     return equalsExact(g);
   }
   
+  /**
+   * Gets a hash code for the Geometry.
+   * 
+   * @return an integer value suitable for use as a hashcode
+   */
   public int hashCode()
   {
     return getEnvelopeInternal().hashCode();
@@ -1136,7 +1159,7 @@ public abstract class Geometry
 	 * To represent these arcs using linear geometry they must be approximated with line segments.
 	 * The buffer geometry is constructed using 8 segments per quadrant to approximate 
 	 * the circular arcs.
-	 * The end cap style is <tt>CAP_ROUND</tt>.
+	 * The end cap style is <code>CAP_ROUND</code>.
 	 * <p>
 	 * The buffer operation always returns a polygonal result. The negative or
 	 * zero-distance buffer of lines and points is always an empty {@link Polygon}.
@@ -1204,9 +1227,9 @@ public abstract class Geometry
    * The end cap style specifies the buffer geometry that will be
    * created at the ends of linestrings.  The styles provided are:
    * <ul>
-   * <li><tt>BufferOp.CAP_ROUND</tt> - (default) a semi-circle
-   * <li><tt>BufferOp.CAP_BUTT</tt> - a straight line perpendicular to the end segment
-   * <li><tt>BufferOp.CAP_SQUARE</tt> - a half-square
+   * <li><code>BufferOp.CAP_ROUND</code> - (default) a semi-circle
+   * <li><code>BufferOp.CAP_BUTT</code> - a straight line perpendicular to the end segment
+   * <li><code>BufferOp.CAP_SQUARE</code> - a half-square
    * </ul>
 	 * <p>
 	 * The buffer operation always returns a polygonal result. The negative or
@@ -1271,23 +1294,25 @@ public abstract class Geometry
   public abstract Geometry reverse();
   
   /**
-   * Computes a <code>Geometry</code> representing the points shared by this
-   * <code>Geometry</code> and <code>other</code>.
+   * Computes a <code>Geometry</code> representing the point-set which is
+   * common to both this <code>Geometry</code> and the <code>other</code> Geometry.
+   * <p>
+   * The intersection of two geometries of different dimension produces a result
+   * geometry of dimension less than or equal to the minimum dimension of the input
+   * geometries. 
+   * The result geometry may be a heterogenous {@link GeometryCollection}.
+   * If the result is empty, it is an atomic geometry
+   * with the dimension of the lowest input dimension.
    * <p>
    * Intersection of {@link GeometryCollection}s is supported
-   * only for homogeneous collection types.
-   * The result is a {@link GeometryCollection} of the
-   * intersection of each element of the target with the argument. 
+   * only for homogeneous collection types. 
    * <p>
-   * The intersection of two geometries of different dimension produces a result
-   * geometry of dimension equal to the minimum dimension of the input
-   * geometries. The result geometry is always a homogeneous
-   * {@link GeometryCollection}.
+   * Non-empty heterogeneous {@link GeometryCollection} arguments are not supported.
    *
    * @param  other the <code>Geometry</code> with which to compute the intersection
-   * @return the point-set common to the two <code>Geometry</code>s
+   * @return a Geometry representing the point-set common to the two <code>Geometry</code>s
    * @throws TopologyException if a robustness error occurs
-   * @throws IllegalArgumentException if the argument is a non-empty heterogeneous GeometryCollection
+   * @throws IllegalArgumentException if the argument is a non-empty heterogeneous <code>GeometryCollection</code>
    */
   public Geometry intersection(Geometry other)
   {
@@ -1295,15 +1320,15 @@ public abstract class Geometry
   	 * TODO: MD - add optimization for P-A case using Point-In-Polygon
   	 */
     // special case: if one input is empty ==> empty
-    if (this.isEmpty()) return this.getFactory().createGeometryCollection(null);
-    if (other.isEmpty()) return this.getFactory().createGeometryCollection(null);
+    if (this.isEmpty() || other.isEmpty()) 
+      return OverlayOp.createEmptyResult(OverlayOp.INTERSECTION, this, other, factory);
 
     // compute for GCs
-    if (isGeometryCollection(this)) {
+    if (this.isGeometryCollection()) {
       final Geometry g2 = other;
       return GeometryCollectionMapper.map(
           (GeometryCollection) this,
-          new GeometryCollectionMapper.MapOp() {
+          new GeometryMapper.MapOp() {
         public Geometry map(Geometry g) {
           return g.intersection(g2);
         }
@@ -1318,16 +1343,17 @@ public abstract class Geometry
   }
 
   /**
-   * Computes a <tt>Geometry</tt> representing all the points in this
-   * <tt>Geometry</tt> and <tt>other</tt>.
-   * <p>
-   * The method may be used on arguments of different dimension, but it does not
-   * support {@link GeometryCollection} arguments.
+   * Computes a <code>Geometry</code> representing the point-set 
+   * which is contained in both this
+   * <code>Geometry</code> and the <code>other</code> Geometry.
    * <p>
    * The union of two geometries of different dimension produces a result
    * geometry of dimension equal to the maximum dimension of the input
-   * geometries. The result geometry may be a heterogenous
+   * geometries. 
+   * The result geometry may be a heterogenous
    * {@link GeometryCollection}.
+   * If the result is empty, it is an atomic geometry
+   * with the dimension of the highest input dimension.
    * <p>
    * Unioning {@link LineString}s has the effect of
    * <b>noding</b> and <b>dissolving</b> the input linework. In this context
@@ -1337,6 +1363,8 @@ public abstract class Geometry
    * segments will be reduced to a single line segment in the result. 
    * If <b>merged</b> linework is required, the {@link LineMerger}
    * class can be used.
+   * <p>
+   * Non-empty {@link GeometryCollection} arguments are not supported.
    * 
    * @param other
    *          the <code>Geometry</code> with which to compute the union
@@ -1350,10 +1378,16 @@ public abstract class Geometry
    */
   public Geometry union(Geometry other)
   {
+    // handle empty geometry cases
+    if (this.isEmpty() || other.isEmpty()) {
+      if (this.isEmpty() && other.isEmpty())
+        return OverlayOp.createEmptyResult(OverlayOp.UNION, this, other, factory);
+        
     // special case: if either input is empty ==> other input
-    if (this.isEmpty()) return (Geometry) other.clone();
-    if (other.isEmpty()) return (Geometry) clone();
-
+      if (this.isEmpty()) return (Geometry) other.clone();
+      if (other.isEmpty()) return (Geometry) clone();
+    }
+    
     // TODO: optimize if envelopes of geometries do not intersect
     
     checkNotGeometryCollection(this);
@@ -1362,24 +1396,26 @@ public abstract class Geometry
   }
 
   /**
-   *  Computes a <code>Geometry</code> representing the points making up this
-   *  <code>Geometry</code> that do not make up <code>other</code>. This method
-   *  returns the closure of the resultant <code>Geometry</code>.
+   * Computes a <code>Geometry</code> representing the closure of the point-set
+   * of the points contained in this <code>Geometry</code> that are not contained in 
+   * the <code>other</code> Geometry. 
+   * <p>
+   * If the result is empty, it is an atomic geometry
+   * with the dimension of the left-hand input.
+   * <p>
+   * Non-empty {@link GeometryCollection} arguments are not supported.
    *
    *@param  other  the <code>Geometry</code> with which to compute the
    *      difference
-   *@return        the point set difference of this <code>Geometry</code> with
+   *@return a Geometry representing the point-set difference of this <code>Geometry</code> with
    *      <code>other</code>
    * @throws TopologyException if a robustness error occurs
    * @throws IllegalArgumentException if either input is a non-empty GeometryCollection
    */
   public Geometry difference(Geometry other)
   {
-    // mod to handle empty cases better - return type of input
-    //if (this.isEmpty() || other.isEmpty()) return (Geometry) clone();
-    
     // special case: if A.isEmpty ==> empty; if B.isEmpty ==> A
-    if (this.isEmpty()) return this.getFactory().createGeometryCollection(null);
+    if (this.isEmpty()) return OverlayOp.createEmptyResult(OverlayOp.DIFFERENCE, this, other, factory);
     if (other.isEmpty()) return (Geometry) clone();
 
     checkNotGeometryCollection(this);
@@ -1388,23 +1424,35 @@ public abstract class Geometry
   }
 
   /**
-   *  Returns a set combining the points in this <code>Geometry</code> not in
-   *  <code>other</code>, and the points in <code>other</code> not in this
-   *  <code>Geometry</code>. This method returns the closure of the resultant
-   *  <code>Geometry</code>.
+   * Computes a <coe>Geometry </code> representing the closure of the point-set 
+   * which is the union of the points in this <code>Geometry</code> which are not 
+   * contained in the <code>other</code> Geometry,
+   * with the points in the <code>other</code> Geometry not contained in this
+   * <code>Geometry</code>. 
+   * If the result is empty, it is an atomic geometry
+   * with the dimension of the highest input dimension.
+   * <p>
+   * Non-empty {@link GeometryCollection} arguments are not supported.
    *
-   *@param  other  the <code>Geometry</code> with which to compute the symmetric
+   *@param  other the <code>Geometry</code> with which to compute the symmetric
    *      difference
-   *@return        the point set symmetric difference of this <code>Geometry</code>
+   *@return a Geometry representing the point-set symmetric difference of this <code>Geometry</code>
    *      with <code>other</code>
    * @throws TopologyException if a robustness error occurs
    * @throws IllegalArgumentException if either input is a non-empty GeometryCollection
    */
   public Geometry symDifference(Geometry other)
   {
-    // special case: if either input is empty ==> other input
-    if (this.isEmpty()) return (Geometry) other.clone();
-    if (other.isEmpty()) return (Geometry) clone();
+    // handle empty geometry cases
+    if (this.isEmpty() || other.isEmpty()) {
+      // both empty - check dimensions
+      if (this.isEmpty() && other.isEmpty())
+        return OverlayOp.createEmptyResult(OverlayOp.SYMDIFFERENCE, this, other, factory);
+        
+    // special case: if either input is empty ==> result = other arg
+      if (this.isEmpty()) return (Geometry) other.clone();
+      if (other.isEmpty()) return (Geometry) clone();
+    }
 
     checkNotGeometryCollection(this);
     checkNotGeometryCollection(other);
@@ -1414,7 +1462,7 @@ public abstract class Geometry
 	/**
 	 * Computes the union of all the elements of this geometry. 
 	 * <p>
-	 * <tt>union()</tt> supports
+	 * <code>union()</code> supports
 	 * {@link GeometryCollection}s 
 	 * (which the other overlay operations currently do not).
 	 * <p>
@@ -1428,6 +1476,7 @@ public abstract class Geometry
 	 * </ul>
 	 * 
 	 * @return the union geometry
+   * @throws TopologyException if a robustness error occurs
 	 * 
 	 * @see UnaryUnionOp
 	 */
@@ -1446,8 +1495,8 @@ public abstract class Geometry
    * within the given tolerance distance, in exactly the same order.
    * </ul>
    * This method does <i>not</i>
-   * test the values of the <tt>GeometryFactory</tt>, the <tt>SRID</tt>, 
-   * or the <tt>userData</tt> fields.
+   * test the values of the <code>GeometryFactory</code>, the <code>SRID</code>, 
+   * or the <code>userData</code> fields.
    * <p>
    * To properly test equality between different geometries,
    * it is usually necessary to {@link #normalize()} them first.
@@ -1478,8 +1527,8 @@ public abstract class Geometry
    * (such as using geometries as keys in collections).
    * <p>
    * This method does <i>not</i>
-   * test the values of the <tt>GeometryFactory</tt>, the <tt>SRID</tt>, 
-   * or the <tt>userData</tt> fields.
+   * test the values of the <code>GeometryFactory</code>, the <code>SRID</code>, 
+   * or the <code>userData</code> fields.
    * <p>
    * To properly test equality between different geometries,
    * it is usually necessary to {@link #normalize()} them first.
@@ -1500,10 +1549,11 @@ public abstract class Geometry
    * This is a convenience method which creates normalized
    * versions of both geometries before computing
    * {@link #equalsExact(Geometry)}.
+   * <p>
    * This method is relatively expensive to compute.  
    * For maximum performance, the client 
-   * should instead perform normalization itself
-   * at an appropriate point during execution.
+   * should instead perform normalization on the individual geometries
+   * at an appropriate point during processing.
    * 
    * @param g a Geometry
    * @return true if the input geometries are exactly equal in their normalized form
@@ -1733,9 +1783,15 @@ public abstract class Geometry
     }
   }
 
-  protected boolean isGeometryCollection(Geometry g)
+  /**
+   * Tests whether this is an instance of a general {@link GeometryCollection},
+   * rather than a homogeneous subclass.
+   * 
+   * @return true if this is a hetereogeneous GeometryCollection
+   */
+  protected boolean isGeometryCollection()
   {
-    return g.getClass().equals(com.vividsolutions.jts.geom.GeometryCollection.class);
+    return getClass().equals(com.vividsolutions.jts.geom.GeometryCollection.class);
   }
 
   /**
diff --git a/src/com/vividsolutions/jts/geom/GeometryFactory.java b/src/com/vividsolutions/jts/geom/GeometryFactory.java
index 551481d..1771008 100644
--- a/src/com/vividsolutions/jts/geom/GeometryFactory.java
+++ b/src/com/vividsolutions/jts/geom/GeometryFactory.java
@@ -366,11 +366,12 @@ public class GeometryFactory
   }
 
   /**
-   * Creates a MultiPoint using the given CoordinateSequence.
-   * A a null or empty CoordinateSequence will create an empty MultiPoint.
+   * Creates a {@link MultiPoint} using the 
+   * points in the given {@link CoordinateSequence}.
+   * A <code>null</code> or empty CoordinateSequence creates an empty MultiPoint.
    *
    * @param coordinates a CoordinateSequence (possibly empty), or <code>null</code>
-   * @return a MultiPoint object
+   * @return a MultiPoint geometry
    */
   public MultiPoint createMultiPoint(CoordinateSequence coordinates) {
     if (coordinates == null) {
@@ -378,7 +379,10 @@ public class GeometryFactory
     }
     Point[] points = new Point[coordinates.size()];
     for (int i = 0; i < coordinates.size(); i++) {
-      points[i] = createPoint(coordinates.getCoordinate(i));
+      CoordinateSequence ptSeq = getCoordinateSequenceFactory()
+        .create(1, coordinates.getDimension());
+      CoordinateSequences.copy(coordinates, i, ptSeq, 0, 1);
+      points[i] = createPoint(ptSeq);
     }
     return createMultiPoint(points);
   }
@@ -402,6 +406,45 @@ public class GeometryFactory
   }
 
   /**
+   * Constructs a <code>Polygon</code> with the given exterior boundary.
+   *
+   * @param shell
+   *            the outer boundary of the new <code>Polygon</code>, or
+   *            <code>null</code> or an empty <code>LinearRing</code> if
+   *            the empty geometry is to be created.
+   * @throws IllegalArgumentException if the boundary ring is invalid
+   */
+  public Polygon createPolygon(CoordinateSequence coordinates) {
+    return createPolygon(createLinearRing(coordinates));
+  }
+
+  /**
+   * Constructs a <code>Polygon</code> with the given exterior boundary.
+   *
+   * @param shell
+   *            the outer boundary of the new <code>Polygon</code>, or
+   *            <code>null</code> or an empty <code>LinearRing</code> if
+   *            the empty geometry is to be created.
+   * @throws IllegalArgumentException if the boundary ring is invalid
+   */
+  public Polygon createPolygon(Coordinate[] coordinates) {
+    return createPolygon(createLinearRing(coordinates));
+  }
+
+  /**
+   * Constructs a <code>Polygon</code> with the given exterior boundary.
+   *
+   * @param shell
+   *            the outer boundary of the new <code>Polygon</code>, or
+   *            <code>null</code> or an empty <code>LinearRing</code> if
+   *            the empty geometry is to be created.
+   * @throws IllegalArgumentException if the boundary ring is invalid
+   */
+  public Polygon createPolygon(LinearRing shell) {
+    return createPolygon(shell, null);
+  }
+
+  /**
    *  Build an appropriate <code>Geometry</code>, <code>MultiGeometry</code>, or
    *  <code>GeometryCollection</code> to contain the <code>Geometry</code>s in
    *  it.
@@ -497,12 +540,34 @@ public class GeometryFactory
   }
 
   /**
-   * @return a clone of g based on a CoordinateSequence created by this
-   * GeometryFactory's CoordinateSequenceFactory
+   * Creates a deep copy of the input {@link Geometry}.
+   * The {@link CoordinateSequenceFactory} defined for this factory
+   * is used to copy the {@link CoordinateSequence}s
+   * of the input geometry.
+   * <p>
+   * This is a convenient way to change the <tt>CoordinateSequence</tt>
+   * used to represent a geometry, or to change the 
+   * factory used for a geometry.
+   * <p>
+   * {@link Geometry#clone()} can also be used to make a deep copy,
+   * but it does not allow changing the CoordinateSequence type.
+   * 
+   * @return a deep copy of the input geometry, using the CoordinateSequence type of this factory
+   * 
+   * @see Geometry#clone() 
    */
   public Geometry createGeometry(Geometry g)
   {
-    // could this be cached to make this more efficient? Or maybe it isn't enough overhead to bother
+    GeometryEditor editor = new GeometryEditor(this);
+    return editor.edit(g, new GeometryEditor.CoordinateSequenceOperation() {
+      public CoordinateSequence edit(CoordinateSequence coordSeq, Geometry geometry) {
+                  return coordinateSequenceFactory.create(coordSeq);
+          }
+    });
+  }
+  /*
+  public Geometry OLDcreateGeometry(Geometry g)
+  {
     GeometryEditor editor = new GeometryEditor(this);
     return editor.edit(g, new GeometryEditor.CoordinateOperation() {
       public Coordinate[] edit(Coordinate[] coordinates, Geometry geometry) {
@@ -510,7 +575,7 @@ public class GeometryFactory
           }
     });
   }
-
+*/
 
   public int getSRID() {
     return SRID;
diff --git a/src/com/vividsolutions/jts/geom/IntersectionMatrix.java b/src/com/vividsolutions/jts/geom/IntersectionMatrix.java
index 20a1e40..be3860d 100644
--- a/src/com/vividsolutions/jts/geom/IntersectionMatrix.java
+++ b/src/com/vividsolutions/jts/geom/IntersectionMatrix.java
@@ -35,11 +35,11 @@
 package com.vividsolutions.jts.geom;
 
 /**
- * Models a Dimensionally Extended Nine-Intersection Model (DE-9IM) matrix. 
- * This class is used to represent intersection matrices (such as "212FF1FF2")
- * capturing the topological relationship between two {@link Geometry}s. 
- * It can also be represent patterns (such as "T*T******")for matching 
- * existing matrices.
+ * Models a <b>Dimensionally Extended Nine-Intersection Model (DE-9IM)</b> matrix. 
+ * DE-9IM matrices (such as "212FF1FF2")
+ * specify the topological relationship between two {@link Geometry}s. 
+ * This class can also represent matrix patterns (such as "T*T******")
+ * which are used for matching instances of DE-9IM matrices.
  *
  *  Methods are provided to:
  *  <UL>
@@ -50,10 +50,15 @@ package com.vividsolutions.jts.geom;
  *  </UL>
  *  <P>
  *
- *  For a description of the DE-9IM, see the <A
- *  HREF="http://www.opengis.org/techno/specs.htm">OpenGIS Simple Features
- *  Specification for SQL</A>.
- *  
+ *  For a description of the DE-9IM and the spatial predicates derived from it, 
+ *  see the <i><A
+ *  HREF="http://www.opengis.org/techno/specs.htm">OGC 99-049 OpenGIS Simple Features
+ *  Specification for SQL</A></i>, as well as
+ *  <i>OGC 06-103r4 OpenGIS 
+ *  Implementation Standard for Geographic information - 
+ *  Simple feature access - Part 1: Common architecture</i>
+ *  (which provides some further details on certain predicate specifications).
+ * <p>
  * The entries of the matrix are defined by the constants in the {@link Dimension} class.
  * The indices of the matrix represent the topological locations 
  * that occur in a geometry (Interior, Boundary, Exterior).  
@@ -124,42 +129,57 @@ public class IntersectionMatrix implements Cloneable {
   }
 
   /**
-   *  Returns true if the dimension value satisfies the dimension symbol.
+   *  Tests if the dimension value matches <tt>TRUE</tt>
+   *  (i.e.  has value 0, 1, 2 or TRUE).
+   *
+   *@param  actualDimensionValue     a number that can be stored in the <code>IntersectionMatrix</code>
+   *      . Possible values are <code>{TRUE, FALSE, DONTCARE, 0, 1, 2}</code>.
+   *@return true if the dimension value matches TRUE
+   */
+  public static boolean isTrue(int actualDimensionValue) {
+    if (actualDimensionValue >= 0 || actualDimensionValue  == Dimension.TRUE) {
+      return true;
+    }
+    return false;
+  }
+  
+  /**
+   *  Tests if the dimension value satisfies the dimension symbol.
    *
    *@param  actualDimensionValue     a number that can be stored in the <code>IntersectionMatrix</code>
    *      . Possible values are <code>{TRUE, FALSE, DONTCARE, 0, 1, 2}</code>.
    *@param  requiredDimensionSymbol  a character used in the string
    *      representation of an <code>IntersectionMatrix</code>. Possible values
    *      are <code>{T, F, * , 0, 1, 2}</code>.
-   *@return                          true if the dimension symbol encompasses
+   *@return                          true if the dimension symbol matches
    *      the dimension value
    */
   public static boolean matches(int actualDimensionValue, char requiredDimensionSymbol) {
-    if (requiredDimensionSymbol == '*') {
+    if (requiredDimensionSymbol == Dimension.SYM_DONTCARE) {
       return true;
     }
-    if (requiredDimensionSymbol == 'T' && (actualDimensionValue >= 0 || actualDimensionValue
+    if (requiredDimensionSymbol == Dimension.SYM_TRUE && (actualDimensionValue >= 0 || actualDimensionValue
          == Dimension.TRUE)) {
       return true;
     }
-    if (requiredDimensionSymbol == 'F' && actualDimensionValue == Dimension.FALSE) {
+    if (requiredDimensionSymbol == Dimension.SYM_FALSE && actualDimensionValue == Dimension.FALSE) {
       return true;
     }
-    if (requiredDimensionSymbol == '0' && actualDimensionValue == Dimension.P) {
+    if (requiredDimensionSymbol == Dimension.SYM_P && actualDimensionValue == Dimension.P) {
       return true;
     }
-    if (requiredDimensionSymbol == '1' && actualDimensionValue == Dimension.L) {
+    if (requiredDimensionSymbol == Dimension.SYM_L && actualDimensionValue == Dimension.L) {
       return true;
     }
-    if (requiredDimensionSymbol == '2' && actualDimensionValue == Dimension.A) {
+    if (requiredDimensionSymbol == Dimension.SYM_A && actualDimensionValue == Dimension.A) {
       return true;
     }
     return false;
   }
 
   /**
-   *  Returns true if each of the actual dimension symbols satisfies the
-   *  corresponding required dimension symbol.
+   *  Tests if each of the actual dimension symbols in a matrix string satisfies the
+   *  corresponding required dimension symbol in a pattern string.
    *
    *@param  actualDimensionSymbols    nine dimension symbols to validate.
    *      Possible values are <code>{T, F, * , 0, 1, 2}</code>.
@@ -336,9 +356,9 @@ public class IntersectionMatrix implements Cloneable {
         (dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.A) ||
         (dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.L)) {
       return matrix[Location.INTERIOR][Location.INTERIOR] == Dimension.FALSE &&
-          (matches(matrix[Location.INTERIOR][Location.BOUNDARY], 'T')
-           || matches(matrix[Location.BOUNDARY][Location.INTERIOR], 'T')
-           || matches(matrix[Location.BOUNDARY][Location.BOUNDARY], 'T'));
+          (isTrue(matrix[Location.INTERIOR][Location.BOUNDARY])
+           || isTrue(matrix[Location.BOUNDARY][Location.INTERIOR])
+           || isTrue(matrix[Location.BOUNDARY][Location.BOUNDARY]));
     }
     return false;
   }
@@ -372,14 +392,14 @@ public class IntersectionMatrix implements Cloneable {
     if ((dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.L) ||
         (dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.A) ||
         (dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.A)) {
-      return matches(matrix[Location.INTERIOR][Location.INTERIOR], 'T') &&
-          matches(matrix[Location.INTERIOR][Location.EXTERIOR], 'T');
+      return isTrue(matrix[Location.INTERIOR][Location.INTERIOR]) &&
+      isTrue(matrix[Location.INTERIOR][Location.EXTERIOR]);
     }
     if ((dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.P) ||
         (dimensionOfGeometryA == Dimension.A && dimensionOfGeometryB == Dimension.P) ||
         (dimensionOfGeometryA == Dimension.A && dimensionOfGeometryB == Dimension.L)) {
-      return matches(matrix[Location.INTERIOR][Location.INTERIOR], 'T') &&
-          matches(matrix[Location.EXTERIOR][Location.INTERIOR], 'T');
+      return isTrue(matrix[Location.INTERIOR][Location.INTERIOR]) &&
+      isTrue(matrix[Location.EXTERIOR][Location.INTERIOR]);
     }
     if (dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.L) {
       return matrix[Location.INTERIOR][Location.INTERIOR] == 0;
@@ -395,7 +415,7 @@ public class IntersectionMatrix implements Cloneable {
    *      the second
    */
   public boolean isWithin() {
-    return matches(matrix[Location.INTERIOR][Location.INTERIOR], 'T') &&
+    return isTrue(matrix[Location.INTERIOR][Location.INTERIOR]) &&
         matrix[Location.INTERIOR][Location.EXTERIOR] == Dimension.FALSE &&
         matrix[Location.BOUNDARY][Location.EXTERIOR] == Dimension.FALSE;
   }
@@ -408,7 +428,7 @@ public class IntersectionMatrix implements Cloneable {
    *      second
    */
   public boolean isContains() {
-    return matches(matrix[Location.INTERIOR][Location.INTERIOR], 'T') &&
+    return isTrue(matrix[Location.INTERIOR][Location.INTERIOR]) &&
         matrix[Location.EXTERIOR][Location.INTERIOR] == Dimension.FALSE &&
         matrix[Location.EXTERIOR][Location.BOUNDARY] == Dimension.FALSE;
   }
@@ -425,10 +445,10 @@ public class IntersectionMatrix implements Cloneable {
    */
   public boolean isCovers() {
     boolean hasPointInCommon =
-        matches(matrix[Location.INTERIOR][Location.INTERIOR], 'T')
-        || matches(matrix[Location.INTERIOR][Location.BOUNDARY], 'T')
-        || matches(matrix[Location.BOUNDARY][Location.INTERIOR], 'T')
-        || matches(matrix[Location.BOUNDARY][Location.BOUNDARY], 'T');
+        isTrue(matrix[Location.INTERIOR][Location.INTERIOR])
+        || isTrue(matrix[Location.INTERIOR][Location.BOUNDARY])
+        || isTrue(matrix[Location.BOUNDARY][Location.INTERIOR])
+        || isTrue(matrix[Location.BOUNDARY][Location.BOUNDARY]);
 
     return hasPointInCommon &&
         matrix[Location.EXTERIOR][Location.INTERIOR] == Dimension.FALSE &&
@@ -447,10 +467,10 @@ public class IntersectionMatrix implements Cloneable {
    */
   public boolean isCoveredBy() {
     boolean hasPointInCommon =
-        matches(matrix[Location.INTERIOR][Location.INTERIOR], 'T')
-        || matches(matrix[Location.INTERIOR][Location.BOUNDARY], 'T')
-        || matches(matrix[Location.BOUNDARY][Location.INTERIOR], 'T')
-        || matches(matrix[Location.BOUNDARY][Location.BOUNDARY], 'T');
+        isTrue(matrix[Location.INTERIOR][Location.INTERIOR])
+        || isTrue(matrix[Location.INTERIOR][Location.BOUNDARY])
+        || isTrue(matrix[Location.BOUNDARY][Location.INTERIOR])
+        || isTrue(matrix[Location.BOUNDARY][Location.BOUNDARY]);
 
     return hasPointInCommon &&
         matrix[Location.INTERIOR][Location.EXTERIOR] == Dimension.FALSE &&
@@ -458,25 +478,32 @@ public class IntersectionMatrix implements Cloneable {
   }
 
   /**
-   *  Returns <code>true</code> if this <code>IntersectionMatrix</code> is
-   *  T*F**FFF*.
+   *  Tests whether the argument dimensions are equal and 
+   *  this <code>IntersectionMatrix</code> matches
+   *  the pattern <tt>T*F**FFF*</tt>.
+   *  <p>
+   *  <b>Note:</b> This pattern differs from the one stated in 
+   *  <i>Simple feature access - Part 1: Common architecture</i>.
+   *  That document states the pattern as <tt>TFFFTFFFT</tt>.  This would
+   *  specify that
+   *  two identical <tt>POINT</tt>s are not equal, which is not desirable behaviour.
+   *  The pattern used here has been corrected to compute equality in this situation.
    *
    *@param  dimensionOfGeometryA  the dimension of the first <code>Geometry</code>
    *@param  dimensionOfGeometryB  the dimension of the second <code>Geometry</code>
-   *@return                       <code>true</code> if the two <code>Geometry</code>
-   *      s related by this <code>IntersectionMatrix</code> are equal; the
-   *      <code>Geometry</code>s must have the same dimension for this function
-   *      to return <code>true</code>
+   *@return                       <code>true</code> if the two <code>Geometry</code>s
+   *      related by this <code>IntersectionMatrix</code> are equal; the
+   *      <code>Geometry</code>s must have the same dimension to be equal
    */
   public boolean isEquals(int dimensionOfGeometryA, int dimensionOfGeometryB) {
     if (dimensionOfGeometryA != dimensionOfGeometryB) {
       return false;
     }
-    return matches(matrix[Location.INTERIOR][Location.INTERIOR], 'T') &&
-        matrix[Location.EXTERIOR][Location.INTERIOR] == Dimension.FALSE &&
+    return isTrue(matrix[Location.INTERIOR][Location.INTERIOR]) &&
         matrix[Location.INTERIOR][Location.EXTERIOR] == Dimension.FALSE &&
-        matrix[Location.EXTERIOR][Location.BOUNDARY] == Dimension.FALSE &&
-        matrix[Location.BOUNDARY][Location.EXTERIOR] == Dimension.FALSE;
+        matrix[Location.BOUNDARY][Location.EXTERIOR] == Dimension.FALSE &&
+        matrix[Location.EXTERIOR][Location.INTERIOR] == Dimension.FALSE &&
+        matrix[Location.EXTERIOR][Location.BOUNDARY] == Dimension.FALSE;
   }
 
   /**
@@ -496,14 +523,14 @@ public class IntersectionMatrix implements Cloneable {
   public boolean isOverlaps(int dimensionOfGeometryA, int dimensionOfGeometryB) {
     if ((dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.P) ||
         (dimensionOfGeometryA == Dimension.A && dimensionOfGeometryB == Dimension.A)) {
-      return matches(matrix[Location.INTERIOR][Location.INTERIOR], 'T') &&
-          matches(matrix[Location.INTERIOR][Location.EXTERIOR], 'T') && matches(matrix[Location.EXTERIOR][Location.INTERIOR],
-          'T');
+      return isTrue(matrix[Location.INTERIOR][Location.INTERIOR]) 
+          && isTrue(matrix[Location.INTERIOR][Location.EXTERIOR]) 
+          && isTrue(matrix[Location.EXTERIOR][Location.INTERIOR]);
     }
     if (dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.L) {
-      return matrix[Location.INTERIOR][Location.INTERIOR] == 1 &&
-          matches(matrix[Location.INTERIOR][Location.EXTERIOR], 'T') &&
-          matches(matrix[Location.EXTERIOR][Location.INTERIOR], 'T');
+      return matrix[Location.INTERIOR][Location.INTERIOR] == 1 
+         && isTrue(matrix[Location.INTERIOR][Location.EXTERIOR]) 
+         && isTrue(matrix[Location.EXTERIOR][Location.INTERIOR]);
     }
     return false;
   }
diff --git a/src/com/vividsolutions/jts/geom/LineSegment.java b/src/com/vividsolutions/jts/geom/LineSegment.java
index 30656d7..8174902 100644
--- a/src/com/vividsolutions/jts/geom/LineSegment.java
+++ b/src/com/vividsolutions/jts/geom/LineSegment.java
@@ -323,7 +323,8 @@ public class LineSegment
    * equal the vector for the projection of <tt>p<//t> on the line
    * defined by this segment.
    * <p>
-   * The projection factor returned will be in the range <tt>(-inf, +inf)</tt>.
+   * The projection factor will lie in the range <tt>(-inf, +inf)</tt>,
+   * or be <code>NaN</code> if the line segment has zero length..
    * 
    * @param p the point to compute the factor for
    * @return the projection factor for the point
@@ -345,9 +346,13 @@ public class LineSegment
         */
     double dx = p1.x - p0.x;
     double dy = p1.y - p0.y;
-    double len2 = dx * dx + dy * dy;
+    double len = dx * dx + dy * dy;
+    
+    // handle zero-length segments
+    if (len <= 0.0) return Double.NaN;
+    
     double r = ( (p.x - p0.x) * dx + (p.y - p0.y) * dy )
-              / len2;
+              / len;
     return r;
   }
 
@@ -359,6 +364,7 @@ public class LineSegment
    * <p>
    * Essentially, this is the {@link #projectionFactor} clamped to 
    * the range <tt>[0.0, 1.0]</tt>.
+   * If the segment has zero length, 1.0 is returned.
    *  
    * @param inputPt the point
    * @return the fraction along the line segment the projection of the point occurs
@@ -369,7 +375,7 @@ public class LineSegment
     double segFrac = projectionFactor(inputPt);
     if (segFrac < 0.0)
       segFrac = 0.0;
-    else if (segFrac > 1.0)
+    else if (segFrac > 1.0 || Double.isNaN(segFrac))
       segFrac = 1.0;
     return segFrac;
   }
diff --git a/src/com/vividsolutions/jts/geom/Lineal.java b/src/com/vividsolutions/jts/geom/Lineal.java
index 5461ed3..c655b42 100644
--- a/src/com/vividsolutions/jts/geom/Lineal.java
+++ b/src/com/vividsolutions/jts/geom/Lineal.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.geom;
 
 /**
diff --git a/src/com/vividsolutions/jts/geom/LinearRing.java b/src/com/vividsolutions/jts/geom/LinearRing.java
index d6fdae9..312e8c4 100644
--- a/src/com/vividsolutions/jts/geom/LinearRing.java
+++ b/src/com/vividsolutions/jts/geom/LinearRing.java
@@ -36,7 +36,7 @@ package com.vividsolutions.jts.geom;
 
 /**
  * Models an OGC SFS <code>LinearRing</code>.
- * A LinearRing is a LineString which is both closed and simple.
+ * A <code>LinearRing</code> is a {@link LineString} which is both closed and simple.
  * In other words,
  * the first and last coordinate in the ring must be equal,
  * and the interior of the ring must not self-intersect.
@@ -127,15 +127,11 @@ public class LinearRing extends LineString
   }
 
   /**
-   * Returns <code>true</code>, since by definition LinearRings are always simple.
-   * @return <code>true</code>
-   *
-   * @see Geometry#isSimple
+   * Tests whether this ring is closed.
+   * Empty rings are closed by definition.
+   * 
+   * @return true if this ring is closed
    */
-  public boolean isSimple() {
-    return true;
-  }
-
   public boolean isClosed() {
     if (isEmpty()) {
     	// empty LinearRings are closed by definition
diff --git a/src/com/vividsolutions/jts/geom/MultiPolygon.java b/src/com/vividsolutions/jts/geom/MultiPolygon.java
index ef97b59..f9166df 100644
--- a/src/com/vividsolutions/jts/geom/MultiPolygon.java
+++ b/src/com/vividsolutions/jts/geom/MultiPolygon.java
@@ -99,10 +99,12 @@ public class MultiPolygon
     return "MultiPolygon";
   }
 
+  /*
   public boolean isSimple() {
     return true;
   }
-
+*/
+  
   /**
    * Computes the boundary of this geometry
    *
diff --git a/src/com/vividsolutions/jts/geom/Point.java b/src/com/vividsolutions/jts/geom/Point.java
index 9eb95a3..f721e6c 100644
--- a/src/com/vividsolutions/jts/geom/Point.java
+++ b/src/com/vividsolutions/jts/geom/Point.java
@@ -38,11 +38,12 @@ import com.vividsolutions.jts.util.Assert;
 import com.vividsolutions.jts.operation.valid.*;
 
 /**
- *  Implementation of <code>Point</code>.
+ * Represents a single point.
  *
- * A Point is valid iff:
+ * A <code>Point</code> is topologically valid if and only if:
  * <ul>
- * <li>the coordinate which defines it is a valid coordinate (i.e does not have an NaN X or Y ordinate)
+ * <li>the coordinate which defines it (if any) is a valid coordinate 
+ * (i.e does not have an <code>NaN</code> X or Y ordinate)
  * </ul>
  * 
  *@version 1.7
@@ -168,6 +169,9 @@ public class Point
     if (isEmpty() && other.isEmpty()) {
       return true;
     }
+    if (isEmpty() != other.isEmpty()) {
+      return false;
+    }
     return equal(((Point) other).getCoordinate(), this.getCoordinate(), tolerance);
   }
 
diff --git a/src/com/vividsolutions/jts/geom/Polygon.java b/src/com/vividsolutions/jts/geom/Polygon.java
index cb17193..4b23a88 100644
--- a/src/com/vividsolutions/jts/geom/Polygon.java
+++ b/src/com/vividsolutions/jts/geom/Polygon.java
@@ -39,15 +39,28 @@ import java.util.Arrays;
 import com.vividsolutions.jts.algorithm.*;
 
 /**
- * Represents a linear polygon, which may include holes.
- * The shell and holes of the polygon are represented by {@link LinearRing}s.
- * In a valid polygon, holes may touch the shell or other holes at a single point.
- * However, no sequence of touching holes may split the polygon into two pieces.
- * The orientation of the rings in the polygon does not matter.
+ * Represents a polygon with linear edges, which may include holes.
+ * The outer boundary (shell) 
+ * and inner boundaries (holes) of the polygon are represented by {@link LinearRing}s.
+ * The boundary rings of the polygon may have any orientation.
+ * Polygons are closed, simple geometries by definition.
  * <p>
- *  The shell and holes must conform to the assertions specified in the <A
- *  HREF="http://www.opengis.org/techno/specs.htm">OpenGIS Simple Features
- *  Specification for SQL</A> .
+ * The polygon model conforms to the assertions specified in the 
+ * <A HREF="http://www.opengis.org/techno/specs.htm">OpenGIS Simple Features
+ * Specification for SQL</A>.
+ * <p>
+ * A <code>Polygon</code> is topologically valid if and only if:
+ * <ul>
+ * <li>the coordinates which define it are valid coordinates
+ * <li>the linear rings for the shell and holes are valid
+ * (i.e. are closed and do not self-intersect)
+ * <li>holes touch the shell or another hole at at most one point
+ * (which implies that the rings of the shell and holes must not cross)
+ * <li>the interior of the polygon is connected,  
+ * or equivalently no sequence of touching holes 
+ * makes the interior of the polygon disconnected
+ * (i.e. effectively split the polygon into two pieces).
+ * </ul>
  *
  *@version 1.7
  */
@@ -187,10 +200,12 @@ public class Polygon
    *
    * @return <code>true</code>
    */
+  /*
   public boolean isSimple() {
     return true;
   }
-
+*/
+  
   public boolean isRectangle()
   {
     if (getNumInteriorRing() != 0) return false;
@@ -308,9 +323,6 @@ public class Polygon
     if (holes.length != otherPolygon.holes.length) {
       return false;
     }
-    if (holes.length != otherPolygon.holes.length) {
-      return false;
-    }
     for (int i = 0; i < holes.length; i++) {
       if (!((Geometry) holes[i]).equalsExact(otherPolygon.holes[i], tolerance)) {
         return false;
diff --git a/src/com/vividsolutions/jts/geom/Polygonal.java b/src/com/vividsolutions/jts/geom/Polygonal.java
index 372ec5c..28f3021 100644
--- a/src/com/vividsolutions/jts/geom/Polygonal.java
+++ b/src/com/vividsolutions/jts/geom/Polygonal.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.geom;
 
 /**
diff --git a/src/com/vividsolutions/jts/geom/PrecisionModel.java b/src/com/vividsolutions/jts/geom/PrecisionModel.java
index 9a95806..0bd3266 100644
--- a/src/com/vividsolutions/jts/geom/PrecisionModel.java
+++ b/src/com/vividsolutions/jts/geom/PrecisionModel.java
@@ -76,12 +76,13 @@ import java.util.Map;
  * of 1000. To specify -3 decimal places of precision (i.e. rounding to
  * the nearest 1000), use a scale factor of 0.001.
  * <p>
- *  Coordinates are represented internally as Java double-precision values.
+ * Coordinates are represented internally as Java double-precision values.
  * Since Java uses the IEEE-394 floating point standard, this
- *  provides 53 bits of precision. (Thus the maximum precisely representable
- *  integer is 9,007,199,254,740,992).
- *<p>
- *  JTS methods currently do not handle inputs with different precision models.
+ * provides 53 bits of precision. (Thus the maximum precisely representable
+ * <i>integer</i> is 9,007,199,254,740,992 - or almost 16 decimal digits of precision).
+ * <p>
+ * JTS binary methods currently do not handle inputs which have different precision models.
+ * The precision model of any constructed geometric value is undefined.
  *
  *@version 1.7
  */
diff --git a/src/com/vividsolutions/jts/geom/Puntal.java b/src/com/vividsolutions/jts/geom/Puntal.java
index 6f5318d..518889f 100644
--- a/src/com/vividsolutions/jts/geom/Puntal.java
+++ b/src/com/vividsolutions/jts/geom/Puntal.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.geom;
 
 /**
diff --git a/src/com/vividsolutions/jts/geom/Triangle.java b/src/com/vividsolutions/jts/geom/Triangle.java
index 9c325f5..6c537c4 100644
--- a/src/com/vividsolutions/jts/geom/Triangle.java
+++ b/src/com/vividsolutions/jts/geom/Triangle.java
@@ -1,4 +1,3 @@
-
 /*
  * The JTS Topology Suite is a collection of Java classes that
  * implement the fundamental operations required to validate a given
@@ -38,111 +37,114 @@ import com.vividsolutions.jts.algorithm.*;
 /**
  * Represents a planar triangle, and provides methods for calculating various
  * properties of triangles.
- *
+ * 
  * @version 1.7
  */
 public class Triangle
 {
 
-
   /**
-   * Tests whether a triangle is acute.
-   * A triangle is acute iff all interior angles are acute.
-   * This is a strict test - right triangles will return <tt>false</tt>
-   * A triangle which is not acute is either right or obtuse.
+   * Tests whether a triangle is acute. A triangle is acute iff all interior
+   * angles are acute. This is a strict test - right triangles will return
+   * <tt>false</tt> A triangle which is not acute is either right or obtuse.
    * <p>
-   * Note: this implementation is not robust for angles very close to 90 degrees.
+   * Note: this implementation is not robust for angles very close to 90
+   * degrees.
    * 
-   * @param a a vertex of the triangle
-   * @param b a vertex of the triangle
-   * @param c a vertex of the triangle
+   * @param a
+   *          a vertex of the triangle
+   * @param b
+   *          a vertex of the triangle
+   * @param c
+   *          a vertex of the triangle
    * @return true if the triangle is acute
    */
   public static boolean isAcute(Coordinate a, Coordinate b, Coordinate c)
   {
-    if (! Angle.isAcute(a, b, c)) return false;
-    if (! Angle.isAcute(b, c, a)) return false;
-    if (! Angle.isAcute(c, a, b)) return false;
+    if (!Angle.isAcute(a, b, c))
+      return false;
+    if (!Angle.isAcute(b, c, a))
+      return false;
+    if (!Angle.isAcute(c, a, b))
+      return false;
     return true;
   }
 
   /**
-   * Computes the line which is the perpendicular bisector of the
-   * line segment a-b.
-   *
-   * @param a a point
-   * @param b another point
+   * Computes the line which is the perpendicular bisector of the line segment
+   * a-b.
+   * 
+   * @param a
+   *          a point
+   * @param b
+   *          another point
    * @return the perpendicular bisector, as an HCoordinate
    */
-  public static HCoordinate perpendicularBisector(Coordinate a, Coordinate b) {
+  public static HCoordinate perpendicularBisector(Coordinate a, Coordinate b)
+  {
     // returns the perpendicular bisector of the line segment ab
     double dx = b.x - a.x;
     double dy = b.y - a.y;
     HCoordinate l1 = new HCoordinate(a.x + dx / 2.0, a.y + dy / 2.0, 1.0);
-    HCoordinate l2 = new HCoordinate(a.x - dy + dx / 2.0, a.y + dx + dy / 2.0, 1.0);
-    return new HCoordinate(l1,l2);
+    HCoordinate l2 = new HCoordinate(a.x - dy + dx / 2.0, a.y + dx + dy / 2.0,
+        1.0);
+    return new HCoordinate(l1, l2);
   }
 
   /**
-   * Computes the circumcentre of a triangle.
-   * The circumcentre is the centre of the circumcircle,
-   * the smallest circle which encloses the triangle.
-   * It is also the common intersection point of the
-   * perpendicular bisectors of the sides of the triangle,
-   * and is the only point which has equal distance to all three
-   * vertices of the triangle.
-   *
-   * @param a a vertx of the triangle
-   * @param b a vertx of the triangle
-   * @param c a vertx of the triangle
+   * Computes the circumcentre of a triangle. The circumcentre is the centre of
+   * the circumcircle, the smallest circle which encloses the triangle. It is
+   * also the common intersection point of the perpendicular bisectors of the
+   * sides of the triangle, and is the only point which has equal distance to
+   * all three vertices of the triangle.
+   * 
+   * @param a
+   *          a vertx of the triangle
+   * @param b
+   *          a vertx of the triangle
+   * @param c
+   *          a vertx of the triangle
    * @return the circumcentre of the triangle
    */
   /*
-   // original non-robust algorithm
-  public static Coordinate circumcentre(Coordinate a, Coordinate b, Coordinate c)
-  {
-    // compute the perpendicular bisector of chord ab
-    HCoordinate cab = perpendicularBisector(a, b);
-    // compute the perpendicular bisector of chord bc
-    HCoordinate cbc = perpendicularBisector(b, c);
-    // compute the intersection of the bisectors (circle radii)
-    HCoordinate hcc = new HCoordinate(cab, cbc);
-    Coordinate cc = null;
-    try {
-      cc = new Coordinate(hcc.getX(), hcc.getY());
-    }
-    catch (NotRepresentableException ex) {
-      // MD - not sure what we can do to prevent this (robustness problem)
-      // Idea - can we condition which edges we choose?
-      throw new IllegalStateException(ex.getMessage());
-    }
-    
-    //System.out.println("Acc = " + a.distance(cc) + ", Bcc = " + b.distance(cc) + ", Ccc = " + c.distance(cc) );
-
-    return cc;
-  }
-  */
-  
+   * // original non-robust algorithm public static Coordinate
+   * circumcentre(Coordinate a, Coordinate b, Coordinate c) { // compute the
+   * perpendicular bisector of chord ab HCoordinate cab =
+   * perpendicularBisector(a, b); // compute the perpendicular bisector of chord
+   * bc HCoordinate cbc = perpendicularBisector(b, c); // compute the
+   * intersection of the bisectors (circle radii) HCoordinate hcc = new
+   * HCoordinate(cab, cbc); Coordinate cc = null; try { cc = new
+   * Coordinate(hcc.getX(), hcc.getY()); } catch (NotRepresentableException ex)
+   * { // MD - not sure what we can do to prevent this (robustness problem) //
+   * Idea - can we condition which edges we choose? throw new
+   * IllegalStateException(ex.getMessage()); }
+   * 
+   * //System.out.println("Acc = " + a.distance(cc) + ", Bcc = " +
+   * b.distance(cc) + ", Ccc = " + c.distance(cc) );
+   * 
+   * return cc; }
+   */
+
   /**
-   * Computes the circumcentre of a triangle.
-   * The circumcentre is the centre of the circumcircle,
-   * the smallest circle which encloses the triangle.
-   * It is also the common intersection point of the
-   * perpendicular bisectors of the sides of the triangle,
-   * and is the only point which has equal distance to all three
-   * vertices of the triangle.
+   * Computes the circumcentre of a triangle. The circumcentre is the centre of
+   * the circumcircle, the smallest circle which encloses the triangle. It is
+   * also the common intersection point of the perpendicular bisectors of the
+   * sides of the triangle, and is the only point which has equal distance to
+   * all three vertices of the triangle.
    * <p>
-   * The circumcentre does not necessarily lie within the triangle.
+   * The circumcentre does not necessarily lie within the triangle. For example,
+   * the circumcentre of an obtuse isoceles triangle lies outside the triangle.
    * <p>
-   * This method uses an algorithm due to J.R.Shewchuk which
-   * uses normalization to the origin
-   * to improve the accuracy of computation.
-   * (See <i>Lecture Notes on Geometric Robustness</i>, 
-   * Jonathan Richard Shewchuk, 1999).
-   *
-   * @param a a vertx of the triangle
-   * @param b a vertx of the triangle
-   * @param c a vertx of the triangle
+   * This method uses an algorithm due to J.R.Shewchuk which uses normalization
+   * to the origin to improve the accuracy of computation. (See <i>Lecture Notes
+   * on Geometric Robustness</i>, Jonathan Richard Shewchuk, 1999).
+   * 
+   * @param a
+   *          a vertx of the triangle
+   * @param b
+   *          a vertx of the triangle
+   * @param c
+   *          a vertx of the triangle
    * @return the circumcentre of the triangle
    */
   public static Coordinate circumcentre(Coordinate a, Coordinate b, Coordinate c)
@@ -153,47 +155,51 @@ public class Triangle
     double ay = a.y - cy;
     double bx = b.x - cx;
     double by = b.y - cy;
-    
+
     double denom = 2 * det(ax, ay, bx, by);
-    double numx = det(ay, ax*ax + ay*ay, by, bx*bx + by*by);
-    double numy = det(ax, ax*ax + ay*ay, bx, bx*bx + by*by);
-    
+    double numx = det(ay, ax * ax + ay * ay, by, bx * bx + by * by);
+    double numy = det(ax, ax * ax + ay * ay, bx, bx * bx + by * by);
+
     double ccx = cx - numx / denom;
     double ccy = cy + numy / denom;
-    
+
     return new Coordinate(ccx, ccy);
   }
-  
+
   /**
-   * Computes the determinant of a 2x2 matrix.
-   * Uses standard double-precision arithmetic, 
-   * so is susceptible to round-off error.
+   * Computes the determinant of a 2x2 matrix. Uses standard double-precision
+   * arithmetic, so is susceptible to round-off error.
    * 
-   * @param m00 the [0,0] entry of the matrix
-   * @param m01 the [0,1] entry of the matrix
-   * @param m10 the [1,0] entry of the matrix
-   * @param m11 the [1,1] entry of the matrix
+   * @param m00
+   *          the [0,0] entry of the matrix
+   * @param m01
+   *          the [0,1] entry of the matrix
+   * @param m10
+   *          the [1,0] entry of the matrix
+   * @param m11
+   *          the [1,1] entry of the matrix
    * @return the determinant
    */
   private static double det(double m00, double m01, double m10, double m11)
   {
     return m00 * m11 - m01 * m10;
   }
-  
+
   /**
-   * Computes the incentre of a triangle.
-   * The <i>inCentre</i> of a triangle is the point which is equidistant
-   * from the sides of the triangle.
-   * It is also the point at which the bisectors
-   * of the triangle's angles meet.
-   * It is the centre of the triangle's <i>incircle</i>,
-   * which is the unique circle that is tangent to each of the triangle's three sides.
+   * Computes the incentre of a triangle. The <i>inCentre</i> of a triangle is
+   * the point which is equidistant from the sides of the triangle. It is also
+   * the point at which the bisectors of the triangle's angles meet. It is the
+   * centre of the triangle's <i>incircle</i>, which is the unique circle that
+   * is tangent to each of the triangle's three sides.
    * <p>
    * The incentre always lies within the triangle.
-    *
-   * @param a a vertx of the triangle
-   * @param b a vertx of the triangle
-   * @param c a vertx of the triangle
+   * 
+   * @param a
+   *          a vertx of the triangle
+   * @param b
+   *          a vertx of the triangle
+   * @param c
+   *          a vertx of the triangle
    * @return the point which is the incentre of the triangle
    */
   public static Coordinate inCentre(Coordinate a, Coordinate b, Coordinate c)
@@ -204,24 +210,26 @@ public class Triangle
     double len2 = a.distance(b);
     double circum = len0 + len1 + len2;
 
-    double inCentreX = (len0 * a.x + len1 * b.x +len2 * c.x)  / circum;
-    double inCentreY = (len0 * a.y + len1 * b.y +len2 * c.y)  / circum;
+    double inCentreX = (len0 * a.x + len1 * b.x + len2 * c.x) / circum;
+    double inCentreY = (len0 * a.y + len1 * b.y + len2 * c.y) / circum;
     return new Coordinate(inCentreX, inCentreY);
   }
 
   /**
-   * Computes the centroid (centre of mass) of a triangle.
-   * This is also the point at which the triangle's three
-   * medians intersect (a triangle median is the segment from a vertex of the triangle to the
-   * midpoint of the opposite side).
-   * The centroid divides each median in a ratio of 2:1.
+   * Computes the centroid (centre of mass) of a triangle. This is also the
+   * point at which the triangle's three medians intersect (a triangle median is
+   * the segment from a vertex of the triangle to the midpoint of the opposite
+   * side). The centroid divides each median in a ratio of 2:1.
    * <p>
    * The centroid always lies within the triangle.
-   *
-   *
-   * @param a a vertex of the triangle
-   * @param b a vertex of the triangle
-   * @param c a vertex of the triangle
+   * 
+   * 
+   * @param a
+   *          a vertex of the triangle
+   * @param b
+   *          a vertex of the triangle
+   * @param c
+   *          a vertex of the triangle
    * @return the centroid of the triangle
    */
   public static Coordinate centroid(Coordinate a, Coordinate b, Coordinate c)
@@ -233,13 +241,17 @@ public class Triangle
 
   /**
    * Computes the length of the longest side of a triangle
-   *
-   * @param a a vertex of the triangle
-   * @param b a vertex of the triangle
-   * @param c a vertex of the triangle
+   * 
+   * @param a
+   *          a vertex of the triangle
+   * @param b
+   *          a vertex of the triangle
+   * @param c
+   *          a vertex of the triangle
    * @return the length of the longest side of the triangle
    */
-  public static double longestSideLength(Coordinate a, Coordinate b, Coordinate c)
+  public static double longestSideLength(Coordinate a, Coordinate b,
+      Coordinate c)
   {
     double lenAB = a.distance(b);
     double lenBC = b.distance(c);
@@ -253,19 +265,23 @@ public class Triangle
   }
 
   /**
-   * Computes the point at which the bisector of the angle ABC
-   * cuts the segment AC.
-   *
-   * @param a a vertex of the triangle
-   * @param b a vertex of the triangle
-   * @param c a vertex of the triangle
+   * Computes the point at which the bisector of the angle ABC cuts the segment
+   * AC.
+   * 
+   * @param a
+   *          a vertex of the triangle
+   * @param b
+   *          a vertex of the triangle
+   * @param c
+   *          a vertex of the triangle
    * @return the angle bisector cut point
    */
-  public static Coordinate angleBisector(Coordinate a, Coordinate b, Coordinate c)
+  public static Coordinate angleBisector(Coordinate a, Coordinate b,
+      Coordinate c)
   {
     /**
-     * Uses the fact that the lengths of the parts of the split segment
-     * are proportional to the lengths of the adjacent triangle sides
+     * Uses the fact that the lengths of the parts of the split segment are
+     * proportional to the lengths of the adjacent triangle sides
      */
     double len0 = b.distance(a);
     double len2 = b.distance(c);
@@ -273,106 +289,148 @@ public class Triangle
     double dx = c.x - a.x;
     double dy = c.y - a.y;
 
-    Coordinate splitPt = new Coordinate(a.x + frac * dx,
-                                        a.y + frac * dy);
+    Coordinate splitPt = new Coordinate(a.x + frac * dx, a.y + frac * dy);
     return splitPt;
   }
 
   /**
-   * Computes the 2D area of a triangle.
-   * The area value is always non-negative.
-   *
-   * @param a a vertex of the triangle
-   * @param b a vertex of the triangle
-   * @param c a vertex of the triangle
+   * Computes the 2D area of a triangle. The area value is always non-negative.
+   * 
+   * @param a
+   *          a vertex of the triangle
+   * @param b
+   *          a vertex of the triangle
+   * @param c
+   *          a vertex of the triangle
    * @return the area of the triangle
    * 
    * @see #signedArea(Coordinate, Coordinate, Coordinate)
    */
   public static double area(Coordinate a, Coordinate b, Coordinate c)
   {
-    return Math.abs(((c.x - a.x) * (b.y - a.y) - (b.x - a.x) * (c.y - a.y)) / 2);
+    return Math
+        .abs(((c.x - a.x) * (b.y - a.y) - (b.x - a.x) * (c.y - a.y)) / 2);
   }
 
   /**
-   * Computes the signed 2D area of a triangle.
-   * The area value is positive if the triangle is oriented CW,
-   * and negative if it is oriented CCW.
+   * Computes the signed 2D area of a triangle. The area value is positive if
+   * the triangle is oriented CW, and negative if it is oriented CCW.
    * <p>
-   * The signed area value can be used to determine point orientation, but 
-   * the implementation in this method
-   * is susceptible to round-off errors.  
-   * Use {@link CGAlgorithms#orientationIndex(Coordinate, Coordinate, Coordinate)} for robust orientation
-   * calculation.
-   *
-   * @param a a vertex of the triangle
-   * @param b a vertex of the triangle
-   * @param c a vertex of the triangle
+   * The signed area value can be used to determine point orientation, but the
+   * implementation in this method is susceptible to round-off errors. Use
+   * {@link CGAlgorithms#orientationIndex(Coordinate, Coordinate, Coordinate)}
+   * for robust orientation calculation.
+   * 
+   * @param a
+   *          a vertex of the triangle
+   * @param b
+   *          a vertex of the triangle
+   * @param c
+   *          a vertex of the triangle
    * @return the signed 2D area of the triangle
    * 
    * @see CGAlgorithms#orientationIndex(Coordinate, Coordinate, Coordinate)
    */
   public static double signedArea(Coordinate a, Coordinate b, Coordinate c)
   {
-		/**
-		 * Uses the formula 1/2 * | u x v |
-		 * where
-		 * 	u,v are the side vectors of the triangle
-		 *  x is the vector cross-product
-		 * For 2D vectors, this formual simplifies to the expression below
-		 */
+    /**
+     * Uses the formula 1/2 * | u x v | where u,v are the side vectors of the
+     * triangle x is the vector cross-product For 2D vectors, this formual
+     * simplifies to the expression below
+     */
     return ((c.x - a.x) * (b.y - a.y) - (b.x - a.x) * (c.y - a.y)) / 2;
   }
 
-	/**
-	 * Computes the 3D area of a triangle.
-	 * The value computed is alway non-negative.
-	 * 
-   * @param a a vertex of the triangle
-   * @param b a vertex of the triangle
-   * @param c a vertex of the triangle
+  /**
+   * Computes the 3D area of a triangle. The value computed is alway
+   * non-negative.
+   * 
+   * @param a
+   *          a vertex of the triangle
+   * @param b
+   *          a vertex of the triangle
+   * @param c
+   *          a vertex of the triangle
    * @return the 3D area of the triangle
-	 */
-	public static double area3D(Coordinate a, Coordinate b, Coordinate c)
-	{
-		/**
-		 * Uses the formula 1/2 * | u x v |
-		 * where
-		 * 	u,v are the side vectors of the triangle
-		 *  x is the vector cross-product
-		 */
-		// side vectors u and v
-		double ux = b.x - a.x;
-		double uy = b.y - a.y;
-		double uz = b.z - a.z;
-		
-		double vx = c.x - a.x;
-		double vy = c.y - a.y;
-		double vz = c.z - a.z;
-		
-		// cross-product = u x v 
-		double crossx = uy * vz - uz * vy;
-		double crossy = uz * vx - ux * vz;
-		double crossz = ux * vy - uy * vx;
-		
-		// tri area = 1/2 * | u x v |
-		double absSq = crossx * crossx + crossy * crossy + crossz * crossz;
-		double area3D = Math.sqrt(absSq) / 2;
-		
-		return area3D;
-	}
-	
-	/**
-	 * The coordinates of the vertices of the triangle
-	 */
+   */
+  public static double area3D(Coordinate a, Coordinate b, Coordinate c)
+  {
+    /**
+     * Uses the formula 1/2 * | u x v | where u,v are the side vectors of the
+     * triangle x is the vector cross-product
+     */
+    // side vectors u and v
+    double ux = b.x - a.x;
+    double uy = b.y - a.y;
+    double uz = b.z - a.z;
+
+    double vx = c.x - a.x;
+    double vy = c.y - a.y;
+    double vz = c.z - a.z;
+
+    // cross-product = u x v
+    double crossx = uy * vz - uz * vy;
+    double crossy = uz * vx - ux * vz;
+    double crossz = ux * vy - uy * vx;
+
+    // tri area = 1/2 * | u x v |
+    double absSq = crossx * crossx + crossy * crossy + crossz * crossz;
+    double area3D = Math.sqrt(absSq) / 2;
+
+    return area3D;
+  }
+
+  /**
+   * Computes the Z-value (elevation) of an XY point on a three-dimensional
+   * plane defined by a triangle whose vertices have Z-values. The defining
+   * triangle must not be degenerate (in other words, the triangle must enclose
+   * a non-zero area), and must not be parallel to the Z-axis.
+   * <p>
+   * This method can be used to interpolate the Z-value of a point inside a
+   * triangle (for example, of a TIN facet with elevations on the vertices).
+   * 
+   * @param p
+   *          the point to compute the Z-value of
+   * @param v0
+   *          a vertex of a triangle, with a Z ordinate
+   * @param v1
+   *          a vertex of a triangle, with a Z ordinate
+   * @param v2
+   *          a vertex of a triangle, with a Z ordinate
+   * @return the computed Z-value (elevation) of the point
+   */
+  public static double interpolateZ(Coordinate p, Coordinate v0, Coordinate v1,
+      Coordinate v2)
+  {
+    double x0 = v0.x;
+    double y0 = v0.y;
+    double a = v1.x - x0;
+    double b = v2.x - x0;
+    double c = v1.y - y0;
+    double d = v2.y - y0;
+    double det = a * d - b * c;
+    double dx = p.x - x0;
+    double dy = p.y - y0;
+    double t = (d * dx - b * dy) / det;
+    double u = (-c * dx + a * dy) / det;
+    double z = v0.z + t * (v1.z - v0.z) + u * (v2.z - v0.z);
+    return z;
+  }
+
+  /**
+   * The coordinates of the vertices of the triangle
+   */
   public Coordinate p0, p1, p2;
 
   /**
    * Creates a new triangle with the given vertices.
    * 
-   * @param p0 a vertex
-   * @param p1 a vertex
-   * @param p2 a vertex
+   * @param p0
+   *          a vertex
+   * @param p1
+   *          a vertex
+   * @param p2
+   *          a vertex
    */
   public Triangle(Coordinate p0, Coordinate p1, Coordinate p2)
   {
@@ -382,21 +440,139 @@ public class Triangle
   }
 
   /**
-   * Computes the incentre of a triangle.
-   * The <i>incentre</i> of a triangle is the point which is equidistant
-   * from the sides of the triangle.
-   * It is also the point at which the bisectors
-   * of the triangle's angles meet.
-   * It is the centre of the triangle's <i>incircle</i>,
-   * which is the unique circle that is tangent to each of the triangle's three sides.
-   *
-   * @return the point which is the inCentre of the triangle
+   * Computes the incentre of this triangle. The <i>incentre</i> of a triangle
+   * is the point which is equidistant from the sides of the triangle. It is
+   * also the point at which the bisectors of the triangle's angles meet. It is
+   * the centre of the triangle's <i>incircle</i>, which is the unique circle
+   * that is tangent to each of the triangle's three sides.
+   * 
+   * @return the point which is the inCentre of this triangle
    */
   public Coordinate inCentre()
   {
     return inCentre(p0, p1, p2);
   }
 
+  /**
+   * Tests whether this triangle is acute. A triangle is acute iff all interior
+   * angles are acute. This is a strict test - right triangles will return
+   * <tt>false</tt> A triangle which is not acute is either right or obtuse.
+   * <p>
+   * Note: this implementation is not robust for angles very close to 90
+   * degrees.
+   * 
+   * @return true if this triangle is acute
+   */
+  public boolean isAcute()
+  {
+    return isAcute(this.p0, this.p1, this.p2);
+  }
+
+  /**
+   * Computes the circumcentre of this triangle. The circumcentre is the centre
+   * of the circumcircle, the smallest circle which encloses the triangle. It is
+   * also the common intersection point of the perpendicular bisectors of the
+   * sides of the triangle, and is the only point which has equal distance to
+   * all three vertices of the triangle.
+   * <p>
+   * The circumcentre does not necessarily lie within the triangle.
+   * <p>
+   * This method uses an algorithm due to J.R.Shewchuk which uses normalization
+   * to the origin to improve the accuracy of computation. (See <i>Lecture Notes
+   * on Geometric Robustness</i>, Jonathan Richard Shewchuk, 1999).
+   * 
+   * @return the circumcentre of this triangle
+   */
+  public Coordinate circumcentre()
+  {
+    return circumcentre(this.p0, this.p1, this.p2);
+  }
 
-}
+  /**
+   * Computes the centroid (centre of mass) of this triangle. This is also the
+   * point at which the triangle's three medians intersect (a triangle median is
+   * the segment from a vertex of the triangle to the midpoint of the opposite
+   * side). The centroid divides each median in a ratio of 2:1.
+   * <p>
+   * The centroid always lies within the triangle.
+   * 
+   * @return the centroid of this triangle
+   */
+  public Coordinate centroid()
+  {
+    return centroid(this.p0, this.p1, this.p2);
+  }
+
+  /**
+   * Computes the length of the longest side of this triangle
+   * 
+   * @return the length of the longest side of this triangle
+   */
+  public double longestSideLength()
+  {
+    return longestSideLength(this.p0, this.p1, this.p2);
+  }
 
+  /**
+   * Computes the 2D area of this triangle. The area value is always
+   * non-negative.
+   * 
+   * @return the area of this triangle
+   * 
+   * @see #signedArea()
+   */
+  public double area()
+  {
+    return area(this.p0, this.p1, this.p2);
+  }
+
+  /**
+   * Computes the signed 2D area of this triangle. The area value is positive if
+   * the triangle is oriented CW, and negative if it is oriented CCW.
+   * <p>
+   * The signed area value can be used to determine point orientation, but the
+   * implementation in this method is susceptible to round-off errors. Use
+   * {@link CGAlgorithms#orientationIndex(Coordinate, Coordinate, Coordinate)}
+   * for robust orientation calculation.
+   * 
+   * @return the signed 2D area of this triangle
+   * 
+   * @see CGAlgorithms#orientationIndex(Coordinate, Coordinate, Coordinate)
+   */
+  public double signedArea()
+  {
+    return signedArea(this.p0, this.p1, this.p2);
+  }
+
+  /**
+   * Computes the 3D area of this triangle. The value computed is alway
+   * non-negative.
+   * 
+   * @return the 3D area of this triangle
+   */
+  public double area3D()
+  {
+    return area3D(this.p0, this.p1, this.p2);
+  }
+
+  /**
+   * Computes the Z-value (elevation) of an XY point on a three-dimensional
+   * plane defined by this triangle (whose vertices must have Z-values). This
+   * triangle must not be degenerate (in other words, the triangle must enclose
+   * a non-zero area), and must not be parallel to the Z-axis.
+   * <p>
+   * This method can be used to interpolate the Z-value of a point inside this
+   * triangle (for example, of a TIN facet with elevations on the vertices).
+   * 
+   * @param p
+   *          the point to compute the Z-value of
+   * @return the computed Z-value (elevation) of the point
+   */
+  public double interpolateZ(Coordinate p)
+  {
+    if (p == null)
+      throw new IllegalArgumentException("Supplied point is null.");
+    return interpolateZ(p, this.p0, this.p1, this.p2);
+  }
+
+}
diff --git a/src/com/vividsolutions/jts/geom/impl/CoordinateArraySequence.java b/src/com/vividsolutions/jts/geom/impl/CoordinateArraySequence.java
index 8ed9f8f..b38f665 100644
--- a/src/com/vividsolutions/jts/geom/impl/CoordinateArraySequence.java
+++ b/src/com/vividsolutions/jts/geom/impl/CoordinateArraySequence.java
@@ -36,10 +36,15 @@ import java.io.Serializable;
 import com.vividsolutions.jts.geom.*;
 
 /**
- * The {@link CoordinateSequence} implementation that {@link Geometry}s use by default.
- * In this implementation, Coordinates returned by #toArray and #getCoordinate are live --
+ * A {@link CoordinateSequence} backed by an array of {@link Coordinates}.
+ * This is the implementation that {@link Geometry}s use by default.
+ * Coordinates returned by #toArray and #getCoordinate are live --
  * modifications to them are actually changing the
  * CoordinateSequence's underlying data.
+ * A dimension may be specified for the coordinates in the sequence,
+ * which may be 2 or 3.
+ * The actual coordinates will always have 3 ordinates,
+ * but the dimension is useful as metadata in some situations. 
  *
  * @version 1.7
  */
@@ -49,16 +54,37 @@ public class CoordinateArraySequence
   //With contributions from Markus Schaber [schabios at logi-track.com] 2004-03-26
   private static final long serialVersionUID = -915438501601840650L;
 
+  /**
+   * The actual dimension of the coordinates in the sequence.
+   * Allowable values are 2 or 3.
+   */
+  private int dimension = 3;
+  
   private Coordinate[] coordinates;
 
   /**
-   * Constructs a sequence based on the given array (the
+   * Constructs a sequence based on the given array
+   * of {@link Coordinate}s (the
    * array is not copied).
+   * The coordinate dimension defaults to 3.
    *
    * @param coordinates the coordinate array that will be referenced.
    */
   public CoordinateArraySequence(Coordinate[] coordinates) {
+    this(coordinates, 3);
+  }
+
+  /**
+   * Constructs a sequence based on the given array 
+   * of {@link Coordinate}s (the
+   * array is not copied).
+   *
+   * @param coordinates the coordinate array that will be referenced.
+   * @param the dimension of the coordinates
+   */
+  public CoordinateArraySequence(Coordinate[] coordinates, int dimension) {
     this.coordinates = coordinates;
+    this.dimension = dimension;
     if (coordinates == null)
       this.coordinates = new Coordinate[0];
   }
@@ -77,15 +103,32 @@ public class CoordinateArraySequence
   }
 
   /**
-   * Constructs a sequence based on the given array (the
-   * array is not copied).
+   * Constructs a sequence of a given size, populated
+   * with new {@link Coordinate}s.
    *
-   * @param coordinates the coordinate array that will be referenced.
+   * @param size the size of the sequence to create
+   * @param the dimension of the coordinates
+   */
+  public CoordinateArraySequence(int size, int dimension) {
+    coordinates = new Coordinate[size];
+    this.dimension = dimension;
+    for (int i = 0; i < size; i++) {
+      coordinates[i] = new Coordinate();
+    }
+  }
+
+  /**
+   * Creates a new sequence based on a deep copy of the given {@link CoordinateSequence}.
+   * The coordinate dimension is set to equal the dimension of the input.
+   *
+   * @param coordSeq the coordinate sequence that will be copied.
    */
   public CoordinateArraySequence(CoordinateSequence coordSeq)
   {
-    if (coordSeq != null)
+    if (coordSeq != null) {
+      dimension = coordSeq.getDimension();
       coordinates = new Coordinate[coordSeq.size()];
+    }
     else
       coordinates = new Coordinate[0];
 
@@ -97,7 +140,7 @@ public class CoordinateArraySequence
   /**
    * @see com.vividsolutions.jts.geom.CoordinateSequence#getDimension()
    */
-  public int getDimension() { return 3; }
+  public int getDimension() { return dimension; }
 
   /**
    * Get the Coordinate with index i.
diff --git a/src/com/vividsolutions/jts/geom/impl/CoordinateArraySequenceFactory.java b/src/com/vividsolutions/jts/geom/impl/CoordinateArraySequenceFactory.java
index e880793..d9bd729 100644
--- a/src/com/vividsolutions/jts/geom/impl/CoordinateArraySequenceFactory.java
+++ b/src/com/vividsolutions/jts/geom/impl/CoordinateArraySequenceFactory.java
@@ -88,6 +88,6 @@ public final class CoordinateArraySequenceFactory
   public CoordinateSequence create(int size, int dimension) {
     if (dimension > 3)
       throw new IllegalArgumentException("dimension must be <= 3");
-    return new CoordinateArraySequence(size);
+    return new CoordinateArraySequence(size, dimension);
   }
 }
\ No newline at end of file
diff --git a/src/com/vividsolutions/jts/geom/impl/PackedCoordinateSequence.java b/src/com/vividsolutions/jts/geom/impl/PackedCoordinateSequence.java
index 13445eb..5b38d90 100644
--- a/src/com/vividsolutions/jts/geom/impl/PackedCoordinateSequence.java
+++ b/src/com/vividsolutions/jts/geom/impl/PackedCoordinateSequence.java
@@ -295,6 +295,16 @@ public abstract class PackedCoordinateSequence
     }
 
     /**
+     * Gets the underlying array containing the coordinate values.
+     * 
+     * @return the array of coordinate values
+     */
+    public double[] getRawCoordinates()
+    {
+      return coords;
+    }
+    
+    /**
      * @see com.vividsolutions.jts.geom.CoordinateSequence#size()
      */
     public int size() {
@@ -421,6 +431,16 @@ public abstract class PackedCoordinateSequence
     }
 
     /**
+     * Gets the underlying array containing the coordinate values.
+     * 
+     * @return the array of coordinate values
+     */
+    public float[] getRawCoordinates()
+    {
+      return coords;
+    }
+    
+    /**
      * @see com.vividsolutions.jts.geom.CoordinateSequence#size()
      */
     public int size() {
diff --git a/src/com/vividsolutions/jts/geom/prep/PreparedGeometry.java b/src/com/vividsolutions/jts/geom/prep/PreparedGeometry.java
index 04ff1dd..e338661 100644
--- a/src/com/vividsolutions/jts/geom/prep/PreparedGeometry.java
+++ b/src/com/vividsolutions/jts/geom/prep/PreparedGeometry.java
@@ -46,6 +46,10 @@ import com.vividsolutions.jts.geom.*;
  * and delegate others. 
  * See the implementing classes for documentation about which methods and situations
  * they optimize.
+ * <p>
+ * Subclasses are intended to be thread-safe, to allow <code>PreparedGeometry</code>
+ * to be used in a multi-threaded context 
+ * (which allows extracting maximum benefit from the prepared state).
  * 
  * @author Martin Davis
  *
diff --git a/src/com/vividsolutions/jts/geom/prep/PreparedLineString.java b/src/com/vividsolutions/jts/geom/prep/PreparedLineString.java
index 4b6a78b..ca0d3e6 100644
--- a/src/com/vividsolutions/jts/geom/prep/PreparedLineString.java
+++ b/src/com/vividsolutions/jts/geom/prep/PreparedLineString.java
@@ -37,6 +37,8 @@ import com.vividsolutions.jts.noding.*;
 
 /**
  * A prepared version for {@link Lineal} geometries.
+ * <p>
+ * Instances of this class are thread-safe.
  * 
  * @author mbdavis
  *
@@ -50,7 +52,7 @@ public class PreparedLineString
     super((Geometry) line);
   }
 
-  public FastSegmentSetIntersectionFinder getIntersectionFinder()
+  public synchronized FastSegmentSetIntersectionFinder getIntersectionFinder()
   {
   	/**
   	 * MD - Another option would be to use a simple scan for 
diff --git a/src/com/vividsolutions/jts/geom/prep/PreparedLineStringIntersects.java b/src/com/vividsolutions/jts/geom/prep/PreparedLineStringIntersects.java
index 32a690f..d203d0f 100644
--- a/src/com/vividsolutions/jts/geom/prep/PreparedLineStringIntersects.java
+++ b/src/com/vividsolutions/jts/geom/prep/PreparedLineStringIntersects.java
@@ -88,12 +88,14 @@ class PreparedLineStringIntersects
 		 * If any segments intersect, obviously intersects = true
 		 */
     List lineSegStr = SegmentStringUtil.extractSegmentStrings(geom);
-		boolean segsIntersect = prepLine.getIntersectionFinder().intersects(lineSegStr);
-		// MD - performance testing
-//		boolean segsIntersect = false;
-		if (segsIntersect) 
-      return true;
-		
+    // only request intersection finder if there are segments (ie NOT for point inputs)
+    if (lineSegStr.size() > 0) {
+  		boolean segsIntersect = prepLine.getIntersectionFinder().intersects(lineSegStr);
+  		// MD - performance testing
+  //		boolean segsIntersect = false;
+  		if (segsIntersect) 
+        return true;
+    }
 		/**
 		 * For L/L case we are done
 		 */
diff --git a/src/com/vividsolutions/jts/geom/prep/PreparedPoint.java b/src/com/vividsolutions/jts/geom/prep/PreparedPoint.java
index c42e1d4..3390a5e 100644
--- a/src/com/vividsolutions/jts/geom/prep/PreparedPoint.java
+++ b/src/com/vividsolutions/jts/geom/prep/PreparedPoint.java
@@ -37,6 +37,8 @@ import com.vividsolutions.jts.geom.*;
 
 /**
  * A prepared version for {@link Puntal} geometries.
+ * <p>
+ * Instances of this class are thread-safe.
  * 
  * @author Martin Davis
  *
diff --git a/src/com/vividsolutions/jts/geom/prep/PreparedPolygon.java b/src/com/vividsolutions/jts/geom/prep/PreparedPolygon.java
index d80e70c..fa43fd9 100644
--- a/src/com/vividsolutions/jts/geom/prep/PreparedPolygon.java
+++ b/src/com/vividsolutions/jts/geom/prep/PreparedPolygon.java
@@ -44,6 +44,8 @@ import com.vividsolutions.jts.operation.predicate.*;
  * <p>
  * This class does <b>not</b> support MultiPolygons which are non-valid 
  * (e.g. with overlapping elements). 
+ * <p>
+ * Instances of this class are thread-safe.
  * 
  * @author mbdavis
  *
@@ -61,7 +63,12 @@ public class PreparedPolygon
     isRectangle = getGeometry().isRectangle();
   }
 
-  public FastSegmentSetIntersectionFinder getIntersectionFinder()
+  /**
+   * Gets the indexed intersection finder for this geometry.
+   * 
+   * @return the intersection finder
+   */
+  public synchronized FastSegmentSetIntersectionFinder getIntersectionFinder()
   {
   	/**
   	 * MD - Another option would be to use a simple scan for 
@@ -74,7 +81,7 @@ public class PreparedPolygon
    return segIntFinder;
   }
   
-  public PointOnGeometryLocator getPointLocator()
+  public synchronized PointOnGeometryLocator getPointLocator()
   {
   	if (pia == null)
       pia = new IndexedPointInAreaLocator(getGeometry());
diff --git a/src/com/vividsolutions/jts/geom/prep/PreparedPolygonIntersects.java b/src/com/vividsolutions/jts/geom/prep/PreparedPolygonIntersects.java
index 4f7b2e4..520d572 100644
--- a/src/com/vividsolutions/jts/geom/prep/PreparedPolygonIntersects.java
+++ b/src/com/vividsolutions/jts/geom/prep/PreparedPolygonIntersects.java
@@ -96,9 +96,12 @@ class PreparedPolygonIntersects
 		 * If any segments intersect, result is true
 		 */
     List lineSegStr = SegmentStringUtil.extractSegmentStrings(geom);
-		boolean segsIntersect = prepPoly.getIntersectionFinder().intersects(lineSegStr);
-		if (segsIntersect) 
-      return true;
+    // only request intersection finder if there are segments (ie NOT for point inputs)
+    if (lineSegStr.size() > 0) {
+      boolean segsIntersect = prepPoly.getIntersectionFinder().intersects(lineSegStr);
+      if (segsIntersect) 
+        return true;
+    }
 		
 		/**
 		 * If the test has dimension = 2 as well, it is necessary to
diff --git a/src/com/vividsolutions/jts/geom/prep/PreparedPolygonPredicate.java b/src/com/vividsolutions/jts/geom/prep/PreparedPolygonPredicate.java
index 921eb21..f8ff310 100644
--- a/src/com/vividsolutions/jts/geom/prep/PreparedPolygonPredicate.java
+++ b/src/com/vividsolutions/jts/geom/prep/PreparedPolygonPredicate.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.geom.prep;
 
 import java.util.*;
diff --git a/src/com/vividsolutions/jts/geom/util/AffineTransformation.java b/src/com/vividsolutions/jts/geom/util/AffineTransformation.java
index a2e0f09..d76650b 100644
--- a/src/com/vividsolutions/jts/geom/util/AffineTransformation.java
+++ b/src/com/vividsolutions/jts/geom/util/AffineTransformation.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.geom.util;
 
 import com.vividsolutions.jts.geom.*;
diff --git a/src/com/vividsolutions/jts/geom/util/AffineTransformationBuilder.java b/src/com/vividsolutions/jts/geom/util/AffineTransformationBuilder.java
index a24d235..2ce84cb 100644
--- a/src/com/vividsolutions/jts/geom/util/AffineTransformationBuilder.java
+++ b/src/com/vividsolutions/jts/geom/util/AffineTransformationBuilder.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.geom.util;
 
 import com.vividsolutions.jts.geom.*;
diff --git a/src/com/vividsolutions/jts/geom/util/AffineTransformationFactory.java b/src/com/vividsolutions/jts/geom/util/AffineTransformationFactory.java
index 380344d..d57aa7b 100644
--- a/src/com/vividsolutions/jts/geom/util/AffineTransformationFactory.java
+++ b/src/com/vividsolutions/jts/geom/util/AffineTransformationFactory.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.geom.util;
 
 import com.vividsolutions.jts.algorithm.Angle;
diff --git a/src/com/vividsolutions/jts/geom/util/GeometryCollectionMapper.java b/src/com/vividsolutions/jts/geom/util/GeometryCollectionMapper.java
index cff0f26..078fa77 100644
--- a/src/com/vividsolutions/jts/geom/util/GeometryCollectionMapper.java
+++ b/src/com/vividsolutions/jts/geom/util/GeometryCollectionMapper.java
@@ -1,7 +1,41 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.geom.util;
 
 import java.util.*;
 import com.vividsolutions.jts.geom.*;
+import com.vividsolutions.jts.geom.util.GeometryMapper.MapOp;
 
 /**
  * Maps the members of a {@link GeometryCollection}
@@ -36,8 +70,4 @@ public class GeometryCollectionMapper
     return gc.getFactory().createGeometryCollection(
         GeometryFactory.toGeometryArray(mapped));
   }
-  
-  public interface MapOp {
-    Geometry map(Geometry g);
-  }
 }
diff --git a/src/com/vividsolutions/jts/geom/util/GeometryCombiner.java b/src/com/vividsolutions/jts/geom/util/GeometryCombiner.java
index b186656..96dc140 100644
--- a/src/com/vividsolutions/jts/geom/util/GeometryCombiner.java
+++ b/src/com/vividsolutions/jts/geom/util/GeometryCombiner.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.geom.util;
 
 import java.util.*;
diff --git a/src/com/vividsolutions/jts/geom/util/GeometryEditor.java b/src/com/vividsolutions/jts/geom/util/GeometryEditor.java
index cd1495c..cadda7c 100644
--- a/src/com/vividsolutions/jts/geom/util/GeometryEditor.java
+++ b/src/com/vividsolutions/jts/geom/util/GeometryEditor.java
@@ -40,8 +40,7 @@ import java.util.ArrayList;
 
 
 /**
- * A class which supports 
- * creating new {@link Geometry}s 
+ * A class which supports creating new {@link Geometry}s 
  * which are modifications of existing ones.
  * Geometry objects are intended to be treated as immutable.
  * This class "modifies" Geometrys
@@ -116,7 +115,7 @@ public class GeometryEditor
    *
    * @param geometry the Geometry to edit
    * @param operation the edit operation to carry out
-   * @return a new {@link Geometry} which is the result of the editing
+   * @return a new {@link Geometry} which is the result of the editing (which may be empty)
    */
   public Geometry edit(Geometry geometry, GeometryEditorOperation operation)
   {
@@ -151,30 +150,26 @@ public class GeometryEditor
   private Polygon editPolygon(Polygon polygon,
                               GeometryEditorOperation operation) {
     Polygon newPolygon = (Polygon) operation.edit(polygon, factory);
-
+    // create one if needed
+    if (newPolygon == null)
+      newPolygon = factory.createPolygon((CoordinateSequence) null);
     if (newPolygon.isEmpty()) {
       //RemoveSelectedPlugIn relies on this behaviour. [Jon Aquino]
       return newPolygon;
     }
 
-    LinearRing shell = (LinearRing) edit(newPolygon.getExteriorRing(),
-        operation);
-
-    if (shell.isEmpty()) {
+    LinearRing shell = (LinearRing) edit(newPolygon.getExteriorRing(), operation);
+    if (shell == null || shell.isEmpty()) {
       //RemoveSelectedPlugIn relies on this behaviour. [Jon Aquino]
       return factory.createPolygon(null, null);
     }
 
     ArrayList holes = new ArrayList();
-
     for (int i = 0; i < newPolygon.getNumInteriorRing(); i++) {
-      LinearRing hole = (LinearRing) edit(newPolygon.getInteriorRingN(i),
-      operation);
-
-      if (hole.isEmpty()) {
+      LinearRing hole = (LinearRing) edit(newPolygon.getInteriorRingN(i), operation);
+      if (hole == null || hole.isEmpty()) {
         continue;
       }
-
       holes.add(hole);
     }
 
@@ -184,35 +179,33 @@ public class GeometryEditor
 
   private GeometryCollection editGeometryCollection(
       GeometryCollection collection, GeometryEditorOperation operation) {
-    GeometryCollection newCollection = (GeometryCollection) operation.edit(collection,
+    // first edit the entire collection
+    // MD - not sure why this is done - could just check original collection?
+    GeometryCollection collectionForType = (GeometryCollection) operation.edit(collection,
         factory);
+    
+    // edit the component geometries
     ArrayList geometries = new ArrayList();
-
-    for (int i = 0; i < newCollection.getNumGeometries(); i++) {
-      Geometry geometry = edit(newCollection.getGeometryN(i), operation);
-
-      if (geometry.isEmpty()) {
+    for (int i = 0; i < collectionForType.getNumGeometries(); i++) {
+      Geometry geometry = edit(collectionForType.getGeometryN(i), operation);
+      if (geometry == null || geometry.isEmpty()) {
         continue;
       }
-
       geometries.add(geometry);
     }
 
-    if (newCollection.getClass() == MultiPoint.class) {
+    if (collectionForType.getClass() == MultiPoint.class) {
       return factory.createMultiPoint((Point[]) geometries.toArray(
             new Point[] {  }));
     }
-
-    if (newCollection.getClass() == MultiLineString.class) {
+    if (collectionForType.getClass() == MultiLineString.class) {
       return factory.createMultiLineString((LineString[]) geometries.toArray(
             new LineString[] {  }));
     }
-
-    if (newCollection.getClass() == MultiPolygon.class) {
+    if (collectionForType.getClass() == MultiPolygon.class) {
       return factory.createMultiPolygon((Polygon[]) geometries.toArray(
             new Polygon[] {  }));
     }
-
     return factory.createGeometryCollection((Geometry[]) geometries.toArray(
           new Geometry[] {  }));
   }
@@ -232,6 +225,7 @@ public class GeometryEditor
      * @param factory the factory with which to construct the modified Geometry
      * (may be different to the factory of the input geometry)
      * @return a new Geometry which is a modification of the input Geometry
+     * @return null if the Geometry is to be deleted completely
      */
     Geometry edit(Geometry geometry, GeometryFactory factory);
   }
@@ -253,8 +247,9 @@ public class GeometryEditor
   		return geometry;
   	}
   }
+  
   /**
-   * A {@link GeometryEditorOperation} which modifies the coordinate list of a {@link Geometry}.
+   * A {@link GeometryEditorOperation} which edits the coordinate list of a {@link Geometry}.
    * Operates on Geometry subclasses which contains a single coordinate list.
    */
   public abstract static class CoordinateOperation
@@ -296,4 +291,45 @@ public class GeometryEditor
     public abstract Coordinate[] edit(Coordinate[] coordinates,
                                       Geometry geometry);
   }
+  
+  /**
+   * A {@link GeometryEditorOperation} which edits the {@link CoordinateSequence}
+   * of a {@link Geometry}.
+   * Operates on Geometry subclasses which contains a single coordinate list.
+   */
+  public abstract static class CoordinateSequenceOperation
+      implements GeometryEditorOperation
+  {
+    public final Geometry edit(Geometry geometry, GeometryFactory factory) {
+      if (geometry instanceof LinearRing) {
+        return factory.createLinearRing(edit(
+            ((LinearRing)geometry).getCoordinateSequence(),
+            geometry));
+      }
+
+      if (geometry instanceof LineString) {
+        return factory.createLineString(edit(
+            ((LineString)geometry).getCoordinateSequence(),
+            geometry));
+      }
+
+      if (geometry instanceof Point) {
+        return factory.createPoint(edit(
+            ((Point)geometry).getCoordinateSequence(),
+            geometry));
+      }
+
+      return geometry;
+    }
+
+    /**
+     * Edits a {@link CoordinateSequence} from a {@link Geometry}.
+     *
+     * @param coordseq the coordinate array to operate on
+     * @param geometry the geometry containing the coordinate list
+     * @return an edited coordinate sequence (which may be the same as the input)
+     */
+    public abstract CoordinateSequence edit(CoordinateSequence coordSeq,
+                                      Geometry geometry);
+  }
 }
diff --git a/src/com/vividsolutions/jts/geom/util/GeometryMapper.java b/src/com/vividsolutions/jts/geom/util/GeometryMapper.java
index 59f41c7..260909f 100644
--- a/src/com/vividsolutions/jts/geom/util/GeometryMapper.java
+++ b/src/com/vividsolutions/jts/geom/util/GeometryMapper.java
@@ -71,8 +71,8 @@ public class GeometryMapper
   public static Collection map(Collection geoms, MapOp op)
   {
     List mapped = new ArrayList();
-    for (Object o : geoms) {
-      Geometry g = (Geometry) o;
+    for (Iterator i = geoms.iterator(); i.hasNext(); ) {
+      Geometry g = (Geometry) i.next();
       Geometry gr = op.map(g);
       if (gr != null)
         mapped.add(gr);
diff --git a/src/com/vividsolutions/jts/geom/util/GeometryTransformer.java b/src/com/vividsolutions/jts/geom/util/GeometryTransformer.java
index 45d4b6b..6549974 100644
--- a/src/com/vividsolutions/jts/geom/util/GeometryTransformer.java
+++ b/src/com/vividsolutions/jts/geom/util/GeometryTransformer.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.geom.util;
 
 import java.util.*;
@@ -269,4 +302,4 @@ public class GeometryTransformer
     return factory.buildGeometry(transGeomList);
   }
 
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/geom/util/LinearComponentExtracter.java b/src/com/vividsolutions/jts/geom/util/LinearComponentExtracter.java
index 35bdea6..8b7c192 100644
--- a/src/com/vividsolutions/jts/geom/util/LinearComponentExtracter.java
+++ b/src/com/vividsolutions/jts/geom/util/LinearComponentExtracter.java
@@ -39,6 +39,8 @@ import com.vividsolutions.jts.geom.*;
 
 /**
  * Extracts all the 1-dimensional ({@link LineString}) components from a {@link Geometry}.
+ * For polygonal geometries, this will extract all the component {@link LinearRing}s.
+ * If desired, <code>LinearRing</code>s can be forced to be returned as <code>LineString</code>s.
  *
  * @version 1.7
  */
diff --git a/src/com/vividsolutions/jts/geom/util/NoninvertibleTransformationException.java b/src/com/vividsolutions/jts/geom/util/NoninvertibleTransformationException.java
index 2a683ed..7efb031 100644
--- a/src/com/vividsolutions/jts/geom/util/NoninvertibleTransformationException.java
+++ b/src/com/vividsolutions/jts/geom/util/NoninvertibleTransformationException.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.geom.util;
 
 /**
diff --git a/src/com/vividsolutions/jts/geom/util/ShortCircuitedGeometryVisitor.java b/src/com/vividsolutions/jts/geom/util/ShortCircuitedGeometryVisitor.java
index 14f7ee5..0d4856e 100644
--- a/src/com/vividsolutions/jts/geom/util/ShortCircuitedGeometryVisitor.java
+++ b/src/com/vividsolutions/jts/geom/util/ShortCircuitedGeometryVisitor.java
@@ -1,10 +1,43 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.geom.util;
 
 import com.vividsolutions.jts.geom.*;
 
 /**
- * A visitor to {@link Geometry} elements which can
- * be short-circuited by a given condition
+ * A visitor to {@link Geometry} componets, which 
+ * allows short-circuiting when a defined condition holds.
  *
  * @version 1.7
  */
@@ -33,4 +66,4 @@ public abstract class ShortCircuitedGeometryVisitor
   protected abstract void visit(Geometry element);
 
   protected abstract boolean isDone();
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/geom/util/SineStarFactory.java b/src/com/vividsolutions/jts/geom/util/SineStarFactory.java
index 93c5acd..cd251a4 100644
--- a/src/com/vividsolutions/jts/geom/util/SineStarFactory.java
+++ b/src/com/vividsolutions/jts/geom/util/SineStarFactory.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.geom.util;
 
 import com.vividsolutions.jts.geom.*;
diff --git a/src/com/vividsolutions/jts/geomgraph/Edge.java b/src/com/vividsolutions/jts/geomgraph/Edge.java
index 86f9d00..5736519 100644
--- a/src/com/vividsolutions/jts/geomgraph/Edge.java
+++ b/src/com/vividsolutions/jts/geomgraph/Edge.java
@@ -257,6 +257,18 @@ public class Edge
     return true;
   }
 
+  public String toString()
+  {
+    StringBuffer buf = new StringBuffer();
+    buf.append("edge " + name + ": ");
+    buf.append("LINESTRING (");
+    for (int i = 0; i < pts.length; i++) {
+      if (i > 0) buf.append(",");
+      buf.append(pts[i].x + " " + pts[i].y);
+    }
+    buf.append(")  " + label + " " + depthDelta);
+    return buf.toString();
+  }
   public void print(PrintStream out)
   {
     out.print("edge " + name + ": ");
diff --git a/src/com/vividsolutions/jts/geomgraph/EdgeEnd.java b/src/com/vividsolutions/jts/geomgraph/EdgeEnd.java
index f3e4d70..4d30372 100644
--- a/src/com/vividsolutions/jts/geomgraph/EdgeEnd.java
+++ b/src/com/vividsolutions/jts/geomgraph/EdgeEnd.java
@@ -139,4 +139,12 @@ public class EdgeEnd
     String name = className.substring(lastDotPos + 1);
     out.print("  " + name + ": " + p0 + " - " + p1 + " " + quadrant + ":" + angle + "   " + label);
   }
+  public String toString()
+  {
+    double angle = Math.atan2(dy, dx);
+    String className = getClass().getName();
+    int lastDotPos = className.lastIndexOf('.');
+    String name = className.substring(lastDotPos + 1);
+    return "  " + name + ": " + p0 + " - " + p1 + " " + quadrant + ":" + angle + "   " + label;
+  }
 }
diff --git a/src/com/vividsolutions/jts/geomgraph/EdgeEndStar.java b/src/com/vividsolutions/jts/geomgraph/EdgeEndStar.java
index 620bdd1..73fee52 100644
--- a/src/com/vividsolutions/jts/geomgraph/EdgeEndStar.java
+++ b/src/com/vividsolutions/jts/geomgraph/EdgeEndStar.java
@@ -336,4 +336,17 @@ abstract public class EdgeEndStar
       e.print(out);
     }
   }
+  
+  public String toString()
+  {
+    StringBuffer buf = new StringBuffer();
+    buf.append("EdgeEndStar:   " + getCoordinate());
+    buf.append("\n");
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      EdgeEnd e = (EdgeEnd) it.next();
+      buf.append(e);
+      buf.append("\n");
+    }
+    return buf.toString();
+  }
 }
diff --git a/src/com/vividsolutions/jts/geomgraph/EdgeIntersection.java b/src/com/vividsolutions/jts/geomgraph/EdgeIntersection.java
index 288ebaf..d5fb7ee 100644
--- a/src/com/vividsolutions/jts/geomgraph/EdgeIntersection.java
+++ b/src/com/vividsolutions/jts/geomgraph/EdgeIntersection.java
@@ -100,4 +100,8 @@ public class EdgeIntersection
     out.print(" seg # = " + segmentIndex);
     out.println(" dist = " + dist);
   }
+  public String toString()
+  {
+    return coord + " seg # = " + segmentIndex + " dist = " + dist;
+  }
 }
diff --git a/src/com/vividsolutions/jts/geomgraph/GeometryGraph.java b/src/com/vividsolutions/jts/geomgraph/GeometryGraph.java
index dc69112..cb66e5c 100644
--- a/src/com/vividsolutions/jts/geomgraph/GeometryGraph.java
+++ b/src/com/vividsolutions/jts/geomgraph/GeometryGraph.java
@@ -396,12 +396,13 @@ Debug.print(e.getEdgeIntersectionList());
   private void insertBoundaryPoint(int argIndex, Coordinate coord)
   {
     Node n = nodes.addNode(coord);
+    // nodes always have labels
     Label lbl = n.getLabel();
     // the new point to insert is on a boundary
     int boundaryCount = 1;
     // determine the current location for the point (if any)
     int loc = Location.NONE;
-    if (lbl != null) loc = lbl.getLocation(argIndex, Position.ON);
+    loc = lbl.getLocation(argIndex, Position.ON);
     if (loc == Location.BOUNDARY) boundaryCount++;
 
     // determine the boundary status of the point according to the Boundary Determination Rule
diff --git a/src/com/vividsolutions/jts/geomgraph/Node.java b/src/com/vividsolutions/jts/geomgraph/Node.java
index 9586dbf..3aebf21 100644
--- a/src/com/vividsolutions/jts/geomgraph/Node.java
+++ b/src/com/vividsolutions/jts/geomgraph/Node.java
@@ -136,6 +136,8 @@ public class Node
    */
   public void setLabelBoundary(int argIndex)
   {
+    if (label == null) return;
+
     // determine the current location for the point (if any)
     int loc = Location.NONE;
     if (label != null)
diff --git a/src/com/vividsolutions/jts/index/ArrayListVisitor.java b/src/com/vividsolutions/jts/index/ArrayListVisitor.java
index 0124baf..29e2d38 100644
--- a/src/com/vividsolutions/jts/index/ArrayListVisitor.java
+++ b/src/com/vividsolutions/jts/index/ArrayListVisitor.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.index;
 
 import java.util.*;
@@ -21,4 +54,4 @@ public class ArrayListVisitor
 
   public ArrayList getItems() { return items; }
 
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/index/ItemVisitor.java b/src/com/vividsolutions/jts/index/ItemVisitor.java
index af81b0b..540224a 100644
--- a/src/com/vividsolutions/jts/index/ItemVisitor.java
+++ b/src/com/vividsolutions/jts/index/ItemVisitor.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.index;
 
 /**
@@ -9,4 +42,4 @@ package com.vividsolutions.jts.index;
 public interface ItemVisitor
 {
   void visitItem(Object item);
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/index/chain/MonotoneChain.java b/src/com/vividsolutions/jts/index/chain/MonotoneChain.java
index 5fce1cd..b9c24c0 100644
--- a/src/com/vividsolutions/jts/index/chain/MonotoneChain.java
+++ b/src/com/vividsolutions/jts/index/chain/MonotoneChain.java
@@ -112,6 +112,12 @@ public class MonotoneChain {
   public int getStartIndex()  { return start; }
   public int getEndIndex()    { return end; }
 
+  /**
+   * Gets the line segment starting at <code>index</code>
+   * 
+   * @param index index of segment
+   * @param ls line segment to extract into
+   */
   public void getLineSegment(int index, LineSegment ls)
   {
     ls.p0 = pts[index];
diff --git a/src/com/vividsolutions/jts/index/chain/MonotoneChainSelectAction.java b/src/com/vividsolutions/jts/index/chain/MonotoneChainSelectAction.java
index 315e959..5e6b712 100644
--- a/src/com/vividsolutions/jts/index/chain/MonotoneChainSelectAction.java
+++ b/src/com/vividsolutions/jts/index/chain/MonotoneChainSelectAction.java
@@ -49,16 +49,22 @@ public class MonotoneChainSelectAction
   LineSegment selectedSegment = new LineSegment();
 
   /**
-   * This function can be overridden if the original chain is needed.
+   * This method is overridden 
+   * to process a segment 
+   * in the context of the parent chain.
+   * 
+   * @param mc the parent chain
+   * @param startIndex the index of the start vertex of the segment being processed
    */
-  public void select(MonotoneChain mc, int start)
+  public void select(MonotoneChain mc, int startIndex)
   {
-    mc.getLineSegment(start, selectedSegment);
+    mc.getLineSegment(startIndex, selectedSegment);
+    // call this routine in case select(segmenet) was overridden
     select(selectedSegment);
   }
 
   /**
-   * This is a convenience function which can be overridden to obtain the actual
+   * This is a convenience method which can be overridden to obtain the actual
    * line segment which is selected.
    * 
    * @param seg
diff --git a/src/com/vividsolutions/jts/index/intervalrtree/SortedPackedIntervalRTree.java b/src/com/vividsolutions/jts/index/intervalrtree/SortedPackedIntervalRTree.java
index 6495261..ee73f95 100644
--- a/src/com/vividsolutions/jts/index/intervalrtree/SortedPackedIntervalRTree.java
+++ b/src/com/vividsolutions/jts/index/intervalrtree/SortedPackedIntervalRTree.java
@@ -82,11 +82,18 @@ public class SortedPackedIntervalRTree
   private void init()
   {
     if (root != null) return;
+    buildRoot();
+  }
+  
+  private synchronized void buildRoot() 
+  {
+    if (root != null) return;
     root = buildTree();
   }
   
-	private IntervalRTreeNode buildTree()
+	private  IntervalRTreeNode buildTree()
 	{
+	  
     // sort the leaf nodes
     Collections.sort(leaves, new IntervalRTreeNode.NodeComparator());
     
diff --git a/src/com/vividsolutions/jts/index/kdtree/KdTree.java b/src/com/vividsolutions/jts/index/kdtree/KdTree.java
index f2717fb..2d158e4 100644
--- a/src/com/vividsolutions/jts/index/kdtree/KdTree.java
+++ b/src/com/vividsolutions/jts/index/kdtree/KdTree.java
@@ -79,6 +79,17 @@ public class KdTree
 		this.tolerance = tolerance;
 	}
 
+  /**
+   * Tests whether the index contains any items.
+   * 
+   * @return true if the index does not contain any items
+   */
+  public boolean isEmpty()
+  {
+    if (root == null) return true;
+    return false;
+  }
+  
 	/**
 	 * Inserts a new point in the kd-tree, with no data.
 	 * 
@@ -112,9 +123,25 @@ public class KdTree
 		boolean isOddLevel = true;
 		boolean isLessThan = true;
 
-		// traverse the tree first cutting the plane left-right the top-bottom
+		/**
+		 * Traverse the tree,
+		 * first cutting the plane left-right (by X ordinate)
+		 * then top-bottom (by Y ordinate)
+		 */
 		while (currentNode != last) {
-			if (isOddLevel) {
+      // test if point is already a node
+      if (currentNode != null) {
+        boolean isInTolerance = p.distance(currentNode.getCoordinate()) <= tolerance;
+
+        // check if point is already in tree (up to tolerance) and if so simply
+        // return existing node
+        if (isInTolerance) {
+          currentNode.increment();
+          return currentNode;
+        }
+      }
+
+      if (isOddLevel) {
 				isLessThan = p.x < currentNode.getX();
 			} else {
 				isLessThan = p.y < currentNode.getY();
@@ -125,23 +152,7 @@ public class KdTree
 			} else {
 				currentNode = currentNode.getRight();
 			}
-			// test if point is already a node
-			if (currentNode != null) {
-				boolean isInTolerance = p.distance(currentNode.getCoordinate()) <= tolerance;
-
-				// if (isInTolerance && ! p.equals2D(currentNode.getCoordinate())) {
-				// System.out.println("KDTree: Snapped!");
-				// System.out.println(WKTWriter.toPoint(p));
-				// }
-
-				// check if point is already in tree (up to tolerance) and if so simply
-				// return
-				// existing node
-				if (isInTolerance) {
-					currentNode.increment();
-					return currentNode;
-				}
-			}
+			
 			isOddLevel = !isOddLevel;
 		}
 
diff --git a/src/com/vividsolutions/jts/index/quadtree/Node.java b/src/com/vividsolutions/jts/index/quadtree/Node.java
index 742e24a..3457094 100644
--- a/src/com/vividsolutions/jts/index/quadtree/Node.java
+++ b/src/com/vividsolutions/jts/index/quadtree/Node.java
@@ -33,7 +33,6 @@
  */
 package com.vividsolutions.jts.index.quadtree;
 
-import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.Envelope;
 import com.vividsolutions.jts.util.Assert;
 
@@ -65,7 +64,8 @@ public class Node
   }
 
   private Envelope env;
-  private Coordinate centre;
+  private double centrex;
+  private double centrey;
   private int level;
 
   public Node(Envelope env, int level)
@@ -73,9 +73,8 @@ public class Node
     //this.parent = parent;
     this.env = env;
     this.level = level;
-    centre = new Coordinate();
-    centre.x = (env.getMinX() + env.getMaxX()) / 2;
-    centre.y = (env.getMinY() + env.getMaxY()) / 2;
+    centrex = (env.getMinX() + env.getMaxX()) / 2;
+    centrey = (env.getMinY() + env.getMaxY()) / 2;
   }
 
   public Envelope getEnvelope() { return env; }
@@ -86,13 +85,15 @@ public class Node
   }
 
   /**
-   * Returns the subquad containing the envelope.
+   * Returns the subquad containing the envelope <tt>searchEnv</tt>.
    * Creates the subquad if
    * it does not already exist.
+   * 
+   * @return the subquad containing the search envelope
    */
   public Node getNode(Envelope searchEnv)
   {
-    int subnodeIndex = getSubnodeIndex(searchEnv, centre);
+    int subnodeIndex = getSubnodeIndex(searchEnv, centrex, centrey);
     // if subquadIndex is -1 searchEnv is not contained in a subquad
     if (subnodeIndex != -1) {
       // create the quad if it does not exist
@@ -111,7 +112,7 @@ public class Node
    */
   public NodeBase find(Envelope searchEnv)
   {
-    int subnodeIndex = getSubnodeIndex(searchEnv, centre);
+    int subnodeIndex = getSubnodeIndex(searchEnv, centrex, centrey);
     if (subnodeIndex == -1)
       return this;
     if (subnode[subnodeIndex] != null) {
@@ -128,7 +129,7 @@ public class Node
     Assert.isTrue(env == null || env.contains(node.env));
 //System.out.println(env);
 //System.out.println(quad.env);
-    int index = getSubnodeIndex(node.env, centre);
+    int index = getSubnodeIndex(node.env, centrex, centrey);
 //System.out.println(index);
     if (node.level == level - 1) {
       subnode[index] = node;
@@ -167,26 +168,26 @@ public class Node
       switch (index) {
       case 0:
         minx = env.getMinX();
-        maxx = centre.x;
+        maxx = centrex;
         miny = env.getMinY();
-        maxy = centre.y;
+        maxy = centrey;
         break;
       case 1:
-        minx = centre.x;
+        minx = centrex;
         maxx = env.getMaxX();
         miny = env.getMinY();
-        maxy = centre.y;
+        maxy = centrey;
         break;
       case 2:
         minx = env.getMinX();
-        maxx = centre.x;
-        miny = centre.y;
+        maxx = centrex;
+        miny = centrey;
         maxy = env.getMaxY();
         break;
       case 3:
-        minx = centre.x;
+        minx = centrex;
         maxx = env.getMaxX();
-        miny = centre.y;
+        miny = centrey;
         maxy = env.getMaxY();
         break;
       }
diff --git a/src/com/vividsolutions/jts/index/quadtree/NodeBase.java b/src/com/vividsolutions/jts/index/quadtree/NodeBase.java
index f74d65e..087fd42 100644
--- a/src/com/vividsolutions/jts/index/quadtree/NodeBase.java
+++ b/src/com/vividsolutions/jts/index/quadtree/NodeBase.java
@@ -33,44 +33,40 @@
  */
 package com.vividsolutions.jts.index.quadtree;
 
-import java.util.*;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
 
-import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.Envelope;
-import com.vividsolutions.jts.index.*;
+import com.vividsolutions.jts.index.ItemVisitor;
 
 /**
  * The base class for nodes in a {@link Quadtree}.
  *
  * @version 1.7
  */
-public abstract class NodeBase {
-
-//<<TODO:REFACTOR?>> Several classes in the various tree packages have the
-//same name and duplicate code. This suggests that there should be a generic
-//tree package containing the code that is duplicated, perhaps in abstract
-//base classes. [Jon Aquino]
-
-//<<TODO:RENAME?>> This little class hierarchy has some naming/conceptual
-//problems. A root node is conceptually a kind of node, yet a Root is not a Node.
-//NodeBase begs to be called BaseNode, but not all BaseNodes would be Nodes
-//(for example, Root). [Jon Aquino]
+public abstract class NodeBase implements Serializable {
 
 //DEBUG private static int itemCount = 0;  // debugging
+  
   /**
-   * Returns the index of the subquad that wholly contains the given envelope.
+   * Gets the index of the subquad that wholly contains the given envelope.
    * If none does, returns -1.
+   * 
+   * @return the index of the subquad that wholly contains the given envelope
+   * or -1 if no subquad wholly contains the envelope
    */
-  public static int getSubnodeIndex(Envelope env, Coordinate centre)
+  public static int getSubnodeIndex(Envelope env, double centrex, double centrey)
   {
     int subnodeIndex = -1;
-    if (env.getMinX() >= centre.x) {
-      if (env.getMinY() >= centre.y) subnodeIndex = 3;
-      if (env.getMaxY() <= centre.y) subnodeIndex = 1;
+    if (env.getMinX() >= centrex) {
+      if (env.getMinY() >= centrey) subnodeIndex = 3;
+      if (env.getMaxY() <= centrey) subnodeIndex = 1;
     }
-    if (env.getMaxX() <= centre.x) {
-      if (env.getMinY() >= centre.y) subnodeIndex = 2;
-      if (env.getMaxY() <= centre.y) subnodeIndex = 0;
+    if (env.getMaxX() <= centrex) {
+      if (env.getMinY() >= centrey) subnodeIndex = 2;
+      if (env.getMaxY() <= centrey) subnodeIndex = 0;
     }
     return subnodeIndex;
   }
diff --git a/src/com/vividsolutions/jts/index/quadtree/Quadtree.java b/src/com/vividsolutions/jts/index/quadtree/Quadtree.java
index fb4d8c4..d39841d 100644
--- a/src/com/vividsolutions/jts/index/quadtree/Quadtree.java
+++ b/src/com/vividsolutions/jts/index/quadtree/Quadtree.java
@@ -33,37 +33,45 @@
  */
 package com.vividsolutions.jts.index.quadtree;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 import com.vividsolutions.jts.geom.Envelope;
 import com.vividsolutions.jts.index.*;
 /**
- * A Quadtree is a spatial index structure for efficient querying
- * of 2D rectangles.  If other kinds of spatial objects
- * need to be indexed they can be represented by their
- * envelopes
+ * A Quadtree is a spatial index structure for efficient range querying
+ * of items bounded by 2D rectangles.  
+ * {@link Geometry}s can be indexed by using their
+ * {@link Envelope}s.
+ * Any type of Object can also be indexed as
+ * long as it has an extent that can be represented by an {@link Envelope}.
  * <p>
- * The quadtree structure is used to provide a primary filter
- * for range rectangle queries.  The query() method returns a list of
- * all objects which <i>may</i> intersect the query rectangle.  Note that
- * it may return objects which do not in fact intersect.
- * A secondary filter is required to test for exact intersection.
- * Of course, this secondary filter may consist of other tests besides
- * intersection, such as testing other kinds of spatial relationships.
- *
+ * This Quadtree index provides a <b>primary filter</b>
+ * for range rectangle queries.  The various query methods return a list of
+ * all items which <i>may</i> intersect the query rectangle.  Note that
+ * it may thus return items which do <b>not</b> in fact intersect the query rectangle.
+ * A secondary filter is required to test for actual intersection 
+ * between the query rectangle and the envelope of each candidate item. 
+ * The secondary filter may be performed explicitly, 
+ * or it may be provided implicitly by subsequent operations executed on the items 
+ * (for instance, if the index query is followed by computing a spatial predicate 
+ * between the query geometry and tree items, 
+ * the envelope intersection check is performed automatically.
  * <p>
  * This implementation does not require specifying the extent of the inserted
  * items beforehand.  It will automatically expand to accomodate any extent
  * of dataset.
  * <p>
  * This data structure is also known as an <i>MX-CIF quadtree</i>
- * following the usage of Samet and others.
+ * following the terminology of Samet and others.
  *
  * @version 1.7
  */
 public class Quadtree
-    implements SpatialIndex
+    implements SpatialIndex, Serializable
 {
+  private static final long serialVersionUID = -7461163625812743604L;
+
   /**
    * Ensure that the envelope for the inserted item has non-zero extents.
    * Use the current minExtent to pad the envelope, if necessary
@@ -126,6 +134,17 @@ public class Quadtree
   }
 
   /**
+   * Tests whether the index contains any items.
+   * 
+   * @return true if the index does not contain any items
+   */
+  public boolean isEmpty()
+  {
+    if (root == null) return true;
+    return false;
+  }
+  
+  /**
    * Returns the number of items in the tree.
    *
    * @return the number of items in the tree
diff --git a/src/com/vividsolutions/jts/index/quadtree/Root.java b/src/com/vividsolutions/jts/index/quadtree/Root.java
index 1dd449f..f4fd76d 100644
--- a/src/com/vividsolutions/jts/index/quadtree/Root.java
+++ b/src/com/vividsolutions/jts/index/quadtree/Root.java
@@ -59,7 +59,7 @@ public class Root
    */
   public void insert(Envelope itemEnv, Object item)
   {
-    int index = getSubnodeIndex(itemEnv, origin);
+    int index = getSubnodeIndex(itemEnv, origin.x, origin.y);
     // if index is -1, itemEnv must cross the X or Y axis.
     if (index == -1) {
       add(item);
diff --git a/src/com/vividsolutions/jts/index/strtree/AbstractNode.java b/src/com/vividsolutions/jts/index/strtree/AbstractNode.java
index d51beab..2df956a 100644
--- a/src/com/vividsolutions/jts/index/strtree/AbstractNode.java
+++ b/src/com/vividsolutions/jts/index/strtree/AbstractNode.java
@@ -34,21 +34,37 @@
 package com.vividsolutions.jts.index.strtree;
 import com.vividsolutions.jts.util.*;
 
+import java.io.Serializable;
 import java.util.*;
 
 /**
- * A node of the STR tree. The children of this node are either more nodes
- * (AbstractNodes) or real data (ItemBoundables). If this node contains real data
- * (rather than nodes), then we say that this node is a "leaf node".
+ * A node of an {@link AbstractSTRtree}. A node is one of:
+ * <ul>
+ * <li>empty
+ * <li>an <i>interior node</i> containing child {@link AbstractNode}s
+ * <li>a <i>leaf node</i> containing data items ({@link ItemBoundable}s). 
+ * </ul>
+ * A node stores the bounds of its children, and its level within the index tree.
  *
  * @version 1.7
  */
-public abstract class AbstractNode implements Boundable {
+public abstract class AbstractNode implements Boundable, Serializable {
+  /**
+   * 
+   */
+  private static final long serialVersionUID = 6493722185909573708L;
+  
   private ArrayList childBoundables = new ArrayList();
   private Object bounds = null;
   private int level;
 
   /**
+   * Default constructor required for serialization.
+   */
+  public AbstractNode() {
+  }
+
+  /**
    * Constructs an AbstractNode at the given level in the tree
    * @param level 0 if this node is a leaf, 1 if a parent of a leaf, and so on; the
    * root node will have the highest level
@@ -77,6 +93,11 @@ public abstract class AbstractNode implements Boundable {
    */
   protected abstract Object computeBounds();
 
+  /**
+   * Gets the bounds of this node
+   * 
+   * @return the object representing bounds in this index
+   */
   public Object getBounds() {
     if (bounds == null) {
       bounds = computeBounds();
@@ -93,6 +114,26 @@ public abstract class AbstractNode implements Boundable {
   }
 
   /**
+   * Gets the count of the {@link Boundable}s at this node.
+   * 
+   * @return the count of boundables at this node
+   */
+  public int size()
+  {
+    return childBoundables.size();
+  }
+  
+  /**
+   * Tests whether there are any {@link Boundable}s at this node.
+   * 
+   * @return true if there are boundables at this node
+   */
+  public boolean isEmpty()
+  {
+    return childBoundables.isEmpty();
+  }
+  
+  /**
    * Adds either an AbstractNode, or if this is a leaf node, a data object
    * (wrapped in an ItemBoundable)
    */
diff --git a/src/com/vividsolutions/jts/index/strtree/AbstractSTRtree.java b/src/com/vividsolutions/jts/index/strtree/AbstractSTRtree.java
index f220941..4d586d1 100644
--- a/src/com/vividsolutions/jts/index/strtree/AbstractSTRtree.java
+++ b/src/com/vividsolutions/jts/index/strtree/AbstractSTRtree.java
@@ -35,24 +35,30 @@ package com.vividsolutions.jts.index.strtree;
 
 import com.vividsolutions.jts.index.ItemVisitor;
 import com.vividsolutions.jts.util.*;
+
+import java.io.Serializable;
 import java.util.*;
-import java.util.List;
 
 /**
  * Base class for STRtree and SIRtree. STR-packed R-trees are described in:
- * P. Rigaux, Michel Scholl and Agnes Voisard. Spatial Databases With
- * Application To GIS. Morgan Kaufmann, San Francisco, 2002.
+ * P. Rigaux, Michel Scholl and Agnes Voisard. <i>Spatial Databases With
+ * Application To GIS.</i> Morgan Kaufmann, San Francisco, 2002.
  * <p>
- * This implementation is based on Boundables rather than just AbstractNodes,
+ * This implementation is based on {@link Boundable}s rather than {@link AbstractNode}s,
  * because the STR algorithm operates on both nodes and
- * data, both of which are treated here as Boundables.
+ * data, both of which are treated as Boundables.
  *
  * @see STRtree
  * @see SIRtree
  *
  * @version 1.7
  */
-public abstract class AbstractSTRtree {
+public abstract class AbstractSTRtree implements Serializable {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = -3886435814360241337L;
 
   /**
    * A test for intersection between two bounds, necessary because subclasses
@@ -72,12 +78,28 @@ public abstract class AbstractSTRtree {
   protected AbstractNode root;
 
   private boolean built = false;
+  /**
+   * Set to <tt>null</tt> when index is built, to avoid retaining memory.
+   */
   private ArrayList itemBoundables = new ArrayList();
+  
   private int nodeCapacity;
 
+  private static final int DEFAULT_NODE_CAPACITY = 10;
+
+  /**
+   * Constructs an AbstractSTRtree with the 
+   * default node capacity.
+   */
+  public AbstractSTRtree() {
+    this(DEFAULT_NODE_CAPACITY);
+  }
+
   /**
    * Constructs an AbstractSTRtree with the specified maximum number of child
    * nodes that a node may have
+   * 
+   * @param nodeCapacity the maximum number of child nodes in a node
    */
   public AbstractSTRtree(int nodeCapacity) {
     Assert.isTrue(nodeCapacity > 1, "Node capacity must be greater than 1");
@@ -91,10 +113,12 @@ public abstract class AbstractSTRtree {
    * inserted into the tree.
    */
   public void build() {
-    Assert.isTrue(!built);
+    if (built) return;
     root = itemBoundables.isEmpty()
-           ?createNode(0)
-           :createHigherLevels(itemBoundables, -1);
+           ? createNode(0)
+           : createHigherLevels(itemBoundables, -1);
+    // the item list is no longer needed
+    itemBoundables = null;
     built = true;
   }
 
@@ -124,7 +148,7 @@ public abstract class AbstractSTRtree {
     return (AbstractNode) nodes.get(nodes.size() - 1);
   }
 
-  protected int compareDoubles(double a, double b) {
+  protected static int compareDoubles(double a, double b) {
     return a > b ? 1
          : a < b ? -1
          : 0;
@@ -151,7 +175,7 @@ public abstract class AbstractSTRtree {
 
   public AbstractNode getRoot() 
   {
-    if (! built) build();
+    build();
     return root; 
   }
 
@@ -160,11 +184,24 @@ public abstract class AbstractSTRtree {
    */
   public int getNodeCapacity() { return nodeCapacity; }
 
+  /**
+   * Tests whether the index contains any items.
+   * This method does not build the index,
+   * so items can still be inserted after it has been called.
+   * 
+   * @return true if the index does not contain any items
+   */
+  public boolean isEmpty()
+  {
+    if (! built) return itemBoundables.isEmpty();
+    return root.isEmpty();
+  }
+  
   protected int size() {
-    if (!built) { build(); }
-    if (itemBoundables.isEmpty()) {
+    if (isEmpty()) {
       return 0;
     }
+    build();
     return size(root);
   }
 
@@ -184,10 +221,10 @@ public abstract class AbstractSTRtree {
   }
 
   protected int depth() {
-    if (!built) { build(); }
-    if (itemBoundables.isEmpty()) {
+    if (isEmpty()) {
       return 0;
     }
+    build();
     return depth(root);
   }
 
@@ -215,10 +252,10 @@ public abstract class AbstractSTRtree {
    *  Also builds the tree, if necessary.
    */
   protected List query(Object searchBounds) {
-    if (!built) { build(); }
+    build();
     ArrayList matches = new ArrayList();
-    if (itemBoundables.isEmpty()) {
-      Assert.isTrue(root.getBounds() == null);
+    if (isEmpty()) {
+      //Assert.isTrue(root.getBounds() == null);
       return matches;
     }
     if (getIntersectsOp().intersects(root.getBounds(), searchBounds)) {
@@ -231,9 +268,11 @@ public abstract class AbstractSTRtree {
    *  Also builds the tree, if necessary.
    */
   protected void query(Object searchBounds, ItemVisitor visitor) {
-    if (!built) { build(); }
-    if (itemBoundables.isEmpty()) {
-      Assert.isTrue(root.getBounds() == null);
+    build();
+    if (isEmpty()) {
+      // nothing in tree, so return
+      //Assert.isTrue(root.getBounds() == null);
+      return;
     }
     if (getIntersectsOp().intersects(root.getBounds(), searchBounds)) {
       query(searchBounds, root, visitor);
@@ -248,9 +287,10 @@ public abstract class AbstractSTRtree {
   protected abstract IntersectsOp getIntersectsOp();
 
   private void query(Object searchBounds, AbstractNode node, List matches) {
-    for (Iterator i = node.getChildBoundables().iterator(); i.hasNext(); ) {
-      Boundable childBoundable = (Boundable) i.next();
-      if (!getIntersectsOp().intersects(childBoundable.getBounds(), searchBounds)) {
+    List childBoundables = node.getChildBoundables();
+    for (int i = 0; i < childBoundables.size(); i++) {
+      Boundable childBoundable = (Boundable) childBoundables.get(i);
+      if (! getIntersectsOp().intersects(childBoundable.getBounds(), searchBounds)) {
         continue;
       }
       if (childBoundable instanceof AbstractNode) {
@@ -266,9 +306,10 @@ public abstract class AbstractSTRtree {
   }
 
   private void query(Object searchBounds, AbstractNode node, ItemVisitor visitor) {
-    for (Iterator i = node.getChildBoundables().iterator(); i.hasNext(); ) {
-      Boundable childBoundable = (Boundable) i.next();
-      if (!getIntersectsOp().intersects(childBoundable.getBounds(), searchBounds)) {
+    List childBoundables = node.getChildBoundables();
+    for (int i = 0; i < childBoundables.size(); i++) {
+      Boundable childBoundable = (Boundable) childBoundables.get(i);
+      if (! getIntersectsOp().intersects(childBoundable.getBounds(), searchBounds)) {
         continue;
       }
       if (childBoundable instanceof AbstractNode) {
@@ -297,7 +338,7 @@ public abstract class AbstractSTRtree {
    */
   public List itemsTree()
   {
-    if (!built) { build(); }
+    build();
 
     List valuesTree = itemsTree(root);
     if (valuesTree == null)
@@ -333,7 +374,7 @@ public abstract class AbstractSTRtree {
    * (Builds the tree, if necessary.)
    */
   protected boolean remove(Object searchBounds, Object item) {
-    if (!built) { build(); }
+    build();
     if (itemBoundables.isEmpty()) {
       Assert.isTrue(root.getBounds() == null);
     }
diff --git a/src/com/vividsolutions/jts/index/strtree/Boundable.java b/src/com/vividsolutions/jts/index/strtree/Boundable.java
index b5578e3..d9a1fcc 100644
--- a/src/com/vividsolutions/jts/index/strtree/Boundable.java
+++ b/src/com/vividsolutions/jts/index/strtree/Boundable.java
@@ -46,7 +46,6 @@ public interface Boundable {
    * on the subclass of AbstractSTRtree.
    * @return an Envelope (for STRtrees), an Interval (for SIRtrees), or other object
    * (for other subclasses of AbstractSTRtree)
-   * @see AbstractSTRtree.IntersectsOp
    */
   Object getBounds();
 }
diff --git a/src/com/vividsolutions/jts/index/strtree/BoundablePair.java b/src/com/vividsolutions/jts/index/strtree/BoundablePair.java
index 9629f0a..f84726f 100644
--- a/src/com/vividsolutions/jts/index/strtree/BoundablePair.java
+++ b/src/com/vividsolutions/jts/index/strtree/BoundablePair.java
@@ -181,7 +181,6 @@ class BoundablePair
    * computes a list of new pairs 
    * from the expansion of the larger boundable.
    * 
-   * @return a List of new pairs
    */
   public void expandToQueue(PriorityQueue priQ, double minDistance)
   {
diff --git a/src/com/vividsolutions/jts/index/strtree/GeometryItemDistance.java b/src/com/vividsolutions/jts/index/strtree/GeometryItemDistance.java
index 84f972b..6303f74 100644
--- a/src/com/vividsolutions/jts/index/strtree/GeometryItemDistance.java
+++ b/src/com/vividsolutions/jts/index/strtree/GeometryItemDistance.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.index.strtree;
 
 import com.vividsolutions.jts.geom.Geometry;
diff --git a/src/com/vividsolutions/jts/index/strtree/ItemBoundable.java b/src/com/vividsolutions/jts/index/strtree/ItemBoundable.java
index 76fa1f6..621f54c 100644
--- a/src/com/vividsolutions/jts/index/strtree/ItemBoundable.java
+++ b/src/com/vividsolutions/jts/index/strtree/ItemBoundable.java
@@ -33,13 +33,15 @@
  */
 package com.vividsolutions.jts.index.strtree;
 
+import java.io.Serializable;
+
 /**
  * Boundable wrapper for a non-Boundable spatial object. Used internally by
  * AbstractSTRtree.
  *
  * @version 1.7
  */
-public class ItemBoundable implements Boundable {
+public class ItemBoundable implements Boundable, Serializable {
   private Object bounds;
   private Object item;
 
diff --git a/src/com/vividsolutions/jts/index/strtree/ItemDistance.java b/src/com/vividsolutions/jts/index/strtree/ItemDistance.java
index 4879816..a8e1a88 100644
--- a/src/com/vividsolutions/jts/index/strtree/ItemDistance.java
+++ b/src/com/vividsolutions/jts/index/strtree/ItemDistance.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.index.strtree;
 
 
diff --git a/src/com/vividsolutions/jts/index/strtree/STRtree.java b/src/com/vividsolutions/jts/index/strtree/STRtree.java
index 47e1fba..5161137 100644
--- a/src/com/vividsolutions/jts/index/strtree/STRtree.java
+++ b/src/com/vividsolutions/jts/index/strtree/STRtree.java
@@ -34,6 +34,8 @@
 package com.vividsolutions.jts.index.strtree;
 
 import com.vividsolutions.jts.index.strtree.AbstractSTRtree;
+
+import java.io.Serializable;
 import java.util.*;
 import com.vividsolutions.jts.geom.*;
 import com.vividsolutions.jts.util.*;
@@ -56,9 +58,38 @@ import com.vividsolutions.jts.index.*;
  *
  * @version 1.7
  */
-public class STRtree extends AbstractSTRtree implements SpatialIndex {
+public class STRtree extends AbstractSTRtree 
+implements SpatialIndex, Serializable 
+{
+
+  private static final class STRtreeNode extends AbstractNode
+  {
+    private STRtreeNode(int level)
+    {
+      super(level);
+    }
+
+    protected Object computeBounds() {
+      Envelope bounds = null;
+      for (Iterator i = getChildBoundables().iterator(); i.hasNext(); ) {
+        Boundable childBoundable = (Boundable) i.next();
+        if (bounds == null) {
+          bounds = new Envelope((Envelope)childBoundable.getBounds());
+        }
+        else {
+          bounds.expandToInclude((Envelope)childBoundable.getBounds());
+        }
+      }
+      return bounds;
+    }
+  }
 
-  private Comparator xComparator =
+  /**
+   * 
+   */
+  private static final long serialVersionUID = 259274702368956900L;
+  
+  private static Comparator xComparator =
     new Comparator() {
       public int compare(Object o1, Object o2) {
         return compareDoubles(
@@ -66,7 +97,7 @@ public class STRtree extends AbstractSTRtree implements SpatialIndex {
             centreX((Envelope)((Boundable)o2).getBounds()));
       }
     };
-  private Comparator yComparator =
+  private static Comparator yComparator =
     new Comparator() {
       public int compare(Object o1, Object o2) {
         return compareDoubles(
@@ -75,17 +106,17 @@ public class STRtree extends AbstractSTRtree implements SpatialIndex {
       }
     };
 
-  private double centreX(Envelope e) {
+  private static double centreX(Envelope e) {
     return avg(e.getMinX(), e.getMaxX());
   }
 
-  private double avg(double a, double b) { return (a + b) / 2d; }
-
-  private double centreY(Envelope e) {
+  private static double centreY(Envelope e) {
     return avg(e.getMinY(), e.getMaxY());
   }
 
-  private IntersectsOp intersectsOp = new IntersectsOp() {
+  private static double avg(double a, double b) { return (a + b) / 2d; }
+
+  private static IntersectsOp intersectsOp = new IntersectsOp() {
     public boolean intersects(Object aBounds, Object bBounds) {
       return ((Envelope)aBounds).intersects((Envelope)bBounds);
     }
@@ -142,6 +173,7 @@ public class STRtree extends AbstractSTRtree implements SpatialIndex {
   }
 
   private static final int DEFAULT_NODE_CAPACITY = 10;
+  
   /**
    * Constructs an STRtree with the default node capacity.
    */
@@ -162,21 +194,7 @@ public class STRtree extends AbstractSTRtree implements SpatialIndex {
   }
 
   protected AbstractNode createNode(int level) {
-    return new AbstractNode(level) {
-      protected Object computeBounds() {
-        Envelope bounds = null;
-        for (Iterator i = getChildBoundables().iterator(); i.hasNext(); ) {
-          Boundable childBoundable = (Boundable) i.next();
-          if (bounds == null) {
-            bounds = new Envelope((Envelope)childBoundable.getBounds());
-          }
-          else {
-            bounds.expandToInclude((Envelope)childBoundable.getBounds());
-          }
-        }
-        return bounds;
-      }
-    };
+    return new STRtreeNode(level);
   }
 
   protected IntersectsOp getIntersectsOp() {
@@ -260,11 +278,15 @@ public class STRtree extends AbstractSTRtree implements SpatialIndex {
   }
   
   /**
-   * Finds the nearest item to the given object
-   * in this tree, 
+   * Finds the item in this tree which is nearest to the given {@link Object}, 
    * using {@link ItemDistance} as the distance metric.
    * A Branch-and-Bound tree traversal algorithm is used
    * to provide an efficient search.
+   * <p>
+   * The query <tt>object</tt> does <b>not</b> have to be 
+   * contained in the tree, but it does 
+   * have to be compatible with the <tt>itemDist</tt> 
+   * distance metric. 
    * 
    * @param env the envelope of the query item
    * @param item the item to find the nearest neighbour of
diff --git a/src/com/vividsolutions/jts/io/ByteOrderDataInStream.java b/src/com/vividsolutions/jts/io/ByteOrderDataInStream.java
index 9b53da4..57c945a 100644
--- a/src/com/vividsolutions/jts/io/ByteOrderDataInStream.java
+++ b/src/com/vividsolutions/jts/io/ByteOrderDataInStream.java
@@ -74,9 +74,9 @@ public class ByteOrderDataInStream
   }
 
   /**
+   * Reads a byte value
    *
-   *
-   * @return
+   * @return the byte read
    */
   public byte readByte()
   	throws IOException
diff --git a/src/com/vividsolutions/jts/io/InStream.java b/src/com/vividsolutions/jts/io/InStream.java
index 03a6c6e..1fadb99 100644
--- a/src/com/vividsolutions/jts/io/InStream.java
+++ b/src/com/vividsolutions/jts/io/InStream.java
@@ -36,7 +36,7 @@ import java.io.IOException;
 
 /**
  * A interface for classes providing an input stream of bytes.
- * This interface is similar to the Java {@link InputStream},
+ * This interface is similar to the Java <code>InputStream</code>,
  * but with a narrower interface to make it easier to implement.
  *
  */
diff --git a/src/com/vividsolutions/jts/io/OutStream.java b/src/com/vividsolutions/jts/io/OutStream.java
index 773574f..0b2bd3b 100644
--- a/src/com/vividsolutions/jts/io/OutStream.java
+++ b/src/com/vividsolutions/jts/io/OutStream.java
@@ -36,7 +36,7 @@ import java.io.IOException;
 
 /**
  * A interface for classes providing an output stream of bytes.
- * This interface is similar to the Java {@link OutputStream},
+ * This interface is similar to the Java <code>OutputStream</code>,
  * but with a narrower interface to make it easier to implement.
  */
 public interface OutStream
diff --git a/src/com/vividsolutions/jts/io/WKTFileReader.java b/src/com/vividsolutions/jts/io/WKBHexFileReader.java
similarity index 54%
copy from src/com/vividsolutions/jts/io/WKTFileReader.java
copy to src/com/vividsolutions/jts/io/WKBHexFileReader.java
index 0fdc8b9..70aaa59 100644
--- a/src/com/vividsolutions/jts/io/WKTFileReader.java
+++ b/src/com/vividsolutions/jts/io/WKBHexFileReader.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.io;
 
 import java.io.*;
@@ -5,58 +38,58 @@ import java.util.*;
 import com.vividsolutions.jts.geom.*;
 
 /**
- * Reads a sequence of {@link Geometry}s in WKT format 
+ * Reads a sequence of {@link Geometry}s in WKBHex format 
  * from a text file.
+ * Each WKBHex geometry must be on a single line
  * The geometries in the file may be separated by any amount
  * of whitespace and newlines.
  * 
  * @author Martin Davis
  *
  */
-public class WKTFileReader 
+public class WKBHexFileReader 
 {
 	private File file = null;
   private Reader reader;
-//  private Reader fileReader = new FileReader(file);
-	private WKTReader wktReader;
+	private WKBReader wkbReader;
 	private int count = 0;
 	private int limit = -1;
 	private int offset = 0;
 	
   /**
-   * Creates a new <tt>WKTFileReader</tt> given the <tt>File</tt> to read from 
+   * Creates a new <tt>WKBHexFileReader</tt> given the <tt>File</tt> to read from 
    * and a <tt>WKTReader</tt> to use to parse the geometries.
    * 
    * @param file the <tt>File</tt> to read from
-   * @param wktReader the geometry reader to use
+   * @param wkbReader the geometry reader to use
    */
-	public WKTFileReader(File file, WKTReader wktReader)
+	public WKBHexFileReader(File file, WKBReader wkbReader)
 	{
 		this.file = file;
-    this.wktReader = wktReader;
+    this.wkbReader = wkbReader;
 	}
 	
   /**
-   * Creates a new <tt>WKTFileReader</tt>, given the name of the file to read from.
+   * Creates a new <tt>WKBHexFileReader</tt>, given the name of the file to read from.
    * 
    * @param filename the name of the file to read from
-   * @param wktReader the geometry reader to use
+   * @param wkbReader the geometry reader to use
    */
-  public WKTFileReader(String filename, WKTReader wktReader)
+  public WKBHexFileReader(String filename, WKBReader wkbReader)
   {
-    this(new File(filename), wktReader);
+    this(new File(filename), wkbReader);
   }
   
   /**
-   * Creates a new <tt>WKTFileReader</tt>, given a {@link Reader} to read from.
+   * Creates a new <tt>WKBHexFileReader</tt>, given a {@link Reader} to read from.
    * 
    * @param reader the reader to read from
-   * @param wktReader the geometry reader to use
+   * @param wkbReader the geometry reader to use
    */
-  public WKTFileReader(Reader reader, WKTReader wktReader)
+  public WKBHexFileReader(Reader reader, WKBReader wkbReader)
   {
     this.reader = reader;
-    this.wktReader = wktReader;
+    this.wkbReader = wkbReader;
   }
   
 	/**
@@ -112,7 +145,10 @@ public class WKTFileReader
 			ParseException {
 		List geoms = new ArrayList();
 		while (! isAtEndOfFile(bufferedReader) && ! isAtLimit(geoms)) {
-			Geometry g = wktReader.read(bufferedReader);
+		  String line = bufferedReader.readLine().trim();
+		  if (line.length() == 0) 
+		    continue;
+			Geometry g = wkbReader.read(WKBReader.hexToBytes(line));
 			if (count >= offset)
 				geoms.add(g);
 			count++;
diff --git a/src/com/vividsolutions/jts/io/WKBReader.java b/src/com/vividsolutions/jts/io/WKBReader.java
index f2c833c..4bbc43d 100644
--- a/src/com/vividsolutions/jts/io/WKBReader.java
+++ b/src/com/vividsolutions/jts/io/WKBReader.java
@@ -38,12 +38,16 @@ import com.vividsolutions.jts.geom.*;
 /**
  * Reads a {@link Geometry}from a byte stream in Well-Known Binary format.
  * Supports use of an {@link InStream}, which allows easy use
- * with arbitary byte stream sources.
+ * with arbitrary byte stream sources.
  * <p>
  * This class reads the format describe in {@link WKBWriter}.  
  * It also partially handles
  * the <b>Extended WKB</b> format used by PostGIS, 
  * by parsing and storing SRID values.
+ * The reader repairs structurally-invalid input
+ * (specifically, LineStrings and LinearRings which contain
+ * too few points have vertices added,
+ * and non-closed rings are closed).
  * <p>
  * This class is designed to support reuse of a single instance to read multiple
  * geometries. This class is not thread-safe; each thread should create its own
@@ -96,7 +100,11 @@ public class WKBReader
   private int inputDimension = 2;
   private boolean hasSRID = false;
   private int SRID = 0;
-  private boolean isRepairRings = false;
+  /**
+   * true if structurally invalid input should be reported rather than repaired.
+   * At some point this could be made client-controllable.
+   */
+  private boolean isStrict = false;
   private ByteOrderDataInStream dis = new ByteOrderDataInStream();
   private double[] ordValues;
 
@@ -130,7 +138,7 @@ public class WKBReader
   }
 
   /**
-   * Reads a {@link Geometry} in binary WKB format from an {@link InStream).
+   * Reads a {@link Geometry} in binary WKB format from an {@link InStream}.
    *
    * @param is the stream to read from
    * @return the Geometry read
@@ -149,11 +157,11 @@ public class WKBReader
   throws IOException, ParseException
   {
     // determine byte order
-    byte byteOrder = dis.readByte();
-    // default is big endian
-    if (byteOrder == WKBConstants.wkbNDR)
-      dis.setOrder(ByteOrderValues.LITTLE_ENDIAN);
-
+    byte byteOrderWKB = dis.readByte();
+    // always set byte order, since it may change from geometry to geometry
+    int byteOrder = byteOrderWKB == WKBConstants.wkbNDR ? ByteOrderValues.LITTLE_ENDIAN : ByteOrderValues.BIG_ENDIAN;
+    dis.setOrder(byteOrder);
+    
     int typeInt = dis.readInt();
     int geometryType = typeInt & 0xff;
     // determine if Z values are present
@@ -223,7 +231,7 @@ public class WKBReader
   private LineString readLineString() throws IOException
   {
     int size = dis.readInt();
-    CoordinateSequence pts = readCoordinateSequence(size);
+    CoordinateSequence pts = readCoordinateSequenceLineString(size);
     return factory.createLineString(pts);
   }
 
@@ -312,12 +320,20 @@ public class WKBReader
     return seq;
   }
 
+  private CoordinateSequence readCoordinateSequenceLineString(int size) throws IOException
+  {
+    CoordinateSequence seq = readCoordinateSequence(size);
+    if (isStrict) return seq;
+    if (seq.size() == 0 || seq.size() >= 2) return seq;
+    return CoordinateSequences.extend(csFactory, seq, 2);
+  }
+  
   private CoordinateSequence readCoordinateSequenceRing(int size) throws IOException
   {
-  	CoordinateSequence seq = readCoordinateSequence(size);
-  	if (! isRepairRings) return seq;
-  	if (CoordinateSequences.isRing(seq)) return seq;
-  	return CoordinateSequences.ensureValidRing(csFactory, seq);
+    CoordinateSequence seq = readCoordinateSequence(size);
+    if (isStrict) return seq;
+    if (CoordinateSequences.isRing(seq)) return seq;
+    return CoordinateSequences.ensureValidRing(csFactory, seq);
   }
 
   /**
diff --git a/src/com/vividsolutions/jts/io/WKBWriter.java b/src/com/vividsolutions/jts/io/WKBWriter.java
index 9a189d3..6e2e2bc 100644
--- a/src/com/vividsolutions/jts/io/WKBWriter.java
+++ b/src/com/vividsolutions/jts/io/WKBWriter.java
@@ -171,7 +171,7 @@ public class WKBWriter
    * Converts a byte array to a hexadecimal string.
    * 
    * @param bytes
-   * @return
+   * @return a string of hexadecimal digits
    * 
    * @deprecated
    */
@@ -227,7 +227,7 @@ public class WKBWriter
    * the given dimension (2 or 3) for output coordinates
    * and {@link ByteOrderValues#BIG_ENDIAN} byte order.
    * If the input geometry has a small coordinate dimension,
-   * coordinates will be padded with {@link NULL_ORDINATE}.
+   * coordinates will be padded with {@link Coordinate#NULL_ORDINATE}.
    *
    * @param outputDimension the coordinate dimension to output (2 or 3)
    */
@@ -241,8 +241,8 @@ public class WKBWriter
    * and {@link ByteOrderValues#BIG_ENDIAN} byte order. This constructor also
    * takes a flag to control whether srid information will be
    * written.
-   * If the input geometry has a small coordinate dimension,
-   * coordinates will be padded with {@link NULL_ORDINATE}.
+   * If the input geometry has a smaller coordinate dimension,
+   * coordinates will be padded with {@link Coordinate#NULL_ORDINATE}.
    *
    * @param outputDimension the coordinate dimension to output (2 or 3)
    * @param includeSRID indicates whether SRID should be written
diff --git a/src/com/vividsolutions/jts/io/WKTFileReader.java b/src/com/vividsolutions/jts/io/WKTFileReader.java
index 0fdc8b9..759ea2a 100644
--- a/src/com/vividsolutions/jts/io/WKTFileReader.java
+++ b/src/com/vividsolutions/jts/io/WKTFileReader.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.io;
 
 import java.io.*;
diff --git a/src/com/vividsolutions/jts/io/WKTReader.java b/src/com/vividsolutions/jts/io/WKTReader.java
index 046c689..53865f4 100644
--- a/src/com/vividsolutions/jts/io/WKTReader.java
+++ b/src/com/vividsolutions/jts/io/WKTReader.java
@@ -295,12 +295,12 @@ public class WKTReader
 	          return Double.parseDouble(tokenizer.sval);
 	        }
 	        catch (NumberFormatException ex) {
-	          throw new ParseException("Invalid number: " + tokenizer.sval);
+	          parseErrorWithLine("Invalid number: " + tokenizer.sval);
 	        }
       	}
       }
     }
-    parseError("number");
+    parseErrorExpected("number");
     return 0.0;
   }
   /**
@@ -318,7 +318,7 @@ public class WKTReader
     if (nextWord.equals(EMPTY) || nextWord.equals(L_PAREN)) {
       return nextWord;
     }
-    parseError(EMPTY + " or " + L_PAREN);
+    parseErrorExpected(EMPTY + " or " + L_PAREN);
     return null;
   }
 
@@ -336,7 +336,7 @@ public class WKTReader
     if (nextWord.equals(COMMA) || nextWord.equals(R_PAREN)) {
       return nextWord;
     }
-    parseError(COMMA + " or " + R_PAREN);
+    parseErrorExpected(COMMA + " or " + R_PAREN);
     return null;
   }
 
@@ -354,7 +354,7 @@ public class WKTReader
     if (nextWord.equals(R_PAREN)) {
       return nextWord;
     }
-    parseError(R_PAREN);
+    parseErrorExpected(R_PAREN);
     return null;
   }
 
@@ -381,7 +381,7 @@ public class WKTReader
     case ')': return R_PAREN;
     case ',': return COMMA;
     }
-    parseError("word");
+    parseErrorExpected("word");
     return null;
   }
 
@@ -401,13 +401,14 @@ public class WKTReader
   }
 
   /**
-   * Throws a formatted ParseException for the current token.
+   * Throws a formatted ParseException reporting that the current token
+   * was unexpected.
    *
    * @param expected a description of what was expected
    * @throws ParseException
    * @throws AssertionFailedException if an invalid token is encountered
    */
-  private void parseError(String expected)
+  private void parseErrorExpected(String expected)
       throws ParseException
   {
     // throws Asserts for tokens that should never be seen
@@ -417,9 +418,15 @@ public class WKTReader
       Assert.shouldNeverReachHere("Unexpected EOL token");
 
     String tokenStr = tokenString();
-    throw new ParseException("Expected " + expected + " but found " + tokenStr);
+    parseErrorWithLine("Expected " + expected + " but found " + tokenStr);
   }
 
+  private void parseErrorWithLine(String msg)
+  throws ParseException
+  {
+    throw new ParseException(msg + " (line " + tokenizer.lineno() + ")");
+  }
+  
   /**
    * Gets a description of the current token
    *
@@ -485,7 +492,9 @@ public class WKTReader
     else if (type.equalsIgnoreCase("GEOMETRYCOLLECTION")) {
       return readGeometryCollectionText();
     }
-    throw new ParseException("Unknown geometry type: " + type);
+    parseErrorWithLine("Unknown geometry type: " + type);
+    // should never reach here
+    return null;
   }
 
   /**
diff --git a/src/com/vividsolutions/jts/io/WKTWriter.java b/src/com/vividsolutions/jts/io/WKTWriter.java
index c2d0a52..cba671a 100644
--- a/src/com/vividsolutions/jts/io/WKTWriter.java
+++ b/src/com/vividsolutions/jts/io/WKTWriter.java
@@ -63,7 +63,8 @@ import java.text.DecimalFormatSymbols;
 public class WKTWriter
 {
   /**
-   * Generates the WKT for a <code>Point</code>.
+   * Generates the WKT for a <tt>POINT</tt>
+   * specified by a {@link Coordinate}.
    *
    * @param p0 the point coordinate
    *
@@ -75,11 +76,12 @@ public class WKTWriter
   }
 
   /**
-   * Generates the WKT for a N-point <code>LineString</code>.
+   * Generates the WKT for a <tt>LINESTRING</tt>
+   * specified by a {@link CoordinateSequence}.
    *
-   * @param seq the sequence to outpout
+   * @param seq the sequence to write
    *
-   * @return the WKT
+   * @return the WKT string
    */
   public static String toLineString(CoordinateSequence seq)
   {
@@ -100,7 +102,8 @@ public class WKTWriter
   }
 
   /**
-   * Generates the WKT for a 2-point <code>LineString</code>.
+   * Generates the WKT for a <tt>LINESTRING</tt>
+   * specified by two {@link Coordinate}s.
    *
    * @param p0 the first coordinate
    * @param p1 the second coordinate
@@ -240,8 +243,6 @@ public class WKTWriter
    *  Converts a <code>Geometry</code> to its Well-known Text representation.
    *
    *@param  geometry  a <code>Geometry</code> to process
-   *@return           a <Geometry Tagged Text> string (see the OpenGIS Simple
-   *      Features Specification)
    */
   public void write(Geometry geometry, Writer writer)
     throws IOException
@@ -273,8 +274,6 @@ public class WKTWriter
    *  well-known text more readable.
    *
    *@param  geometry  a <code>Geometry</code> to process
-   *@return           a <Geometry Tagged Text> string (see the OpenGIS Simple
-   *      Features Specification), with newlines and spaces
    */
   public void writeFormatted(Geometry geometry, Writer writer)
     throws IOException
@@ -285,8 +284,6 @@ public class WKTWriter
    *  Converts a <code>Geometry</code> to its Well-known Text representation.
    *
    *@param  geometry  a <code>Geometry</code> to process
-   *@return           a <Geometry Tagged Text> string (see the OpenGIS Simple
-   *      Features Specification)
    */
   private void writeFormatted(Geometry geometry, boolean useFormatting, Writer writer)
     throws IOException
diff --git a/src/com/vividsolutions/jts/io/gml2/GMLHandler.java b/src/com/vividsolutions/jts/io/gml2/GMLHandler.java
index c81421f..431585d 100644
--- a/src/com/vividsolutions/jts/io/gml2/GMLHandler.java
+++ b/src/com/vividsolutions/jts/io/gml2/GMLHandler.java
@@ -151,10 +151,10 @@ public class GMLHandler extends DefaultHandler {
 	/**
 	 * Tests whether this handler has completed parsing 
 	 * a geometry.
-	 * If this is the case, {@link getGeometry()} can be called
+	 * If this is the case, {@link #getGeometry()} can be called
 	 * to get the value of the parsed geometry.
 	 * 
-	 * @return
+	 * @return if the parsing of the geometry is complete
 	 */
 	public boolean isGeometryComplete()
 	{
diff --git a/src/com/vividsolutions/jts/io/gml2/GMLWriter.java b/src/com/vividsolutions/jts/io/gml2/GMLWriter.java
index 2682b9b..dad7391 100644
--- a/src/com/vividsolutions/jts/io/gml2/GMLWriter.java
+++ b/src/com/vividsolutions/jts/io/gml2/GMLWriter.java
@@ -134,7 +134,7 @@ public class GMLWriter {
 	 * opening tag of geometries.  Useful in XML-aware environments which 
 	 * parse the geometries before use, such as XSLT.
 	 * 
-	 * @param namespaceMode true if the GML namespace prefix declaration 
+	 * @param emitNamespace true if the GML namespace prefix declaration 
 	 * should be written in the root geometry element
 	 */
 	public void setNamespace(boolean emitNamespace) {
@@ -161,7 +161,7 @@ public class GMLWriter {
 	/**
 	 * Sets the starting column index for pretty printing
 	 * 
-	 * @param arg
+	 * @param indent
 	 */
 	public void setStartingIndentIndex(int indent) {
 		if (indent < 0)
@@ -172,7 +172,7 @@ public class GMLWriter {
 	/**
 	 * Sets the number of coordinates printed per line. 
 	 * 
-	 * @param arg
+	 * @param num
 	 */
 	public void setMaxCoordinatesPerLine(int num) {
 		if (num < 1)
@@ -186,7 +186,6 @@ public class GMLWriter {
 	 * 
 	 * @param geom
 	 * @return String GML2 Encoded Geometry
-	 * @throws IOException 
 	 */
 	public String write(Geometry geom) 
 	{
diff --git a/src/com/vividsolutions/jts/linearref/ExtractLineByLocation.java b/src/com/vividsolutions/jts/linearref/ExtractLineByLocation.java
index 6d4a0e5..601c139 100644
--- a/src/com/vividsolutions/jts/linearref/ExtractLineByLocation.java
+++ b/src/com/vividsolutions/jts/linearref/ExtractLineByLocation.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.linearref;
 
 import com.vividsolutions.jts.geom.*;
@@ -11,7 +44,7 @@ class ExtractLineByLocation
 {
   /**
    * Computes the subline of a {@link LineString} between
-   * two {@link LineStringLocation}s on the line.
+   * two {@link LinearLocation}s on the line.
    * If the start location is after the end location,
    * the computed geometry is reversed.
    *
@@ -172,4 +205,4 @@ class ExtractLineByLocation
     return new LinearLocation(componentIndex, segmentIndex, segmentFraction);
   }
   */
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/linearref/LengthIndexOfPoint.java b/src/com/vividsolutions/jts/linearref/LengthIndexOfPoint.java
index a00e6f4..f2f20f8 100644
--- a/src/com/vividsolutions/jts/linearref/LengthIndexOfPoint.java
+++ b/src/com/vividsolutions/jts/linearref/LengthIndexOfPoint.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.linearref;
 
 import com.vividsolutions.jts.geom.*;
@@ -53,7 +86,7 @@ class LengthIndexOfPoint
    * minLocation = [end of line] ).
    *
    * @param inputPt the coordinate to locate
-   * @param minLocation the minimum location for the point location
+   * @param minIndex the minimum location for the point location
    * @return the location of the nearest point
    */
   public double indexOfAfter(Coordinate inputPt, double minIndex)
@@ -68,9 +101,8 @@ class LengthIndexOfPoint
     double closestAfter = indexOfFromStart(inputPt, minIndex);
     /**
      * Return the minDistanceLocation found.
-     * This will not be null, since it was initialized to minLocation
      */
-    Assert.isTrue(closestAfter > minIndex,
+    Assert.isTrue(closestAfter >= minIndex,
                   "computed index is before specified minimum index");
     return closestAfter;
   }
diff --git a/src/com/vividsolutions/jts/linearref/LengthIndexedLine.java b/src/com/vividsolutions/jts/linearref/LengthIndexedLine.java
index 74f6758..6c111ac 100644
--- a/src/com/vividsolutions/jts/linearref/LengthIndexedLine.java
+++ b/src/com/vividsolutions/jts/linearref/LengthIndexedLine.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.linearref;
 
 import com.vividsolutions.jts.geom.*;
@@ -78,8 +111,14 @@ public class LengthIndexedLine
   public Geometry extractLine(double startIndex, double endIndex)
   {
     LocationIndexedLine lil = new LocationIndexedLine(linearGeom);
-    LinearLocation startLoc = locationOf(startIndex);
-    LinearLocation endLoc = locationOf(endIndex);
+    double startIndex2 = clampIndex(startIndex);
+    double endIndex2 = clampIndex(endIndex);
+    // if extracted line is zero-length, resolve start lower as well to ensure they are equal
+    boolean resolveStartLower = startIndex2 == endIndex2;
+    LinearLocation startLoc = locationOf(startIndex2, resolveStartLower);
+//    LinearLocation endLoc = locationOf(endIndex2, true);
+//    LinearLocation startLoc = locationOf(startIndex2);
+    LinearLocation endLoc = locationOf(endIndex2);
     return ExtractLineByLocation.extract(linearGeom, startLoc, endLoc);
   }
 
@@ -88,6 +127,11 @@ public class LengthIndexedLine
     return LengthLocationMap.getLocation(linearGeom, index);
   }
 
+  private LinearLocation locationOf(double index, boolean resolveLower)
+  {
+    return LengthLocationMap.getLocation(linearGeom, index, resolveLower);
+  }
+
   /**
    * Computes the minimum index for a point on the line.
    * If the line is not simple (i.e. loops back on itself)
@@ -103,7 +147,7 @@ public class LengthIndexedLine
    * @param pt a point on the line
    * @return the minimum index of the point
    *
-   * @see project
+   * @see #project(Coordinate)
    */
   public double indexOf(Coordinate pt)
   {
@@ -130,7 +174,7 @@ public class LengthIndexedLine
    * @param minIndex the value the returned index must be greater than
    * @return the index of the point greater than the given minimum index
    *
-   * @see project
+   * @see #project(Coordinate)
    */
   public double indexOfAfter(Coordinate pt, double minIndex)
   {
@@ -192,7 +236,7 @@ public class LengthIndexedLine
   /**
    * Tests whether an index is in the valid index range for the line.
    *
-   * @param length the index to test
+   * @param index the index to test
    * @return <code>true</code> if the index is in the valid range
    */
   public boolean isValidIndex(double index)
@@ -209,12 +253,19 @@ public class LengthIndexedLine
    */
   public double clampIndex(double index)
   {
+    double posIndex = positiveIndex(index);
     double startIndex = getStartIndex();
-    if (index < startIndex) return startIndex;
+    if (posIndex < startIndex) return startIndex;
 
     double endIndex = getEndIndex();
-    if (index > endIndex) return endIndex;
+    if (posIndex > endIndex) return endIndex;
 
-    return index;
+    return posIndex;
+  }
+  
+  private double positiveIndex(double index)
+  {
+    if (index >= 0.0) return index;
+    return linearGeom.getLength() + index;
   }
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/linearref/LengthLocationMap.java b/src/com/vividsolutions/jts/linearref/LengthLocationMap.java
index 7461fbd..02d1f5a 100644
--- a/src/com/vividsolutions/jts/linearref/LengthLocationMap.java
+++ b/src/com/vividsolutions/jts/linearref/LengthLocationMap.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.linearref;
 
 import com.vividsolutions.jts.geom.*;
@@ -18,7 +51,7 @@ public class LengthLocationMap
    * Computes the {@link LinearLocation} for a
    * given length along a linear {@link Geometry}.
    *
-   * @param line the linear geometry to use
+   * @param linearGeom the linear geometry to use
    * @param length the length index of the location
    * @return the {@link LinearLocation} for the length
    */
@@ -29,10 +62,27 @@ public class LengthLocationMap
   }
 
   /**
+   * Computes the {@link LinearLocation} for a
+   * given length along a linear {@link Geometry},
+   * with control over how the location
+   * is resolved at component endpoints.
+   *
+   * @param linearGeom the linear geometry to use
+   * @param length the length index of the location
+   * @param resolveLower if true lengths are resolved to the lowest possible index
+   * @return the {@link LinearLocation} for the length
+   */
+  public static LinearLocation getLocation(Geometry linearGeom, double length, boolean resolveLower)
+  {
+    LengthLocationMap locater = new LengthLocationMap(linearGeom);
+    return locater.getLocation(length, resolveLower);
+  }
+
+  /**
    * Computes the length for a given {@link LinearLocation}
    * on a linear {@link Geometry}.
    *
-   * @param line the linear geometry to use
+   * @param linearGeom the linear geometry to use
    * @param loc the {@link LinearLocation} index of the location
    * @return the length for the {@link LinearLocation}
    */
@@ -53,18 +103,40 @@ public class LengthLocationMap
    * Compute the {@link LinearLocation} corresponding to a length.
    * Negative lengths are measured in reverse from end of the linear geometry.
    * Out-of-range values are clamped.
+   * Ambiguous indexes are resolved to the lowest possible location value.
    *
    * @param length the length index
    * @return the corresponding LinearLocation
    */
   public LinearLocation getLocation(double length)
   {
+    return getLocation(length, true);
+  }
+
+  /**
+   * Compute the {@link LinearLocation} corresponding to a length.
+   * Negative lengths are measured in reverse from end of the linear geometry.
+   * Out-of-range values are clamped.
+   * Ambiguous indexes are resolved to the lowest or highest possible location value,
+   * depending on the value of <tt>resolveLower</tt>
+   *
+   * @param length the length index
+   * @return the corresponding LinearLocation
+   */
+  public LinearLocation getLocation(double length, boolean resolveLower)
+  {
     double forwardLength = length;
+    
+    // negative values are measured from end of geometry
     if (length < 0.0) {
       double lineLen = linearGeom.getLength();
       forwardLength = lineLen + length;
     }
-    return getLocationForward(forwardLength);
+    LinearLocation loc = getLocationForward(forwardLength);
+    if (resolveLower) {
+      return loc;
+    }
+    return resolveHigher(loc);
   }
 
   private LinearLocation getLocationForward(double length)
@@ -76,7 +148,23 @@ public class LengthLocationMap
 
     LinearIterator it = new LinearIterator(linearGeom);
     while (it.hasNext()) {
-      if (! it.isEndOfLine()) {
+      
+      /**
+       * Special handling is required for the situation when the 
+       * length references exactly to a component endpoint.
+       * In this case, the endpoint location of the current component 
+       * is returned,
+       * rather than the startpoint location of the next component.
+       * This produces consistent behaviour with the project method.
+       */
+      if (it.isEndOfLine()) {
+        if (totalLength == length) {
+          int compIndex = it.getComponentIndex();
+          int segIndex = it.getVertexIndex();
+          return new LinearLocation(compIndex, segIndex, 0.0);          
+        }
+      }
+      else {
         Coordinate p0 = it.getSegmentStart();
         Coordinate p1 = it.getSegmentEnd();
         double segLen = p1.distance(p0);
@@ -89,12 +177,29 @@ public class LengthLocationMap
         }
         totalLength += segLen;
       }
+
       it.next();
     }
     // length is longer than line - return end location
     return LinearLocation.getEndLocation(linearGeom);
   }
 
+  private LinearLocation resolveHigher(LinearLocation loc)
+  {
+    if (! loc.isEndpoint(linearGeom)) 
+      return loc;
+    int compIndex = loc.getComponentIndex();
+    // if last component can't resolve any higher
+    if (compIndex >= linearGeom.getNumGeometries() - 1) return loc;
+ 
+    do {
+      compIndex++;
+    } while (compIndex < linearGeom.getNumGeometries() - 1
+        && linearGeom.getGeometryN(compIndex).getLength() == 0);
+    // resolve to next higher location
+    return new LinearLocation(compIndex, 0, 0.0); 
+  }
+  
   public double getLength(LinearLocation loc)
   {
     double totalLength = 0.0;
diff --git a/src/com/vividsolutions/jts/linearref/LinearGeometryBuilder.java b/src/com/vividsolutions/jts/linearref/LinearGeometryBuilder.java
index 89dcccb..f7af0ac 100644
--- a/src/com/vividsolutions/jts/linearref/LinearGeometryBuilder.java
+++ b/src/com/vividsolutions/jts/linearref/LinearGeometryBuilder.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.linearref;
 
 import java.util.*;
@@ -28,7 +61,7 @@ public class LinearGeometryBuilder
    * Allows invalid lines to be ignored rather than causing Exceptions.
    * An invalid line is one which has only one unique point.
    *
-   * @param ignoreShortLines <code>true</code> if short lines are to be ignored
+   * @param ignoreInvalidLines <code>true</code> if short lines are to be ignored
    */
   public void setIgnoreInvalidLines(boolean ignoreInvalidLines)
   {
@@ -39,7 +72,7 @@ public class LinearGeometryBuilder
    * Allows invalid lines to be ignored rather than causing Exceptions.
    * An invalid line is one which has only one unique point.
    *
-   * @param ignoreShortLines <code>true</code> if short lines are to be ignored
+   * @param fixInvalidLines <code>true</code> if short lines are to be ignored
    */
   public void setFixInvalidLines(boolean fixInvalidLines)
   {
@@ -116,4 +149,4 @@ public class LinearGeometryBuilder
     endLine();
     return geomFact.buildGeometry(lines);
   }
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/linearref/LinearIterator.java b/src/com/vividsolutions/jts/linearref/LinearIterator.java
index 13a32d1..198d681 100644
--- a/src/com/vividsolutions/jts/linearref/LinearIterator.java
+++ b/src/com/vividsolutions/jts/linearref/LinearIterator.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.linearref;
 
 import com.vividsolutions.jts.geom.*;
@@ -33,7 +66,6 @@ public class LinearIterator
 
   /**
    * Invariant: currentLine <> null if the iterator is pointing at a valid coordinate
-   * @throws IllegalArgumentException if linearGeom is not lineal
    */
   private LineString currentLine;
   private int componentIndex = 0;
@@ -92,6 +124,10 @@ public class LinearIterator
 
   /**
    * Tests whether there are any vertices left to iterator over.
+   * Specifically, hasNext() return <tt>true</tt> if the
+   * current state of the iterator represents a valid location
+   * on the linear geometry. 
+   * 
    * @return <code>true</code> if there are more vertices to scan
    */
   public boolean hasNext()
@@ -120,7 +156,7 @@ public class LinearIterator
 
   /**
    * Checks whether the iterator cursor is pointing to the
-   * endpoint of a linestring.
+   * endpoint of a component {@link LineString}.
    *
    * @return <code>true</true> if the iterator is at an endpoint
    */
@@ -170,4 +206,4 @@ public class LinearIterator
       return currentLine.getCoordinateN(vertexIndex + 1);
     return null;
   }
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/linearref/LinearLocation.java b/src/com/vividsolutions/jts/linearref/LinearLocation.java
index 5d683dc..751b47b 100644
--- a/src/com/vividsolutions/jts/linearref/LinearLocation.java
+++ b/src/com/vividsolutions/jts/linearref/LinearLocation.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.linearref;
 
 import com.vividsolutions.jts.geom.*;
@@ -76,6 +109,18 @@ public class LinearLocation
   }
 
   /**
+   * Creates a new location equal to a given one.
+   * 
+   * @param loc a LinearLocation
+   */
+  public LinearLocation(LinearLocation loc)
+  {
+    this.componentIndex = loc.componentIndex;
+    this.segmentIndex = loc.segmentIndex;
+    this.segmentFraction = loc.segmentFraction;
+  }
+
+  /**
    * Ensures the individual values are locally valid.
    * Does <b>not</b> ensure that the indexes are valid for
    * a particular linear geometry.
@@ -170,9 +215,9 @@ public class LinearLocation
 
   /**
    * Sets the value of this location to
-   * refer the end of a linear geometry
+   * refer to the end of a linear geometry.
    *
-   * @param linear the linear geometry to set
+   * @param linear the linear geometry to use to set the end
    */
   public void setToEnd(Geometry linear)
   {
@@ -218,7 +263,7 @@ public class LinearLocation
    * given linear {@link Geometry} which is
    * referenced by this location.
    *
-   * @param linearGeom a linear geometry
+   * @param linearGeom the linear geometry referenced by this location
    * @return the <tt>Coordinate</tt> at the location
    */
   public Coordinate getCoordinate(Geometry linearGeom)
@@ -371,6 +416,22 @@ public class LinearLocation
   }
 
   /**
+   * Tests whether this location is an endpoint of
+   * the linear component it refers to.
+   * 
+   * @param linearGeom the linear geometry referenced by this location
+   * @return true if the location is a component endpoint
+   */
+  public boolean isEndpoint(Geometry linearGeom)
+  {
+    LineString lineComp = (LineString) linearGeom.getGeometryN(componentIndex);
+    // check for endpoint
+    int nseg = lineComp.getNumPoints() - 1;
+    return segmentIndex >= nseg
+        || (segmentIndex == nseg && segmentFraction >= 1.0);
+  }
+    
+  /**
    * Copies this location
    *
    * @return a copy of this location
@@ -379,4 +440,12 @@ public class LinearLocation
   {
     return new LinearLocation(componentIndex, segmentIndex, segmentFraction);
   }
-}
\ No newline at end of file
+  
+  public String toString()
+  {
+    return "LinearLoc[" 
+    + componentIndex + ", "
+    + segmentIndex + ", "
+    + segmentFraction + "]";
+  }
+}
diff --git a/src/com/vividsolutions/jts/linearref/LocationIndexOfLine.java b/src/com/vividsolutions/jts/linearref/LocationIndexOfLine.java
index 104037b..c29a20e 100644
--- a/src/com/vividsolutions/jts/linearref/LocationIndexOfLine.java
+++ b/src/com/vividsolutions/jts/linearref/LocationIndexOfLine.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.linearref;
 
 import com.vividsolutions.jts.geom.*;
@@ -49,4 +82,4 @@ class LocationIndexOfLine
     }
     return subLineLoc;
   }
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/linearref/LocationIndexOfPoint.java b/src/com/vividsolutions/jts/linearref/LocationIndexOfPoint.java
index 3fff0dc..19475a5 100644
--- a/src/com/vividsolutions/jts/linearref/LocationIndexOfPoint.java
+++ b/src/com/vividsolutions/jts/linearref/LocationIndexOfPoint.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.linearref;
 
 import com.vividsolutions.jts.geom.*;
@@ -53,7 +86,7 @@ class LocationIndexOfPoint
    * minLocation = [end of line] ).
    *
    * @param inputPt the coordinate to locate
-   * @param minLocation the minimum location for the point location
+   * @param minIndex the minimum location for the point location
    * @return the location of the nearest point
    */
   public LinearLocation indexOfAfter(Coordinate inputPt, LinearLocation minIndex)
@@ -109,6 +142,11 @@ class LocationIndexOfPoint
         }
       }
     }
+    if (minDistance == Double.MAX_VALUE) {
+      // no minimum was found past minLocation, so return it
+      return new LinearLocation(minIndex);
+    }
+    // otherwise, return computed location
     LinearLocation loc = new LinearLocation(minComponentIndex, minSegmentIndex, minFrac);
     return loc;
   }
diff --git a/src/com/vividsolutions/jts/linearref/LocationIndexedLine.java b/src/com/vividsolutions/jts/linearref/LocationIndexedLine.java
index 344a5d8..262a109 100644
--- a/src/com/vividsolutions/jts/linearref/LocationIndexedLine.java
+++ b/src/com/vividsolutions/jts/linearref/LocationIndexedLine.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.linearref;
 
 import com.vividsolutions.jts.geom.*;
@@ -36,7 +69,7 @@ public class LocationIndexedLine
    * The Z-ordinate of the computed point will be interpolated from
    * the Z-ordinates of the line segment containing it, if they exist.
    *
-   * @param length the index of the desired point
+   * @param index the index of the desired point
    * @return the Coordinate at the given index
    */
   public Coordinate extractPoint(LinearLocation index)
@@ -89,7 +122,7 @@ public class LocationIndexedLine
    *
    * @param pt a point on the line
    * @return the index of the point
-   * @see project
+   * @see #project(Coordinate)
    */
   public LinearLocation indexOf(Coordinate pt)
   {
@@ -116,7 +149,7 @@ public class LocationIndexedLine
    * @param minIndex the value the returned index must be greater than
    * @return the index of the point greater than the given minimum index
    *
-   * @see project
+   * @see #project(Coordinate)
    */
   public LinearLocation indexOfAfter(Coordinate pt, LinearLocation minIndex)
   {
@@ -154,7 +187,7 @@ public class LocationIndexedLine
 
   /**
    * Returns the index of the start of the line
-   * @return
+   * @return the location index
    */
   public LinearLocation getStartIndex()
   {
@@ -163,7 +196,7 @@ public class LocationIndexedLine
 
   /**
    * Returns the index of the end of the line
-   * @return
+   * @return the location index
    */
   public LinearLocation getEndIndex()
   {
@@ -173,7 +206,7 @@ public class LocationIndexedLine
   /**
    * Tests whether an index is in the valid index range for the line.
    *
-   * @param length the index to test
+   * @param index the index to test
    * @return <code>true</code> if the index is in the valid range
    */
   public boolean isValidIndex(LinearLocation index)
@@ -193,4 +226,4 @@ public class LocationIndexedLine
     loc.clamp(linearGeom);
     return loc;
   }
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/math/DD.java b/src/com/vividsolutions/jts/math/DD.java
index ec23e72..db77911 100644
--- a/src/com/vividsolutions/jts/math/DD.java
+++ b/src/com/vividsolutions/jts/math/DD.java
@@ -258,20 +258,22 @@ public strictfp final class DD
     }
   }
   
-  private void init(double x)
+  private final void init(double x)
   {
-    init(x, 0.0);
+    this.hi = x;
+    this.lo = 0.0;
   }
   
-  private void init(double hi, double lo)
+  private final void init(double hi, double lo)
   {
     this.hi = hi;
     this.lo = lo;   
   }
   
-  private void init(DD dd)
+  private final void init(DD dd)
   {
-    init(dd.hi, dd.lo); 
+    hi = dd.hi;
+    lo = dd.lo;
   }
   
   /*
@@ -297,7 +299,7 @@ public strictfp final class DD
    * @param y the addend
    * @return <tt>(this + y)</tt>
    */ 
-  public DD add(DD y)
+  public final DD add(DD y)
   {
     return copy(this).selfAdd(y);
   }
@@ -308,7 +310,7 @@ public strictfp final class DD
    * @param y the addend
    * @return <tt>(this + y)</tt>
    */ 
-  public DD add(double y)
+  public final DD add(double y)
   {
     return copy(this).selfAdd(y);
   }
@@ -322,7 +324,7 @@ public strictfp final class DD
    * @param y the addend
    * @return this object, increased by y
    */
-  public DD selfAdd(DD y)
+  public final DD selfAdd(DD y)
   {
     return selfAdd(y.hi, y.lo);
   }
@@ -336,12 +338,23 @@ public strictfp final class DD
    * @param y the addend
    * @return this object, increased by y
    */
-  public DD selfAdd(double y)
-  {
-    return selfAdd(y, 0.0);
+  public final DD selfAdd(double y)
+  {
+    double H, h, S, s, e, f;
+    S = hi + y;
+    e = S - hi;
+    s = S - e;
+    s = (y - e) + (hi - s);
+    f = s + lo;
+    H = S + f;
+    h = f + (S - H);
+    hi = H + h;
+    lo = h + (H - hi);
+    return this;
+    // return selfAdd(y, 0.0);
   }
   
-  private DD selfAdd(double yhi, double ylo)
+  private final DD selfAdd(double yhi, double ylo)
   {
     double H, h, T, t, S, s, e, f;
     S = hi + yhi; 
@@ -367,7 +380,7 @@ public strictfp final class DD
    * @param y the subtrahend
    * @return <tt>(this - y)</tt>
    */
-  public DD subtract(DD y)
+  public final DD subtract(DD y)
   {
     return add(y.negate());
   }
@@ -378,7 +391,7 @@ public strictfp final class DD
    * @param y the subtrahend
    * @return <tt>(this - y)</tt>
    */
-  public DD subtract(double y)
+  public final DD subtract(double y)
   {
     return add(-y);
   }
@@ -393,7 +406,7 @@ public strictfp final class DD
    * @param y the addend
    * @return this object, decreased by y
    */
-  public DD selfSubtract(DD y)
+  public final DD selfSubtract(DD y)
   {
     if (isNaN()) return this;
     return selfAdd(-y.hi, -y.lo);
@@ -408,7 +421,7 @@ public strictfp final class DD
    * @param y the addend
    * @return this object, decreased by y
    */
-  public DD selfSubtract(double y)
+  public final DD selfSubtract(double y)
   {
     if (isNaN()) return this;
     return selfAdd(-y, 0.0);
@@ -419,7 +432,7 @@ public strictfp final class DD
    * 
    * @return <tt>-this</tt>
    */
-  public DD negate()
+  public final DD negate()
   {
     if (isNaN()) return this;
     return new DD(-hi, -lo);
@@ -431,7 +444,7 @@ public strictfp final class DD
    * @param y the multiplicand
    * @return <tt>(this * y)</tt>
    */
-  public DD multiply(DD y)
+  public final DD multiply(DD y)
   {
     if (y.isNaN()) return createNaN();
     return copy(this).selfMultiply(y);
@@ -443,7 +456,7 @@ public strictfp final class DD
    * @param y the multiplicand
    * @return <tt>(this * y)</tt>
    */
-  public DD multiply(double y)
+  public final DD multiply(double y)
   {
     if (Double.isNaN(y)) return createNaN();
     return copy(this).selfMultiply(y, 0.0);
@@ -458,7 +471,7 @@ public strictfp final class DD
    * @param y the value to multiply by
    * @return this object, multiplied by y
    */
-  public DD selfMultiply(DD y)
+  public final DD selfMultiply(DD y)
   {
     return selfMultiply(y.hi, y.lo);
   }
@@ -472,12 +485,12 @@ public strictfp final class DD
    * @param y the value to multiply by
    * @return this object, multiplied by y
    */
-  public DD selfMultiply(double y)
+  public final DD selfMultiply(double y)
   {
     return selfMultiply(y, 0.0);
   }
   
-  private DD selfMultiply(double yhi, double ylo)
+  private final DD selfMultiply(double yhi, double ylo)
   {
     double hx, tx, hy, ty, C, c;
     C = SPLIT * hi; hx = C-hi; c = SPLIT * yhi;
@@ -497,7 +510,7 @@ public strictfp final class DD
    * @param y the divisor
    * @return a new object with the value <tt>(this / y)</tt>
    */
-  public DD divide(DD y)
+  public final DD divide(DD y)
   {
     double hc, tc, hy, ty, C, c, U, u;
     C = hi/y.hi; c = SPLIT*C; hc =c-C;  u = SPLIT*y.hi; hc = c-hc;
@@ -517,7 +530,7 @@ public strictfp final class DD
    * @param y the divisor
    * @return a new object with the value <tt>(this / y)</tt>
    */
-  public DD divide(double y)
+  public final DD divide(double y)
   {
     if (Double.isNaN(y)) return createNaN();
     return copy(this).selfDivide(y, 0.0);  
@@ -532,7 +545,7 @@ public strictfp final class DD
    * @param y the value to divide by
    * @return this object, divided by y
    */
-  public DD selfDivide(DD y)
+  public final DD selfDivide(DD y)
   {
     return selfDivide(y.hi, y.lo);
   }
@@ -546,12 +559,12 @@ public strictfp final class DD
    * @param y the value to divide by
    * @return this object, divided by y
    */
-  public DD selfDivide(double y)
+  public final DD selfDivide(double y)
   {
     return selfDivide(y, 0.0);
   }
   
-  private DD selfDivide(double yhi, double ylo)
+  private final DD selfDivide(double yhi, double ylo)
   {
     double hc, tc, hy, ty, C, c, U, u;
     C = hi/yhi; c = SPLIT*C; hc =c-C;  u = SPLIT*yhi; hc = c-hc;
@@ -570,7 +583,7 @@ public strictfp final class DD
    * 
    * @return the reciprocal of this value
    */
-  public DD reciprocal()
+  public final DD reciprocal()
   {
     double  hc, tc, hy, ty, C, c, U, u;
     C = 1.0/hi; 
@@ -649,8 +662,10 @@ public strictfp final class DD
    */
   public int signum()
   {
-    if (isPositive()) return 1;
-    if (isNegative()) return -1;
+    if (hi > 0) return 1;
+    if (hi < 0) return -1;
+    if (lo > 0) return 1;
+    if (lo < 0) return -1;
     return 0;
   }
   
@@ -805,6 +820,42 @@ public strictfp final class DD
     return s;
   }
   
+  
+  /*------------------------------------------------------------
+   *   Ordering Functions
+   *------------------------------------------------------------
+   */
+
+  /**
+   * Computes the minimum of this and another DD number.
+   * 
+   * @param x a DD number
+   * @return the minimum of the two numbers
+   */
+  public DD min(DD x) {
+    if (this.le(x)) {
+      return this;
+    }
+    else {
+      return x;
+    }
+  }
+  
+  /**
+   * Computes the maximum of this and another DD number.
+   * 
+   * @param x a DD number
+   * @return the maximum of the two numbers
+   */
+  public DD max(DD x) {
+    if (this.ge(x)) {
+      return this;
+    }
+    else {
+      return x;
+    }
+  }
+
   /*------------------------------------------------------------
    *   Conversion Functions
    *------------------------------------------------------------
@@ -1163,7 +1214,7 @@ public strictfp final class DD
    * (E.g. NaN or 0.0)
    * 
    * @return the string for this special number
-   * @return null if the number is not a special number
+   * or null if the number is not a special number
    */
   private String getSpecialNumberString()
   {
diff --git a/src/com/vividsolutions/jts/math/MathUtil.java b/src/com/vividsolutions/jts/math/MathUtil.java
index 0935a5f..d0587bd 100644
--- a/src/com/vividsolutions/jts/math/MathUtil.java
+++ b/src/com/vividsolutions/jts/math/MathUtil.java
@@ -89,5 +89,58 @@ public class MathUtil
     return ln / LOG_10;
   }
   
+  /**
+   * Computes an index which wraps around a given maximum value.
+   * For values >= 0, this is equals to <tt>val % max</tt>.
+   * For values < 0, this is equal to <tt>max - (-val) % max</tt> 
+   * 
+   * @param index the value to wrap
+   * @param max the maximum value (or modulus)
+   * @return the wrapped index
+   */
+  public static int wrap(int index, int max)
+  {
+    if (index < 0) {
+      return max - ((-index) % max);
+    }
+    return index % max;
+  }
 
+  /**
+   * Computes the average of two numbers.
+   * 
+   * @param x1 a number
+   * @param x2 a number
+   * @return the average of the inputs
+   */
+  public static double average(double x1, double x2)
+  {
+    return (x1 + x2) / 2.0;
+  }
+  
+  public static double max(double v1, double v2, double v3)
+  {
+    double max = v1;
+    if (v2 > max) max = v2;
+    if (v3 > max) max = v3;
+    return max;
+  }
+  
+  public static double max(double v1, double v2, double v3, double v4)
+  {
+    double max = v1;
+    if (v2 > max) max = v2;
+    if (v3 > max) max = v3;
+    if (v4 > max) max = v4;
+    return max;
+  }
+  
+  public static double min(double v1, double v2, double v3, double v4)
+  {
+    double min = v1;
+    if (v2 < min) min = v2;
+    if (v3 < min) min = v3;
+    if (v4 < min) min = v4;
+    return min;
+  }
 }
diff --git a/src/com/vividsolutions/jts/math/Matrix.java b/src/com/vividsolutions/jts/math/Matrix.java
index 6e1d887..741351a 100644
--- a/src/com/vividsolutions/jts/math/Matrix.java
+++ b/src/com/vividsolutions/jts/math/Matrix.java
@@ -68,7 +68,7 @@ public class Matrix
    * @param b a vector of length n
    * 
    * @return a vector containing the solution (if any)
-   * @return null if the system has no or no unique solution
+   * or null if the system has no or no unique solution
    * 
    * @throws IllegalArgumentException if the matrix is the wrong size 
    */
diff --git a/src/com/vividsolutions/jts/math/Plane3D.java b/src/com/vividsolutions/jts/math/Plane3D.java
new file mode 100644
index 0000000..e28fcbf
--- /dev/null
+++ b/src/com/vividsolutions/jts/math/Plane3D.java
@@ -0,0 +1,112 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
+package com.vividsolutions.jts.math;
+
+import com.vividsolutions.jts.geom.Coordinate;
+
+/**
+ * Models a plane in 3-dimensional Cartesian space.
+ * 
+ * @author mdavis
+ *
+ */
+public class Plane3D {
+	
+	/**
+	 * Enums for the 3 coordinate planes
+	 */
+	public static final int XY_PLANE = 1;
+	public static final int YZ_PLANE = 2;
+	public static final int XZ_PLANE = 3;
+	
+	private Vector3D normal;
+	private Coordinate basePt;
+
+	public Plane3D(Vector3D normal, Coordinate basePt)
+	{
+		this.normal = normal;
+		this.basePt = basePt;
+	}
+	
+	/**
+	 * Computes the oriented distance from a point to the plane.
+	 * The distance is:
+	 * <ul>
+	 * <li><b>positive</b> if the point lies above the plane (relative to the plane normal)
+	 * <li><b>zero</b> if the point is on the plane
+	 * <li><b>negative</b> if the point lies below the plane (relative to the plane normal)
+	 * </ul> 
+	 * 
+	 * @param p the point to compute the distance for
+	 * @return the oriented distance to the plane
+	 */
+	public double orientedDistance(Coordinate p) {
+		Vector3D pb = new Vector3D(p, basePt);
+		double pbdDotNormal = pb.dot(normal);
+		if (Double.isNaN(pbdDotNormal)) 
+			throw new IllegalArgumentException("3D Coordinate has NaN ordinate");
+		double d = pbdDotNormal / normal.length();
+		return d;
+	}
+
+	/**
+	 * Computes the axis plane that this plane lies closest to.
+	 * <p>
+	 * Geometries lying in this plane undergo least distortion
+	 * (and have maximum area)
+	 * when projected to the closest axis plane.
+	 * This provides optimal conditioning for
+	 * computing a Point-in-Polygon test.
+	 *  
+	 * @return the index of the closest axis plane.
+	 */
+	public int closestAxisPlane() {
+		double xmag = Math.abs(normal.getX());
+		double ymag = Math.abs(normal.getY());
+		double zmag = Math.abs(normal.getZ());
+		if (xmag > ymag) {
+			if (xmag > zmag)
+				return YZ_PLANE;
+			else
+				return XY_PLANE;
+		}
+		// y >= x
+		else if (zmag > ymag) {
+			return XY_PLANE;
+		}
+		// y >= z
+		return XZ_PLANE;
+	}
+
+}
diff --git a/src/com/vividsolutions/jts/math/Vector2D.java b/src/com/vividsolutions/jts/math/Vector2D.java
index 14e24e0..4541e27 100644
--- a/src/com/vividsolutions/jts/math/Vector2D.java
+++ b/src/com/vividsolutions/jts/math/Vector2D.java
@@ -179,7 +179,7 @@ public class Vector2D {
 	public Vector2D normalize() {
 		double length = length();
 		if (length > 0.0)
-			return divide(length());
+			return divide(length);
 		return create(0.0, 0.0);
 	}
 
@@ -187,6 +187,21 @@ public class Vector2D {
 		return weightedSum(v, 0.5);
 	}
   
+	/**
+	 * Computes the weighted sum of this vector
+	 * with another vector,
+	 * with this vector contributing a fraction
+	 * of <tt>frac</tt> to the total.
+	 * <p>
+	 * In other words, 
+	 * <pre>
+	 * sum = frac * this + (1 - frac) * v
+	 * </pre>
+	 * 
+	 * @param v the vector to sum
+	 * @param frac the fraction of the total contributed by this vector
+	 * @return the weighted sum of the two vectors
+	 */
 	public Vector2D weightedSum(Vector2D v, double frac) {
 		return create(
 				frac * x + (1.0 - frac) * v.x, 
diff --git a/src/com/vividsolutions/jts/math/Vector3D.java b/src/com/vividsolutions/jts/math/Vector3D.java
new file mode 100644
index 0000000..f9efdb1
--- /dev/null
+++ b/src/com/vividsolutions/jts/math/Vector3D.java
@@ -0,0 +1,182 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
+package com.vividsolutions.jts.math;
+
+import com.vividsolutions.jts.geom.Coordinate;
+
+/**
+ * Represents a vector in 3-dimensional Cartesian space.
+ * 
+ * @author mdavis
+ *
+ */
+public class Vector3D {
+	
+	/**
+	 * Computes the dot product of the 3D vectors AB and CD.
+	 * 
+	 * @param A
+	 * @param B
+	 * @param C
+	 * @param D
+	 * @return the dot product
+	 */
+	public static double dot(Coordinate A, Coordinate B, Coordinate C, Coordinate D)
+	{
+		double ABx = B.x - A.x;
+		double ABy = B.y - A.y;
+		double ABz = B.z - A.z;
+		double CDx = D.x - C.x;
+		double CDy = D.y - C.y;
+		double CDz = D.z - C.z;
+		return ABx*CDx + ABy*CDy + ABz*CDz;
+	}
+
+	/**
+	 * Creates a new vector with given X and Y components.
+	 * 
+	 * @param x
+	 *            the x component
+	 * @param y
+	 *            the y component
+	 * @param z
+	 *            the z component
+	 * @return a new vector
+	 */
+	public static Vector3D create(double x, double y, double z) {
+		return new Vector3D(x, y, z);
+	}
+
+	/**
+	 * Creates a vector from a {@link Coordinate}.
+	 * 
+	 * @param coord
+	 *            the Coordinate to copy
+	 * @return a new vector
+	 */
+	public static Vector3D create(Coordinate coord) {
+		return new Vector3D(coord);
+	}
+
+	public Vector3D(Coordinate v) {
+		x = v.x;
+		y = v.y;
+		z = v.z;
+	}
+
+	/**
+	 * Computes the 3D dot-product of two {@link Coordinate}s.
+	 * 
+   * @param v1 the first vector
+   * @param v2 the second vector
+	 * @return the dot product of the vectors
+	 */
+	public static double dot(Coordinate v1, Coordinate v2) {
+		return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
+	}
+
+	private double x;
+	private double y;
+	private double z;
+
+	public Vector3D(Coordinate from, Coordinate to) {
+		x = to.x - from.x;
+		y = to.y - from.y;
+		z = to.z - from.z;
+	}
+
+	public Vector3D(double x, double y, double z) {
+		this.x = x;
+		this.y = y;
+		this.z = z;
+	}
+
+	public double getX() {
+		return x;
+	}
+
+	public double getY() {
+		return y;
+	}
+
+	public double getZ() {
+		return z;
+	}
+
+
+	/**
+	 * Computes the dot-product of two vectors
+	 * 
+	 * @param v
+	 *            a vector
+	 * @return the dot product of the vectors
+	 */
+	public double dot(Vector3D v) {
+		return x * v.x + y * v.y + z * v.z;
+	}
+
+	public double length() {
+		return Math.sqrt(x * x + y * y + z * z);
+	}
+
+	public static double length(Coordinate v) {
+		return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
+	}
+
+	public Vector3D normalize() {
+		double length = length();
+		if (length > 0.0)
+			return divide(length());
+		return create(0.0, 0.0, 0.0);
+	}
+
+	private Vector3D divide(double d) {
+		return create(x / d, y / d, z / d);
+	}
+
+	public static Coordinate normalize(Coordinate v) {
+		double len = length(v);
+		return new Coordinate(v.x / len, v.y / len, v.z / len);
+	}
+	  /**
+	   * Gets a string representation of this vector
+	   * 
+	   * @return a string representing this vector
+	   */
+		public String toString() {
+			return "[" + x + ", " + y + ", " + z + "]";
+		}
+		
+
+}
diff --git a/src/com/vividsolutions/jts/noding/BasicSegmentString.java b/src/com/vividsolutions/jts/noding/BasicSegmentString.java
index e2ae556..66f94ff 100644
--- a/src/com/vividsolutions/jts/noding/BasicSegmentString.java
+++ b/src/com/vividsolutions/jts/noding/BasicSegmentString.java
@@ -36,6 +36,8 @@ package com.vividsolutions.jts.noding;
 import java.util.*;
 import com.vividsolutions.jts.algorithm.LineIntersector;
 import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.impl.CoordinateArraySequence;
+import com.vividsolutions.jts.io.WKTWriter;
 
 /**
  * Represents a list of contiguous line segments,
@@ -103,4 +105,8 @@ public class BasicSegmentString
     return Octant.octant(getCoordinate(index), getCoordinate(index + 1));
   }
 
+  public String toString()
+  {
+    return WKTWriter.toLineString(new CoordinateArraySequence(pts));
+  }
 }
diff --git a/src/com/vividsolutions/jts/noding/FastNodingValidator.java b/src/com/vividsolutions/jts/noding/FastNodingValidator.java
index 653801e..b09dfbf 100644
--- a/src/com/vividsolutions/jts/noding/FastNodingValidator.java
+++ b/src/com/vividsolutions/jts/noding/FastNodingValidator.java
@@ -44,13 +44,17 @@ import com.vividsolutions.jts.io.*;
  * Validates that a collection of {@link SegmentString}s is correctly noded.
  * Indexing is used to improve performance.
  * In the most common use case, validation stops after a single 
- * non-noded intersection is detected.
- * Does NOT check a-b-a collapse situations. 
- * Also does not check for endpoint-interior vertex intersections.
- * This should not be a problem, since the noders should be
+ * non-noded intersection is detected, 
+ * but the class can be requested to detect all intersections
+ * by using the {@link #setFindAllIntersections(boolean)} method.
+ * <p>
+ * The validator does not check for a-b-a topology collapse situations.
+ * <p> 
+ * The validator does not check for endpoint-interior vertex intersections.
+ * This should not be a problem, since the JTS noders should be
  * able to compute intersections between vertices correctly.
  * <p>
- * The client may either test the {@link #isValid} condition, 
+ * The client may either test the {@link #isValid()} condition, 
  * or request that a suitable {@link TopologyException} be thrown.
  *
  * @version 1.7
diff --git a/src/com/vividsolutions/jts/noding/FastSegmentSetIntersectionFinder.java b/src/com/vividsolutions/jts/noding/FastSegmentSetIntersectionFinder.java
index c8b5fc2..3562bb1 100644
--- a/src/com/vividsolutions/jts/noding/FastSegmentSetIntersectionFinder.java
+++ b/src/com/vividsolutions/jts/noding/FastSegmentSetIntersectionFinder.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.noding;
 
 import java.util.*;
diff --git a/src/com/vividsolutions/jts/noding/InteriorIntersectionFinder.java b/src/com/vividsolutions/jts/noding/InteriorIntersectionFinder.java
index cfa7b7d..6ccaf30 100644
--- a/src/com/vividsolutions/jts/noding/InteriorIntersectionFinder.java
+++ b/src/com/vividsolutions/jts/noding/InteriorIntersectionFinder.java
@@ -126,7 +126,7 @@ public class InteriorIntersectionFinder
    * This method is called by clients
    * of the {@link SegmentIntersector} class to process
    * intersections for two segments of the {@link SegmentString}s being intersected.
-   * Note that some clients (such as {@link MonotoneChain}s) may optimize away
+   * Note that some clients (such as <code>MonotoneChain</code>s) may optimize away
    * this call for segment pairs which they have determined do not intersect
    * (e.g. by an disjoint envelope test).
    */
diff --git a/src/com/vividsolutions/jts/noding/IntersectionAdder.java b/src/com/vividsolutions/jts/noding/IntersectionAdder.java
index 947bb46..694e221 100644
--- a/src/com/vividsolutions/jts/noding/IntersectionAdder.java
+++ b/src/com/vividsolutions/jts/noding/IntersectionAdder.java
@@ -41,7 +41,7 @@ import com.vividsolutions.jts.util.Debug;
  * Computes the intersections between two line segments in {@link SegmentString}s
  * and adds them to each string.
  * The {@link SegmentIntersector} is passed to a {@link Noder}.
- * The {@link addIntersections} method is called whenever the {@link Noder}
+ * The {@link SegmentIntersector#processIntersections(SegmentString, int, SegmentString, int)} method is called whenever the {@link Noder}
  * detects that two SegmentStrings <i>might</i> intersect.
  * This class is an example of the <i>Strategy</i> pattern.
  *
@@ -137,7 +137,7 @@ public class IntersectionAdder
    * This method is called by clients
    * of the {@link SegmentIntersector} class to process
    * intersections for two segments of the {@link SegmentString}s being intersected.
-   * Note that some clients (such as {@link MonotoneChain}s) may optimize away
+   * Note that some clients (such as <code>MonotoneChain</code>s) may optimize away
    * this call for segment pairs which they have determined do not intersect
    * (e.g. by an disjoint envelope test).
    */
diff --git a/src/com/vividsolutions/jts/noding/IntersectionFinderAdder.java b/src/com/vividsolutions/jts/noding/IntersectionFinderAdder.java
index 1dba8e4..eec1059 100644
--- a/src/com/vividsolutions/jts/noding/IntersectionFinderAdder.java
+++ b/src/com/vividsolutions/jts/noding/IntersectionFinderAdder.java
@@ -67,7 +67,7 @@ public class IntersectionFinderAdder
    * This method is called by clients
    * of the {@link SegmentIntersector} class to process
    * intersections for two segments of the {@link SegmentString}s being intersected.
-   * Note that some clients (such as {@link MonotoneChain}s) may optimize away
+   * Note that some clients (such as <code>MonotoneChain</code>s) may optimize away
    * this call for segment pairs which they have determined do not intersect
    * (e.g. by an disjoint envelope test).
    */
diff --git a/src/com/vividsolutions/jts/noding/IteratedNoder.java b/src/com/vividsolutions/jts/noding/IteratedNoder.java
index 1d7a4d2..ea4af5f 100644
--- a/src/com/vividsolutions/jts/noding/IteratedNoder.java
+++ b/src/com/vividsolutions/jts/noding/IteratedNoder.java
@@ -90,7 +90,6 @@ public class IteratedNoder
    * the noding.
    *
    * @param segStrings a collection of SegmentStrings to be noded
-   * @return a collection of the noded SegmentStrings
    * @throws TopologyException if the iterated noding fails to converge.
    */
   public void computeNodes(Collection segStrings)
diff --git a/src/com/vividsolutions/jts/noding/MCIndexNoder.java b/src/com/vividsolutions/jts/noding/MCIndexNoder.java
index bfb22ad..d76fbef 100644
--- a/src/com/vividsolutions/jts/noding/MCIndexNoder.java
+++ b/src/com/vividsolutions/jts/noding/MCIndexNoder.java
@@ -42,7 +42,7 @@ import java.util.*;
  * Nodes a set of {@link SegmentString}s using a index based
  * on {@link MonotoneChain}s and a {@link SpatialIndex}.
  * The {@link SpatialIndex} used should be something that supports
- * envelope (range) queries efficiently (such as a {@link Quadtree}
+ * envelope (range) queries efficiently (such as a <code>Quadtree</code>}
  * or {@link STRtree} (which is the default index provided).
  *
  * @version 1.7
@@ -60,6 +60,10 @@ public class MCIndexNoder
   public MCIndexNoder()
   {
   }
+  public MCIndexNoder(SegmentIntersector si)
+  {
+    super(si);
+  }
 
   public List getMonotoneChains() { return monoChains; }
 
diff --git a/src/com/vividsolutions/jts/noding/MCIndexSegmentSetMutualIntersector.java b/src/com/vividsolutions/jts/noding/MCIndexSegmentSetMutualIntersector.java
index b23b2e4..2a6833e 100644
--- a/src/com/vividsolutions/jts/noding/MCIndexSegmentSetMutualIntersector.java
+++ b/src/com/vividsolutions/jts/noding/MCIndexSegmentSetMutualIntersector.java
@@ -50,7 +50,6 @@ import com.vividsolutions.jts.noding.SegmentString;
 public class MCIndexSegmentSetMutualIntersector
     extends SegmentSetMutualIntersector
 {
-  private List monoChains = new ArrayList();
   /*
   * The {@link SpatialIndex} used should be something that supports
   * envelope (range) queries efficiently (such as a {@link Quadtree}
@@ -66,8 +65,6 @@ public class MCIndexSegmentSetMutualIntersector
   {
   }
 
-  public List getMonotoneChains() { return monoChains; }
-
   public SpatialIndex getIndex() { return index; }
 
   
@@ -92,16 +89,16 @@ public class MCIndexSegmentSetMutualIntersector
   {
   	processCounter = indexCounter + 1;
   	nOverlaps = 0;
-  	monoChains.clear();
+  	List monoChains = new ArrayList();
     for (Iterator i = segStrings.iterator(); i.hasNext(); ) {
-      addToMonoChains((SegmentString) i.next());
+      addToMonoChains((SegmentString) i.next(), monoChains);
     }
-    intersectChains();
+    intersectChains(monoChains);
 //    System.out.println("MCIndexBichromaticIntersector: # chain overlaps = " + nOverlaps);
 //    System.out.println("MCIndexBichromaticIntersector: # oct chain overlaps = " + nOctOverlaps);
   }
 
-  private void intersectChains()
+  private void intersectChains(List monoChains)
   {
     MonotoneChainOverlapAction overlapAction = new SegmentOverlapAction(segInt);
 
@@ -117,7 +114,7 @@ public class MCIndexSegmentSetMutualIntersector
     }
   }
 
-  private void addToMonoChains(SegmentString segStr)
+  private void addToMonoChains(SegmentString segStr, List monoChains)
   {
     List segChains = MonotoneChainBuilder.getChains(segStr.getCoordinates(), segStr);
     for (Iterator i = segChains.iterator(); i.hasNext(); ) {
diff --git a/src/com/vividsolutions/jts/noding/NodableSegmentString.java b/src/com/vividsolutions/jts/noding/NodableSegmentString.java
index 94a303f..beafc1a 100644
--- a/src/com/vividsolutions/jts/noding/NodableSegmentString.java
+++ b/src/com/vividsolutions/jts/noding/NodableSegmentString.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.noding;
 
 import com.vividsolutions.jts.geom.Coordinate;
diff --git a/src/com/vividsolutions/jts/noding/NodedSegmentString.java b/src/com/vividsolutions/jts/noding/NodedSegmentString.java
index fe9d93f..f834cfb 100644
--- a/src/com/vividsolutions/jts/noding/NodedSegmentString.java
+++ b/src/com/vividsolutions/jts/noding/NodedSegmentString.java
@@ -55,6 +55,7 @@ public class NodedSegmentString
 	implements NodableSegmentString
 {
 	/**
+	 * Gets the {@link SegmentString}s which result from splitting this string at node points.
 	 * 
 	 * @param segStrings a Collection of NodedSegmentStrings
 	 * @return a Collection of NodedSegmentStrings representing the substrings
@@ -67,6 +68,7 @@ public class NodedSegmentString
   }
 
 	/**
+	 * Adds the noded {@link SegmentString}s which result from splitting this string at node points.
 	 * 
 	 * @param segStrings a Collection of NodedSegmentStrings
 	 * @param resultEdgelist a List which will collect the NodedSegmentStrings representing the substrings
diff --git a/src/com/vividsolutions/jts/noding/Octant.java b/src/com/vividsolutions/jts/noding/Octant.java
index d79c83e..c247ff6 100644
--- a/src/com/vividsolutions/jts/noding/Octant.java
+++ b/src/com/vividsolutions/jts/noding/Octant.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.noding;
 
 import com.vividsolutions.jts.geom.Coordinate;
@@ -74,4 +107,4 @@ public class Octant {
 
   private Octant() {
   }
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/noding/OrientedCoordinateArray.java b/src/com/vividsolutions/jts/noding/OrientedCoordinateArray.java
index 72080f4..4e51155 100644
--- a/src/com/vividsolutions/jts/noding/OrientedCoordinateArray.java
+++ b/src/com/vividsolutions/jts/noding/OrientedCoordinateArray.java
@@ -65,7 +65,7 @@ public class OrientedCoordinateArray
    *
    * @param pts the array to test
    * @return <code>true</code> if the points are oriented forwards
-   * @return <code>false</code if the points are oriented in reverse
+   * or <code>false</code if the points are oriented in reverse
    */
   private static boolean orientation(Coordinate[] pts)
   {
@@ -75,9 +75,9 @@ public class OrientedCoordinateArray
   /**
    * Compares two {@link OrientedCoordinateArray}s for their relative order
    *
-   * @return -1 this one is smaller
-   * @return 0 the two objects are equal
-   * @return 1 this one is greater
+   * @return -1 this one is smaller;
+   * 0 the two objects are equal;
+   * 1 this one is greater
    */
 
   public int compareTo(Object o1) {
diff --git a/src/com/vividsolutions/jts/noding/ScaledNoder.java b/src/com/vividsolutions/jts/noding/ScaledNoder.java
index 447a4c9..fac9b32 100644
--- a/src/com/vividsolutions/jts/noding/ScaledNoder.java
+++ b/src/com/vividsolutions/jts/noding/ScaledNoder.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.noding;
 
 import java.util.*;
@@ -11,6 +44,11 @@ import com.vividsolutions.jts.util.*;
  * This is intended for use with Snap-Rounding noders,
  * which typically are only intended to work in the integer domain.
  * Offsets can be provided to increase the number of digits of available precision.
+ * <p>
+ * Clients should be aware that rescaling can involve loss of precision,
+ * which can cause zero-length line segments to be created.
+ * These in turn can cause problems when used to build a planar graph.
+ * This situation should be checked for and collapsed segments removed if necessary.
  *
  * @version 1.7
  */
@@ -70,7 +108,8 @@ public class ScaledNoder
     for (int i = 0; i < pts.length; i++) {
       roundPts[i] = new Coordinate(
           Math.round((pts[i].x - offsetX) * scaleFactor),
-          Math.round((pts[i].y - offsetY) * scaleFactor)
+          Math.round((pts[i].y - offsetY) * scaleFactor),
+          pts[i].z
         );
     }
     Coordinate[] roundPtsNoDup = CoordinateArrays.removeRepeatedPoints(roundPts);
@@ -95,11 +134,23 @@ public class ScaledNoder
 
   private void rescale(Coordinate[] pts)
   {
+    Coordinate p0 = null;
+    Coordinate p1 = null;
+    
+    if (pts.length == 2) {
+      p0 = new Coordinate(pts[0]);
+      p1 = new Coordinate(pts[1]);
+    }
+
     for (int i = 0; i < pts.length; i++) {
       pts[i].x = pts[i].x / scaleFactor + offsetX;
       pts[i].y = pts[i].y / scaleFactor + offsetY;
     }
+    
+    if (pts.length == 2 && pts[0].equals2D(pts[1])) {
+      System.out.println(pts);
+    }
   }
 
   //private double rescale(double val) { return val / scaleFactor; }
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/noding/SegmentIntersectionDetector.java b/src/com/vividsolutions/jts/noding/SegmentIntersectionDetector.java
index 5a1be70..529bf2c 100644
--- a/src/com/vividsolutions/jts/noding/SegmentIntersectionDetector.java
+++ b/src/com/vividsolutions/jts/noding/SegmentIntersectionDetector.java
@@ -138,7 +138,7 @@ public class SegmentIntersectionDetector
    * This method is called by clients
    * of the {@link SegmentIntersector} class to process
    * intersections for two segments of the {@link SegmentString}s being intersected.
-   * Note that some clients (such as {@link MonotoneChain}s) may optimize away
+   * Note that some clients (such as <code>MonotoneChain</code>s) may optimize away
    * this call for segment pairs which they have determined do not intersect
    * (e.g. by an disjoint envelope test).
    */
diff --git a/src/com/vividsolutions/jts/noding/SegmentIntersector.java b/src/com/vividsolutions/jts/noding/SegmentIntersector.java
index 6bd8a46..4a122dc 100644
--- a/src/com/vividsolutions/jts/noding/SegmentIntersector.java
+++ b/src/com/vividsolutions/jts/noding/SegmentIntersector.java
@@ -40,12 +40,12 @@ import com.vividsolutions.jts.util.Debug;
 /**
  * Processes possible intersections detected by a {@link Noder}.
  * The {@link SegmentIntersector} is passed to a {@link Noder}.
- * The {@link addIntersections} method is called whenever the {@link Noder}
+ * The {@link SegmentIntersector#processIntersections(SegmentString, int, SegmentString, int)} method is called whenever the {@link Noder}
  * detects that two SegmentStrings <i>might</i> intersect.
  * This class may be used either to find all intersections, or
  * to detect the presence of an intersection.  In the latter case,
  * Noders may choose to short-circuit their computation by calling the
- * {@link isDone} method.
+ * {@link #isDone()} method.
  * This class is an example of the <i>Strategy</i> pattern.
  *
  * @version 1.7
diff --git a/src/com/vividsolutions/jts/noding/SegmentNode.java b/src/com/vividsolutions/jts/noding/SegmentNode.java
index 93f311e..0f06885 100644
--- a/src/com/vividsolutions/jts/noding/SegmentNode.java
+++ b/src/com/vividsolutions/jts/noding/SegmentNode.java
@@ -57,6 +57,16 @@ public class SegmentNode
     isInterior = ! coord.equals2D(segString.getCoordinate(segmentIndex));
   }
 
+  /**
+   * Gets the {@link Coordinate} giving the location of this node.
+   * 
+   * @return the coordinate of the node
+   */
+  public Coordinate getCoordinate() 
+  {
+    return coord;
+  }
+  
   public boolean isInterior() { return isInterior; }
 
   public boolean isEndPoint(int maxSegmentIndex)
@@ -67,9 +77,9 @@ public class SegmentNode
   }
 
   /**
-   * @return -1 this SegmentNode is located before the argument location
-   * @return 0 this SegmentNode is at the argument location
-   * @return 1 this SegmentNode is located after the argument location
+   * @return -1 this SegmentNode is located before the argument location;
+   * 0 this SegmentNode is at the argument location;
+   * 1 this SegmentNode is located after the argument location
    */
   public int compareTo(Object obj)
   {
diff --git a/src/com/vividsolutions/jts/noding/SegmentNodeList.java b/src/com/vividsolutions/jts/noding/SegmentNodeList.java
index 4d91784..a5e32e0 100644
--- a/src/com/vividsolutions/jts/noding/SegmentNodeList.java
+++ b/src/com/vividsolutions/jts/noding/SegmentNodeList.java
@@ -191,6 +191,10 @@ public class SegmentNodeList
     while (it.hasNext()) {
       SegmentNode ei = (SegmentNode) it.next();
       SegmentString newEdge = createSplitEdge(eiPrev, ei);
+      /*
+      if (newEdge.size() < 2)
+        throw new RuntimeException("created single point edge: " + newEdge.toString());
+      */
       edgeList.add(newEdge);
       eiPrev = ei;
     }
@@ -198,7 +202,7 @@ public class SegmentNodeList
   }
 
   /**
-   * Checks the correctness of the set of split edges corresponding to this edge
+   * Checks the correctness of the set of split edges corresponding to this edge.
    *
    * @param splitEdges the split edges for this edge (in order)
    */
diff --git a/src/com/vividsolutions/jts/noding/SegmentPointComparator.java b/src/com/vividsolutions/jts/noding/SegmentPointComparator.java
index 4ea11df..192ea4f 100644
--- a/src/com/vividsolutions/jts/noding/SegmentPointComparator.java
+++ b/src/com/vividsolutions/jts/noding/SegmentPointComparator.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.noding;
 
 import com.vividsolutions.jts.geom.Coordinate;
@@ -20,9 +53,9 @@ public class SegmentPointComparator {
    * Compares two {@link Coordinate}s for their relative position along a segment
    * lying in the specified {@link Octant}.
    *
-   * @return -1 node0 occurs first
-   * @return 0 the two nodes are equal
-   * @return 1 node1 occurs first
+   * @return -1 node0 occurs first;
+   * 0 the two nodes are equal;
+   * 1 node1 occurs first
    */
   public static int compare(int octant, Coordinate p0, Coordinate p1)
   {
@@ -62,4 +95,4 @@ public class SegmentPointComparator {
     return 0;
 
   }
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/noding/SegmentSetMutualIntersector.java b/src/com/vividsolutions/jts/noding/SegmentSetMutualIntersector.java
index 2d41742..cd8eaae 100644
--- a/src/com/vividsolutions/jts/noding/SegmentSetMutualIntersector.java
+++ b/src/com/vividsolutions/jts/noding/SegmentSetMutualIntersector.java
@@ -63,14 +63,14 @@ public abstract class SegmentSetMutualIntersector
 
   /**
    * 
-   * @param segStrings0 a collection of {@link SegmentString}s to node
+   * @param segStrings a collection of {@link SegmentString}s to node
    */
   public abstract void setBaseSegments(Collection segStrings);
   
   /**
    * Computes the intersections for two collections of {@link SegmentString}s.
    *
-  * @param segStrings1 a collection of {@link SegmentString}s to node
+  * @param segStrings a collection of {@link SegmentString}s to node
    */
   public abstract void process(Collection segStrings);
 }
\ No newline at end of file
diff --git a/src/com/vividsolutions/jts/noding/SegmentStringUtil.java b/src/com/vividsolutions/jts/noding/SegmentStringUtil.java
index 47ffd86..3ec960d 100644
--- a/src/com/vividsolutions/jts/noding/SegmentStringUtil.java
+++ b/src/com/vividsolutions/jts/noding/SegmentStringUtil.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.noding;
 
 import java.util.*;
diff --git a/src/com/vividsolutions/jts/noding/SinglePassNoder.java b/src/com/vividsolutions/jts/noding/SinglePassNoder.java
index d6749aa..d5fda7d 100644
--- a/src/com/vividsolutions/jts/noding/SinglePassNoder.java
+++ b/src/com/vividsolutions/jts/noding/SinglePassNoder.java
@@ -53,6 +53,10 @@ public abstract class SinglePassNoder
   public SinglePassNoder() {
   }
 
+  public SinglePassNoder(SegmentIntersector segInt) {
+    setSegmentIntersector(segInt);
+  }
+
   /**
    * Sets the SegmentIntersector to use with this noder.
    * A SegmentIntersector will normally add intersection nodes
diff --git a/src/com/vividsolutions/jts/noding/snapround/GeometryNoder.java b/src/com/vividsolutions/jts/noding/snapround/GeometryNoder.java
index add1d20..779713d 100644
--- a/src/com/vividsolutions/jts/noding/snapround/GeometryNoder.java
+++ b/src/com/vividsolutions/jts/noding/snapround/GeometryNoder.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.noding.snapround;
 
 import java.util.*;
@@ -13,12 +46,12 @@ import com.vividsolutions.jts.noding.snapround.*;
  * The input coordinates are expected to be rounded
  * to the given precision model.
  * This class does not perform that function.
- * {@link GeometryPrecisionReducer} may be used to do this.
+ * <code>GeometryPrecisionReducer</code> may be used to do this.
  * <p>
  * This class does <b>not</b> dissolve the output linework,
  * so there may be duplicate linestrings in the output.  
  * Subsequent processing (e.g. polygonization) may require
- * the linework to be unique.  Using {@link UnaryUnion} is one way
+ * the linework to be unique.  Using <code>UnaryUnion</code> is one way
  * to do this (although this is an inefficient approach).
  * 
  * 
@@ -31,8 +64,7 @@ public class GeometryNoder
 
   /**
    * Creates a new noder which snap-rounds to a grid specified
-   * by the given
-   * {@link PrecisionModel).
+   * by the given {@link PrecisionModel}.
    * 
    * @param pm the precision model for the grid to snap-round to
    */
@@ -68,6 +100,7 @@ public class GeometryNoder
     sr.computeNodes(segStrings);
     Collection nodedLines = sr.getNodedSubstrings();
 
+    //TODO: improve this to check for full snap-rounded correctness
     if (isValidityChecked) {
     	NodingValidator nv = new NodingValidator(nodedLines);
     	nv.checkValid();
@@ -109,4 +142,4 @@ public class GeometryNoder
     }
     return segStrings;
   }
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/noding/snapround/HotPixel.java b/src/com/vividsolutions/jts/noding/snapround/HotPixel.java
index 9c68eaa..2de94ed 100644
--- a/src/com/vividsolutions/jts/noding/snapround/HotPixel.java
+++ b/src/com/vividsolutions/jts/noding/snapround/HotPixel.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.noding.snapround;
 
 import com.vividsolutions.jts.algorithm.*;
@@ -47,11 +80,13 @@ public class HotPixel
   private Envelope safeEnv = null;
 
   /**
-   * Creates a new hot pixel.
+   * Creates a new hot pixel, using a given scale factor.
+   * The scale factor must be strictly positive (non-zero).
    * 
    * @param pt the coordinate at the centre of the pixel
-   * @param scaleFactor the scaleFactor determining the pixel size
+   * @param scaleFactor the scaleFactor determining the pixel size.  Must be > 0
    * @param li the intersector to use for testing intersection with line segments
+   * 
    */
   public HotPixel(Coordinate pt, double scaleFactor, LineIntersector li) {
     originalPt = pt;
@@ -59,6 +94,8 @@ public class HotPixel
     this.scaleFactor = scaleFactor;
     this.li = li;
     //tolerance = 0.5;
+    if (scaleFactor <= 0) 
+      throw new IllegalArgumentException("Scale factor must be non-zero");
     if (scaleFactor != 1.0) {
       this.pt = new Coordinate(scale(pt.x), scale(pt.y));
       p0Scaled = new Coordinate();
@@ -277,4 +314,4 @@ public class HotPixel
     return false;
   }
 
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/noding/snapround/MCIndexPointSnapper.java b/src/com/vividsolutions/jts/noding/snapround/MCIndexPointSnapper.java
index 59afbd5..957926b 100644
--- a/src/com/vividsolutions/jts/noding/snapround/MCIndexPointSnapper.java
+++ b/src/com/vividsolutions/jts/noding/snapround/MCIndexPointSnapper.java
@@ -1,13 +1,46 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.noding.snapround;
 
-import java.util.*;
-import com.vividsolutions.jts.geom.*;
-import com.vividsolutions.jts.noding.*;
-import com.vividsolutions.jts.algorithm.LineIntersector;
-import com.vividsolutions.jts.index.chain.*;
-import com.vividsolutions.jts.index.*;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.index.ItemVisitor;
+import com.vividsolutions.jts.index.SpatialIndex;
+import com.vividsolutions.jts.index.chain.MonotoneChain;
+import com.vividsolutions.jts.index.chain.MonotoneChainSelectAction;
 import com.vividsolutions.jts.index.strtree.STRtree;
-import com.vividsolutions.jts.index.quadtree.Quadtree;
+import com.vividsolutions.jts.noding.NodedSegmentString;
+import com.vividsolutions.jts.noding.SegmentString;
 
 /**
  * "Snaps" all {@link SegmentString}s in a {@link SpatialIndex} containing
@@ -19,11 +52,9 @@ public class MCIndexPointSnapper
 {
   public static int nSnaps = 0;
 
-  private Collection monoChains;
   private STRtree index;
 
-  public MCIndexPointSnapper(Collection monoChains, SpatialIndex index) {
-    this.monoChains = monoChains;
+  public MCIndexPointSnapper(SpatialIndex index) {
     this.index = (STRtree) index;
   }
 
@@ -35,13 +66,13 @@ public class MCIndexPointSnapper
    *
    * @param hotPixel the hot pixel to snap to
    * @param parentEdge the edge containing the vertex, if applicable, or <code>null</code>
-   * @param vertexIndex the index of the vertex, if applicable, or -1
+   * @param hotPixelVertexIndex the index of the hotPixel vertex, if applicable, or -1
    * @return <code>true</code> if a node was added for this pixel
    */
-  public boolean snap(HotPixel hotPixel, SegmentString parentEdge, int vertexIndex)
+  public boolean snap(HotPixel hotPixel, SegmentString parentEdge, int hotPixelVertexIndex)
   {
     final Envelope pixelEnv = hotPixel.getSafeEnvelope();
-    final HotPixelSnapAction hotPixelSnapAction = new HotPixelSnapAction(hotPixel, parentEdge, vertexIndex);
+    final HotPixelSnapAction hotPixelSnapAction = new HotPixelSnapAction(hotPixel, parentEdge, hotPixelVertexIndex);
 
     index.query(pixelEnv, new ItemVisitor() {
       public void visitItem(Object item) {
@@ -63,14 +94,15 @@ public class MCIndexPointSnapper
   {
     private HotPixel hotPixel;
     private SegmentString parentEdge;
-    private int vertexIndex;
+    // is -1 if hotPixel is not a vertex
+    private int hotPixelVertexIndex;
     private boolean isNodeAdded = false;
 
-    public HotPixelSnapAction(HotPixel hotPixel, SegmentString parentEdge, int vertexIndex)
+    public HotPixelSnapAction(HotPixel hotPixel, SegmentString parentEdge, int hotPixelVertexIndex)
     {
       this.hotPixel = hotPixel;
       this.parentEdge = parentEdge;
-      this.vertexIndex = vertexIndex;
+      this.hotPixelVertexIndex = hotPixelVertexIndex;
     }
 
     public boolean isNodeAdded() { return isNodeAdded; }
@@ -78,15 +110,25 @@ public class MCIndexPointSnapper
     public void select(MonotoneChain mc, int startIndex)
     {
     	NodedSegmentString ss = (NodedSegmentString) mc.getContext();
-      // don't snap a vertex to itself
+      /**
+       * Check to avoid snapping a hotPixel vertex to the same vertex.
+       * This method is called for segments which intersects the 
+       * hot pixel,
+       * so need to check if either end of the segment is equal to the hot pixel
+       * and if so, do not snap.
+       * 
+       * Sep 22 2012 - MD - currently do need to snap to every vertex,
+       * since otherwise the testCollapse1 test in SnapRoundingTest fails.
+       */
       if (parentEdge != null) {
-        if (ss == parentEdge && startIndex == vertexIndex)
+        if (ss == parentEdge && 
+            (startIndex == hotPixelVertexIndex
+                ))
           return;
       }
-//      isNodeAdded = SimpleSnapRounder.addSnappedNode(hotPixel, ss, startIndex);
       isNodeAdded = hotPixel.addSnappedNode(ss, startIndex);
     }
 
   }
 
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/noding/snapround/MCIndexSnapRounder.java b/src/com/vividsolutions/jts/noding/snapround/MCIndexSnapRounder.java
index aca1315..ce95c07 100644
--- a/src/com/vividsolutions/jts/noding/snapround/MCIndexSnapRounder.java
+++ b/src/com/vividsolutions/jts/noding/snapround/MCIndexSnapRounder.java
@@ -82,7 +82,7 @@ public class MCIndexSnapRounder
   {
     this.nodedSegStrings = inputSegmentStrings;
     noder = new MCIndexNoder();
-    pointSnapper = new MCIndexPointSnapper(noder.getMonotoneChains(), noder.getIndex());
+    pointSnapper = new MCIndexPointSnapper(noder.getIndex());
     snapRound(inputSegmentStrings, li);
 
     // testing purposes only - remove in final version
@@ -124,7 +124,7 @@ public class MCIndexSnapRounder
   }
 
   /**
-   * Computes nodes introduced as a result of snapping segments to snap points (hot pixels)
+   * Snaps segments to nodes created by segment intersections.
    */
   private void computeIntersectionSnaps(Collection snapPts)
   {
@@ -136,8 +136,7 @@ public class MCIndexSnapRounder
   }
 
   /**
-   * Computes nodes introduced as a result of
-   * snapping segments to vertices of other segments
+   * Snaps segments to all vertices.
    *
    * @param edges the list of segment strings to snap together
    */
@@ -150,13 +149,12 @@ public class MCIndexSnapRounder
   }
 
   /**
-   * Performs a brute-force comparison of every segment in each {@link SegmentString}.
-   * This has n^2 performance.
+   * Snaps segments to the vertices of a Segment String.  
    */
   private void computeVertexSnaps(NodedSegmentString e)
   {
     Coordinate[] pts0 = e.getCoordinates();
-    for (int i = 0; i < pts0.length - 1; i++) {
+    for (int i = 0; i < pts0.length ; i++) {
       HotPixel hotPixel = new HotPixel(pts0[i], scaleFactor, li);
       boolean isNodeAdded = pointSnapper.snap(hotPixel, e, i);
       // if a node is created for a vertex, that vertex must be noded too
diff --git a/src/com/vividsolutions/jts/operation/IsSimpleOp.java b/src/com/vividsolutions/jts/operation/IsSimpleOp.java
index 516d3eb..2056a26 100644
--- a/src/com/vividsolutions/jts/operation/IsSimpleOp.java
+++ b/src/com/vividsolutions/jts/operation/IsSimpleOp.java
@@ -36,6 +36,7 @@ package com.vividsolutions.jts.operation;
 
 import java.util.*;
 import com.vividsolutions.jts.geom.*;
+import com.vividsolutions.jts.geom.util.LinearComponentExtracter;
 import com.vividsolutions.jts.geomgraph.*;
 import com.vividsolutions.jts.algorithm.*;
 import com.vividsolutions.jts.geomgraph.index.SegmentIntersector;
@@ -48,34 +49,42 @@ import com.vividsolutions.jts.geomgraph.index.SegmentIntersector;
  *    <li> A Geometry is simple if and only if the only self-intersections are at
  *    boundary points.
  * </ul>
- * This definition relies on the definition of boundary points.
- * The SFS uses the Mod-2 rule to determine which points are on the boundary of
- * lineal geometries, but this class supports
- * using other {@link BoundaryNodeRule}s as well.
  * <p>
- * Simplicity is defined for each {@link Geometry} subclass as follows:
+ * Simplicity is defined for each {@link Geometry} type as follows:
  * <ul>
- * <li>Valid polygonal geometries are simple by definition, so
+ * <li><b>Polygonal</b> geometries are simple by definition, so
  * <code>isSimple</code> trivially returns true.
- * (Hint: in order to check if a polygonal geometry has self-intersections,
- * use {@link Geometry#isValid}).
- * <li>Linear geometries are simple iff they do not self-intersect at points
- * other than boundary points. 
- * (Using the Mod-2 rule, this means that closed linestrings
- * cannot be touched at their endpoints, since these are
- * interior points, not boundary points).
- * <li>Zero-dimensional geometries (points) are simple iff they have no
+ * (Note: this means that <tt>isSimple</tt> cannot be used to test 
+ * for (invalid) self-intersections in <tt>Polygon</tt>s.  
+ * In order to check if a <tt>Polygonal</tt> geometry has self-intersections,
+ * use {@link Geometry#isValid()}).
+ * <li><b>Linear</b> geometries are simple iff they do <i>not</i> self-intersect at interior points
+ * (i.e. points other than boundary points).
+ * This is equivalent to saying that no two linear components satisfy the SFS {@link Geometry#touches(Geometry)}
+ * predicate. 
+ * <li><b>Zero-dimensional (point)</b> geometries are simple if and only if they have no
  * repeated points.
- * <li>Empty <code>Geometry</code>s are always simple
+ * <li><b>Empty</b> geometries are <i>always</i> simple, by definition
  * </ul>
- *
+ * For {@link Lineal} geometries the evaluation of simplicity  
+ * can be customized by supplying a {@link BoundaryNodeRule} 
+ * to define how boundary points are determined.
+ * The default is the SFS-standard {@link BoundaryNodeRule#MOD2_BOUNDARY_RULE}.
+ * Note that under the <tt>Mod-2</tt> rule, closed <tt>LineString</tt>s (rings)
+ * will never satisfy the <tt>touches</tt> predicate at their endpoints, since these are
+ * interior points, not boundary points. 
+ * If it is required to test whether a set of <code>LineString</code>s touch
+ * only at their endpoints, use <code>IsSimpleOp</code> with {@link BoundaryNodeRule#ENDPOINT_BOUNDARY_RULE}.
+ * For example, this can be used to validate that a set of lines form a topologically valid
+ * linear network.
+ * 
  * @see BoundaryNodeRule
  *
  * @version 1.7
  */
 public class IsSimpleOp
 {
-  private Geometry geom;
+  private Geometry inputGeom;
   private boolean isClosedEndpointsInInterior = true;
   private Coordinate nonSimpleLocation = null;
 
@@ -93,7 +102,7 @@ public class IsSimpleOp
    * @param geom the geometry to test
    */
   public IsSimpleOp(Geometry geom) {
-    this.geom = geom;
+    this.inputGeom = geom;
   }
 
   /**
@@ -104,7 +113,7 @@ public class IsSimpleOp
    */
   public IsSimpleOp(Geometry geom, BoundaryNodeRule boundaryNodeRule)
   {
-    this.geom = geom;
+    this.inputGeom = geom;
     isClosedEndpointsInInterior = ! boundaryNodeRule.isInBoundary(2);
   }
 
@@ -116,9 +125,18 @@ public class IsSimpleOp
   public boolean isSimple()
   {
     nonSimpleLocation = null;
+    return computeSimple(inputGeom);
+  }
+  
+  private boolean computeSimple(Geometry geom)
+  {
+    nonSimpleLocation = null;
+    if (geom.isEmpty()) return true;
     if (geom instanceof LineString) return isSimpleLinearGeometry(geom);
     if (geom instanceof MultiLineString) return isSimpleLinearGeometry(geom);
     if (geom instanceof MultiPoint) return isSimpleMultiPoint((MultiPoint) geom);
+    if (geom instanceof Polygonal) return isSimplePolygonal(geom);
+    if (geom instanceof GeometryCollection) return isSimpleGeometryCollection(geom);
     // all other geometry types are simple by definition
     return true;
   }
@@ -130,7 +148,7 @@ public class IsSimpleOp
    * {@link #isSimple} must be called before this method is called.
    *
    * @return a coordinate for the location of the non-boundary self-intersection
-   * @return null if the geometry is simple
+   * or null if the geometry is simple
    */
   public Coordinate getNonSimpleLocation()
   {
@@ -186,6 +204,42 @@ public class IsSimpleOp
     return true;
   }
 
+  /**
+   * Computes simplicity for polygonal geometries.
+   * Polygonal geometries are simple if and only if
+   * all of their component rings are simple.
+   * 
+   * @param geom a Polygonal geometry
+   * @return true if the geometry is simple
+   */
+  private boolean isSimplePolygonal(Geometry geom)
+  {
+    List rings = LinearComponentExtracter.getLines(geom);
+    for (Iterator i = rings.iterator(); i.hasNext(); ) {
+      LinearRing ring = (LinearRing) i.next();
+      if (! isSimpleLinearGeometry(ring))
+        return false;
+    }
+    return true;
+  }
+  
+  /**
+   * Semantics for GeometryCollection is 
+   * simple iff all components are simple.
+   * 
+   * @param geom
+   * @return true if the geometry is simple
+   */
+  private boolean isSimpleGeometryCollection(Geometry geom)
+  {
+    for (int i = 0; i < geom.getNumGeometries(); i++ ) {
+      Geometry comp = geom.getGeometryN(i);
+      if (! computeSimple(comp))
+        return false;
+    }
+    return true;
+  }
+  
   private boolean isSimpleLinearGeometry(Geometry geom)
   {
     if (geom.isEmpty()) return true;
diff --git a/src/com/vividsolutions/jts/operation/buffer/BufferBuilder.java b/src/com/vividsolutions/jts/operation/buffer/BufferBuilder.java
index 50418bf..4fe1e79 100644
--- a/src/com/vividsolutions/jts/operation/buffer/BufferBuilder.java
+++ b/src/com/vividsolutions/jts/operation/buffer/BufferBuilder.java
@@ -192,6 +192,15 @@ public class BufferBuilder
 
     for (Iterator i = nodedSegStrings.iterator(); i.hasNext(); ) {
       SegmentString segStr = (SegmentString) i.next();
+      
+      /**
+       * Discard edges which have zero length, 
+       * since they carry no information and cause problems with topology building
+       */
+      Coordinate[] pts = segStr.getCoordinates();
+      if (pts.length == 2 && pts[0].equals2D(pts[1]))
+        continue;
+
       Label oldLabel = (Label) segStr.getData();
       Edge edge = new Edge(segStr.getCoordinates(), new Label(oldLabel));
       insertUniqueEdge(edge);
diff --git a/src/com/vividsolutions/jts/operation/buffer/BufferInputLineSimplifier.java b/src/com/vividsolutions/jts/operation/buffer/BufferInputLineSimplifier.java
index 65df68b..a758bdd 100644
--- a/src/com/vividsolutions/jts/operation/buffer/BufferInputLineSimplifier.java
+++ b/src/com/vividsolutions/jts/operation/buffer/BufferInputLineSimplifier.java
@@ -171,7 +171,7 @@ public class BufferInputLineSimplifier
    * Finds the next non-deleted index, or the end of the point array if none
    * @param index
    * @return the next non-deleted index, if any
-   * @return inputLine.length if there are no more non-deleted indices
+   * or inputLine.length if there are no more non-deleted indices
    */
   private int findNextNonDeletedIndex(int index)
   {
diff --git a/src/com/vividsolutions/jts/operation/buffer/BufferOp.java b/src/com/vividsolutions/jts/operation/buffer/BufferOp.java
index 10d51b0..b335b82 100644
--- a/src/com/vividsolutions/jts/operation/buffer/BufferOp.java
+++ b/src/com/vividsolutions/jts/operation/buffer/BufferOp.java
@@ -37,6 +37,7 @@ package com.vividsolutions.jts.operation.buffer;
  */
 import com.vividsolutions.jts.geom.*;
 import com.vividsolutions.jts.precision.SimpleGeometryPrecisionReducer;
+import com.vividsolutions.jts.math.MathUtil;
 import com.vividsolutions.jts.noding.*;
 import com.vividsolutions.jts.noding.snapround.*;
 
@@ -107,9 +108,12 @@ public class BufferOp
   /**
    * Compute a scale factor to limit the precision of
    * a given combination of Geometry and buffer distance.
-   * The scale factor is determined by a combination of
+   * The scale factor is determined by
    * the number of digits of precision in the (geometry + buffer distance),
    * limited by the supplied <code>maxPrecisionDigits</code> value.
+   * <p>
+   * The scale factor is based on the absolute magnitude of the (geometry + buffer distance).
+   * since this determines the number of digits of precision which must be handled.
    *
    * @param g the Geometry being buffered
    * @param distance the buffer distance
@@ -123,6 +127,29 @@ public class BufferOp
     int maxPrecisionDigits)
   {
     Envelope env = g.getEnvelopeInternal();
+    double envMax = MathUtil.max(
+        Math.abs(env.getMaxX()), 
+            Math.abs(env.getMaxY()), 
+                Math.abs(env.getMinX()), 
+                    Math.abs(env.getMinY())
+            );
+    
+    double expandByDistance = distance > 0.0 ? distance : 0.0;
+    double bufEnvMax = envMax + 2 * expandByDistance;
+
+    // the smallest power of 10 greater than the buffer envelope
+    int bufEnvPrecisionDigits = (int) (Math.log(bufEnvMax) / Math.log(10) + 1.0);
+    int minUnitLog10 = maxPrecisionDigits - bufEnvPrecisionDigits;
+    
+    double scaleFactor = Math.pow(10.0, minUnitLog10);
+    return scaleFactor;
+  }
+
+  private static double OLDprecisionScaleFactor(Geometry g,
+      double distance,
+    int maxPrecisionDigits)
+  {
+    Envelope env = g.getEnvelopeInternal();
     double envSize = Math.max(env.getHeight(), env.getWidth());
     double expandByDistance = distance > 0.0 ? distance : 0.0;
     double bufEnvSize = envSize + 2 * expandByDistance;
diff --git a/src/com/vividsolutions/jts/operation/buffer/BufferParameters.java b/src/com/vividsolutions/jts/operation/buffer/BufferParameters.java
index c77d2f3..32e1be5 100644
--- a/src/com/vividsolutions/jts/operation/buffer/BufferParameters.java
+++ b/src/com/vividsolutions/jts/operation/buffer/BufferParameters.java
@@ -33,8 +33,17 @@
 package com.vividsolutions.jts.operation.buffer;
 
 /**
- * Contains the parameters which 
- * describe how a buffer should be constructed.
+ * A value class containing the parameters which 
+ * specify how a buffer should be constructed.
+ * <p>
+ * The parameters allow control over:
+ * <ul>
+ * <li>Quadrant segments (accuracy of approximation for circular arcs)
+ * <li>End Cap style
+ * <li>Join style
+ * <li>Mitre limit
+ * <li>whether the buffer is single-sided
+ * </ul>
  * 
  * @author Martin Davis
  *
@@ -171,7 +180,7 @@ public class BufferParameters
    * (in other words, the computed buffer curve is always inside the true
    * curve).
    * 
-   * @param quadrantSegments the number of segments in a fillet for a quadrant
+   * @param quadSegs the number of segments in a fillet for a quadrant
    */
   public void setQuadrantSegments(int quadSegs)
   {
@@ -232,7 +241,7 @@ public class BufferParameters
   
   /**
    * Specifies the end cap style of the generated buffer.
-   * The styles supported are {@link #CAP_ROUND}, {@link #CAP_BUTT}, and {@link #CAP_SQUARE}.
+   * The styles supported are {@link #CAP_ROUND}, {@link #CAP_FLAT}, and {@link #CAP_SQUARE}.
    * The default is CAP_ROUND.
    *
    * @param endCapStyle the end cap style to specify
@@ -254,8 +263,8 @@ public class BufferParameters
   
   /**
    * Sets the join style for outside (reflex) corners between line segments.
-   * Allowable values are {@link JOIN_ROUND} (which is the default),
-   * {@link JOIN_MITRE} and {link JOIN_BEVEL}.
+   * Allowable values are {@link #JOIN_ROUND} (which is the default),
+   * {@link #JOIN_MITRE} and {link JOIN_BEVEL}.
    * 
    * @param joinStyle the code for the join style
    */
@@ -295,7 +304,7 @@ public class BufferParameters
   /**
    * Sets whether the computed buffer should be single-sided.
    * A single-sided buffer is constructed on only one side of each input line.
-   * <b>
+   * <p>
    * The side used is determined by the sign of the buffer distance:
    * <ul>
    * <li>a positive distance indicates the left-hand side
diff --git a/src/com/vividsolutions/jts/operation/buffer/OLDOffsetCurveBuilder.java b/src/com/vividsolutions/jts/operation/buffer/OLDOffsetCurveBuilder.java
deleted file mode 100644
index e393f63..0000000
--- a/src/com/vividsolutions/jts/operation/buffer/OLDOffsetCurveBuilder.java
+++ /dev/null
@@ -1,862 +0,0 @@
-/*
- * The JTS Topology Suite is a collection of Java classes that
- * implement the fundamental operations required to validate a given
- * geo-spatial data set to a known topological specification.
- *
- * Copyright (C) 2001 Vivid Solutions
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * For more information, contact:
- *
- *     Vivid Solutions
- *     Suite #1A
- *     2328 Government Street
- *     Victoria BC  V8T 5G5
- *     Canada
- *
- *     (250)385-6040
- *     www.vividsolutions.com
- */
-package com.vividsolutions.jts.operation.buffer;
-
-import java.util.*;
-import com.vividsolutions.jts.geom.*;
-import com.vividsolutions.jts.algorithm.*;
-import com.vividsolutions.jts.geomgraph.*;
-
-/**
- * Computes the raw offset curve for a
- * single {@link Geometry} component (ring, line or point).
- * A raw offset curve line is not noded -
- * it may contain self-intersections (and usually will).
- * The final buffer polygon is computed by forming a topological graph
- * of all the noded raw curves and tracing outside contours.
- * The points in the raw curve are rounded to the required precision model.
- *
- * @version 1.7
- */
-class OLDOffsetCurveBuilder 
-{  
-  /**
-   * The angle quantum with which to approximate a fillet curve
-   * (based on the input # of quadrant segments)
-   */
-  private double filletAngleQuantum;
-  
-  /**
-   * the max error of approximation (distance) between a quad segment and the true fillet curve
-   */
-  private double maxCurveSegmentError = 0.0;
-  
-  /**
-   * Factor which controls how close curve vertices can be to be snapped
-   */
-  private static final double CURVE_VERTEX_SNAP_DISTANCE_FACTOR = 1.0E-6;
-  
-  /**
-   * Factor which controls how close offset segments can be to
-   * skip adding a filler or mitre.
-   */
-  private static final double OFFSET_SEGMENT_SEPARATION_FACTOR = 1.0E-3;
-  
-  /**
-   * Factor which controls how close curve vertices on inside turns can be to be snapped 
-   */
-  private static final double INSIDE_TURN_VERTEX_SNAP_DISTANCE_FACTOR = 1.0E-3;
-    
-  /**
-   * Factor which determines how short closing segs can be for round buffers
-   */
-  private static final int MAX_CLOSING_SEG_LEN_FACTOR = 80;
-  
-  private double distance = 0.0;
-  private PrecisionModel precisionModel;
-  private BufferParameters bufParams;
-  
-  /**
-   * The Closing Segment Length Factor controls how long
-   * "closing segments" are.  Closing segments are added
-   * at the middle of inside corners to ensure a smoother
-   * boundary for the buffer offset curve. 
-   * In some cases (particularly for round joins with default-or-better
-   * quantization) the closing segments can be made quite short.
-   * This substantially improves performance (due to fewer intersections being created).
-   * 
-   * A closingSegFactor of 0 results in lines to the corner vertex
-   * A closingSegFactor of 1 results in lines halfway to the corner vertex
-   * A closingSegFactor of 80 results in lines 1/81 of the way to the corner vertex
-   * (this option is reasonable for the very common default situation of round joins
-   * and quadrantSegs >= 8)
-   * 
-   */
-  private int closingSegLengthFactor = 1;
-  private OffsetSegmentString vertexList;
-  private LineIntersector li;
-  
-  public OLDOffsetCurveBuilder(
-                PrecisionModel precisionModel,
-                BufferParameters bufParams
-                )
-  {
-    this.precisionModel = precisionModel;
-    this.bufParams = bufParams;
-    
-    // compute intersections in full precision, to provide accuracy
-    // the points are rounded as they are inserted into the curve line
-    li = new RobustLineIntersector();
-    filletAngleQuantum = Math.PI / 2.0 / bufParams.getQuadrantSegments();
-    
-    /**
-     * Non-round joins cause issues with short closing segments,
-     * so don't use them.  In any case, non-round joins 
-     * only really make sense for relatively small buffer distances.
-     */
-    if (bufParams.getQuadrantSegments() >= 8 
-        && bufParams.getJoinStyle() == BufferParameters.JOIN_ROUND)
-      closingSegLengthFactor = MAX_CLOSING_SEG_LEN_FACTOR;
-  }
-
-  public BufferParameters getBufferParameters()
-  {
-    return bufParams;
-  }
-  /**
-   * This method handles single points as well as lines.
-   * Lines are assumed to <b>not</b> be closed (the function will not
-   * fail for closed lines, but will generate superfluous line caps).
-   *
-   * @return a List of Coordinate[]
-   */
-  public List getLineCurve(Coordinate[] inputPts, double distance)
-  {
-    List lineList = new ArrayList();
-    
-    // a zero or negative width buffer of a line/point is empty
-    if (distance <= 0.0 && ! bufParams.isSingleSided()) return lineList;
-
-    double posDistance = Math.abs(distance);
-    init(posDistance);
-    if (inputPts.length <= 1) {
-      switch (bufParams.getEndCapStyle()) {
-        case BufferParameters.CAP_ROUND:
-          addCircle(inputPts[0], posDistance);
-          break;
-        case BufferParameters.CAP_SQUARE:
-          addSquare(inputPts[0], posDistance);
-          break;
-          // default is for buffer to be empty (e.g. for a butt line cap);
-      }
-    }
-    else {
-      if (bufParams.isSingleSided()) {
-        boolean isRightSide = distance > 0.0;
-        computeSingleSidedBufferCurve(inputPts, isRightSide);
-      }
-      else
-        computeLineBufferCurve(inputPts);
-    }
-      
-    
-//System.out.println(vertexList);
-    
-    Coordinate[] lineCoord = vertexList.getCoordinates();
-    lineList.add(lineCoord);
-    return lineList;
-  }
-
-  /**
-   * This method handles the degenerate cases of single points and lines,
-   * as well as rings.
-   *
-   * @return a List of Coordinate[]
-   */
-  public List getRingCurve(Coordinate[] inputPts, int side, double distance)
-  {
-    List lineList = new ArrayList();
-    init(distance);
-    if (inputPts.length <= 2)
-      return getLineCurve(inputPts, distance);
-
-    // optimize creating ring for for zero distance
-    if (distance == 0.0) {
-      lineList.add(copyCoordinates(inputPts));
-      return lineList;
-    }
-    computeRingBufferCurve(inputPts, side);
-    lineList.add(vertexList.getCoordinates());
-    return lineList;
-  }
-
-  private static Coordinate[] copyCoordinates(Coordinate[] pts)
-  {
-    Coordinate[] copy = new Coordinate[pts.length];
-    for (int i = 0; i < copy.length; i++) {
-      copy[i] = new Coordinate(pts[i]);
-    }
-    return copy;
-  }
-  
-  private void init(double distance)
-  {
-    this.distance = distance;
-    maxCurveSegmentError = distance * (1 - Math.cos(filletAngleQuantum / 2.0));
-    vertexList = new OffsetSegmentString();
-    vertexList.setPrecisionModel(precisionModel);
-    /**
-     * Choose the min vertex separation as a small fraction of the offset distance.
-     */
-    vertexList.setMinimumVertexDistance(distance * CURVE_VERTEX_SNAP_DISTANCE_FACTOR);
-  }
-  
-  /**
-   * Use a value which results in a potential distance error which is
-   * significantly less than the error due to 
-   * the quadrant segment discretization.
-   * For QS = 8 a value of 100 is reasonable.
-   * This should produce a maximum of 1% distance error.
-   */
-  private static final double SIMPLIFY_FACTOR = 100.0;
-  
-  /**
-   * Computes the distance tolerance to use during input
-   * line simplification.
-   * 
-   * @param distance the buffer distance
-   * @return the simplification tolerance
-   */
-  private static double simplifyTolerance(double bufDistance)
-  {
-    return bufDistance / SIMPLIFY_FACTOR;
-  }
-  
-  private void computeLineBufferCurve(Coordinate[] inputPts)
-  {
-    double distTol = simplifyTolerance(distance);
-    
-    //--------- compute points for left side of line
-    // Simplify the appropriate side of the line before generating
-    Coordinate[] simp1 = BufferInputLineSimplifier.simplify(inputPts, distTol);
-    // MD - used for testing only (to eliminate simplification)
-//    Coordinate[] simp1 = inputPts;
-    
-    int n1 = simp1.length - 1;
-    initSideSegments(simp1[0], simp1[1], Position.LEFT);
-    for (int i = 2; i <= n1; i++) {
-      addNextSegment(simp1[i], true);
-    }
-    addLastSegment();
-    // add line cap for end of line
-    addLineEndCap(simp1[n1 - 1], simp1[n1]);
-    
-    //---------- compute points for right side of line
-    // Simplify the appropriate side of the line before generating
-    Coordinate[] simp2 = BufferInputLineSimplifier.simplify(inputPts, -distTol);
-    // MD - used for testing only (to eliminate simplification)
-//    Coordinate[] simp2 = inputPts;
-    int n2 = simp2.length - 1;
-   
-    // since we are traversing line in opposite order, offset position is still LEFT
-    initSideSegments(simp2[n2], simp2[n2 - 1], Position.LEFT);
-    for (int i = n2 - 2; i >= 0; i--) {
-      addNextSegment(simp2[i], true);
-    }
-    addLastSegment();
-    // add line cap for start of line
-    addLineEndCap(simp2[1], simp2[0]);
-
-    vertexList.closeRing();
-  }
-
-  /*
-  private void OLDcomputeLineBufferCurve(Coordinate[] inputPts)
-  {
-    int n = inputPts.length - 1;
-    
-    // compute points for left side of line
-    initSideSegments(inputPts[0], inputPts[1], Position.LEFT);
-    for (int i = 2; i <= n; i++) {
-      addNextSegment(inputPts[i], true);
-    }
-    addLastSegment();
-    // add line cap for end of line
-    addLineEndCap(inputPts[n - 1], inputPts[n]);
-
-    // compute points for right side of line
-    initSideSegments(inputPts[n], inputPts[n - 1], Position.LEFT);
-    for (int i = n - 2; i >= 0; i--) {
-      addNextSegment(inputPts[i], true);
-    }
-    addLastSegment();
-    // add line cap for start of line
-    addLineEndCap(inputPts[1], inputPts[0]);
-
-    vertexList.closeRing();
-  }
-  */
-  
-  private void computeSingleSidedBufferCurve(Coordinate[] inputPts, boolean isRightSide)
-  {
-    double distTol = simplifyTolerance(distance);
-    
-    if (isRightSide) {
-      // add original line
-      vertexList.addPts(inputPts, true);
-      
-      //---------- compute points for right side of line
-      // Simplify the appropriate side of the line before generating
-      Coordinate[] simp2 = BufferInputLineSimplifier.simplify(inputPts, -distTol);
-      // MD - used for testing only (to eliminate simplification)
-  //    Coordinate[] simp2 = inputPts;
-      int n2 = simp2.length - 1;
-     
-      // since we are traversing line in opposite order, offset position is still LEFT
-      initSideSegments(simp2[n2], simp2[n2 - 1], Position.LEFT);
-      addFirstSegment();
-      for (int i = n2 - 2; i >= 0; i--) {
-        addNextSegment(simp2[i], true);
-      }
-    }
-    else {
-      // add original line
-      vertexList.addPts(inputPts, false);
-      
-      //--------- compute points for left side of line
-      // Simplify the appropriate side of the line before generating
-      Coordinate[] simp1 = BufferInputLineSimplifier.simplify(inputPts, distTol);
-      // MD - used for testing only (to eliminate simplification)
-//      Coordinate[] simp1 = inputPts;
-      
-      int n1 = simp1.length - 1;
-      initSideSegments(simp1[0], simp1[1], Position.LEFT);
-      addFirstSegment();
-      for (int i = 2; i <= n1; i++) {
-        addNextSegment(simp1[i], true);
-      }
-    }
-    addLastSegment();
-    vertexList.closeRing();
-  }
-
-  private void computeRingBufferCurve(Coordinate[] inputPts, int side)
-  {
-    // simplify input line to improve performance
-    double distTol = simplifyTolerance(distance);
-    // ensure that correct side is simplified
-    if (side == Position.RIGHT)
-      distTol = -distTol;
-    Coordinate[] simp = BufferInputLineSimplifier.simplify(inputPts, distTol);
-//    Coordinate[] simp = inputPts;
-    
-    int n = simp.length - 1;
-    initSideSegments(simp[n - 1], simp[0], side);
-    for (int i = 1; i <= n; i++) {
-      boolean addStartPoint = i != 1;
-      addNextSegment(simp[i], addStartPoint);
-    }
-    vertexList.closeRing();
-  }
-
-  private Coordinate s0, s1, s2;
-  private LineSegment seg0 = new LineSegment();
-  private LineSegment seg1 = new LineSegment();
-  private LineSegment offset0 = new LineSegment();
-  private LineSegment offset1 = new LineSegment();
-  private int side = 0;
-
-  private void initSideSegments(Coordinate s1, Coordinate s2, int side)
-  {
-    this.s1 = s1;
-    this.s2 = s2;
-    this.side = side;
-    seg1.setCoordinates(s1, s2);
-    computeOffsetSegment(seg1, side, distance, offset1);
-  }
-
-  private void addFirstSegment()
-  {
-    vertexList.addPt(offset1.p0);
-  }
-  
-  /**
-   * Add last offset point
-   */
-  private void addLastSegment()
-  {
-    vertexList.addPt(offset1.p1);
-  }
-
-  //private static double MAX_CLOSING_SEG_LEN = 3.0;
-
-  private void addNextSegment(Coordinate p, boolean addStartPoint)
-  {
-    // s0-s1-s2 are the coordinates of the previous segment and the current one
-    s0 = s1;
-    s1 = s2;
-    s2 = p;
-    seg0.setCoordinates(s0, s1);
-    computeOffsetSegment(seg0, side, distance, offset0);
-    seg1.setCoordinates(s1, s2);
-    computeOffsetSegment(seg1, side, distance, offset1);
-
-    // do nothing if points are equal
-    if (s1.equals(s2)) return;
-
-    int orientation = CGAlgorithms.computeOrientation(s0, s1, s2);
-    boolean outsideTurn =
-          (orientation == CGAlgorithms.CLOCKWISE        && side == Position.LEFT)
-      ||  (orientation == CGAlgorithms.COUNTERCLOCKWISE && side == Position.RIGHT);
-
-    if (orientation == 0) { // lines are collinear
-    	addCollinear(addStartPoint);
-		}
-    else if (outsideTurn) 
-		{
-			addOutsideTurn(orientation, addStartPoint);
-		}
-    else { // inside turn
-			addInsideTurn(orientation, addStartPoint);
-    }
-  }
-  
-  private void addCollinear(boolean addStartPoint)
-  {
-  	/**
-  	 * This test could probably be done more efficiently,
-  	 * but the situation of exact collinearity should be fairly rare.
-  	 */
-		li.computeIntersection(s0, s1, s1, s2);
-		int numInt = li.getIntersectionNum();
-		/**
-		 * if numInt is < 2, the lines are parallel and in the same direction. In
-		 * this case the point can be ignored, since the offset lines will also be
-		 * parallel.
-		 */
-		if (numInt >= 2) {
-			/**
-			 * segments are collinear but reversing. 
-			 * Add an "end-cap" fillet
-			 * all the way around to other direction This case should ONLY happen
-			 * for LineStrings, so the orientation is always CW. (Polygons can never
-			 * have two consecutive segments which are parallel but reversed,
-			 * because that would be a self intersection.
-			 * 
-			 */
-			if (bufParams.getJoinStyle() == BufferParameters.JOIN_BEVEL 
-					|| bufParams.getJoinStyle() == BufferParameters.JOIN_MITRE) {
-				if (addStartPoint) vertexList.addPt(offset0.p1);
-				vertexList.addPt(offset1.p0);
-			}
-			else {
-				addFillet(s1, offset0.p1, offset1.p0, CGAlgorithms.CLOCKWISE, distance);
-			}
-		}
-  }
-  
-  /**
-   * Adds the offset points for an outside (convex) turn
-   * 
-   * @param orientation
-   * @param addStartPoint
-   */
-  private void addOutsideTurn(int orientation, boolean addStartPoint)
-  {
-  	/**
-  	 * Heuristic: If offset endpoints are very close together, 
-  	 * just use one of them as the corner vertex.
-  	 * This avoids problems with computing mitre corners in the case
-  	 * where the two segments are almost parallel 
-  	 * (which is hard to compute a robust intersection for).
-  	 */
-    if (offset0.p1.distance(offset1.p0) < distance * OFFSET_SEGMENT_SEPARATION_FACTOR) {
-    	vertexList.addPt(offset0.p1);
-    	return;
-    }
-  	
-		if (bufParams.getJoinStyle() == BufferParameters.JOIN_MITRE) {
-			addMitreJoin(s1, offset0, offset1, distance);
-		}
-		else if (bufParams.getJoinStyle() == BufferParameters.JOIN_BEVEL){
-			addBevelJoin(offset0, offset1);
-		}
-		else {
-		// add a circular fillet connecting the endpoints of the offset segments
-		 if (addStartPoint) vertexList.addPt(offset0.p1);
-      // TESTING - comment out to produce beveled joins
-      addFillet(s1, offset0.p1, offset1.p0, orientation, distance);
-      vertexList.addPt(offset1.p0);
-		}
-  }
-  
-  /**
-   * Adds the offset points for an inside (concave) turn.
-   * 
-   * @param orientation
-   * @param addStartPoint
-   */
-  private void addInsideTurn(int orientation, boolean addStartPoint) {
-    /**
-     * add intersection point of offset segments (if any)
-     */
-    li.computeIntersection(offset0.p0, offset0.p1, offset1.p0, offset1.p1);
-    if (li.hasIntersection()) {
-      vertexList.addPt(li.getIntersection(0));
-    }
-    else {
-      /**
-       * If no intersection is detected, it means the angle is so small and/or the offset so
-       * large that the offsets segments don't intersect. In this case we must
-       * add a "closing segment" to make sure the buffer curve is continuous,
-       * fairly smooth (e.g. no sharp reversals in direction)
-       * and tracks the buffer correctly around the corner. The curve connects
-       * the endpoints of the segment offsets to points
-       * which lie toward the centre point of the corner.
-       * The joining curve will not appear in the final buffer outline, since it
-       * is completely internal to the buffer polygon.
-       * 
-       * In complex buffer cases the closing segment may cut across many other
-       * segments in the generated offset curve.  In order to improve the 
-       * performance of the noding, the closing segment should be kept as short as possible.
-       * (But not too short, since that would defeat its purpose).
-       * This is the purpose of the closingSegFactor heuristic value.
-       */ 
-    	
-       /** 
-       * The intersection test above is vulnerable to robustness errors; i.e. it
-       * may be that the offsets should intersect very close to their endpoints,
-       * but aren't reported as such due to rounding. To handle this situation
-       * appropriately, we use the following test: If the offset points are very
-       * close, don't add closing segments but simply use one of the offset
-       * points
-       */
-      if (offset0.p1.distance(offset1.p0) < distance
-          * INSIDE_TURN_VERTEX_SNAP_DISTANCE_FACTOR) {
-        vertexList.addPt(offset0.p1);
-      } else {
-        // add endpoint of this segment offset
-        vertexList.addPt(offset0.p1);
-        
-        /**
-         * Add "closing segment" of required length.
-         */
-        if (closingSegLengthFactor > 0) {
-          Coordinate mid0 = new Coordinate((closingSegLengthFactor * offset0.p1.x + s1.x)/(closingSegLengthFactor + 1), 
-              (closingSegLengthFactor*offset0.p1.y + s1.y)/(closingSegLengthFactor + 1));
-          vertexList.addPt(mid0);
-          Coordinate mid1 = new Coordinate((closingSegLengthFactor*offset1.p0.x + s1.x)/(closingSegLengthFactor + 1), 
-             (closingSegLengthFactor*offset1.p0.y + s1.y)/(closingSegLengthFactor + 1));
-          vertexList.addPt(mid1);
-        }
-        else {
-          /**
-           * This branch is not expected to be used except for testing purposes.
-           * It is equivalent to the JTS 1.9 logic for closing segments
-           * (which results in very poor performance for large buffer distances)
-           */
-          vertexList.addPt(s1);
-        }
-        
-        //*/  
-        // add start point of next segment offset
-        vertexList.addPt(offset1.p0);
-      }
-    }
-  }
-  
-
-  /**
-   * Compute an offset segment for an input segment on a given side and at a given distance.
-   * The offset points are computed in full double precision, for accuracy.
-   *
-   * @param seg the segment to offset
-   * @param side the side of the segment ({@link Position}) the offset lies on
-   * @param distance the offset distance
-   * @param offset the points computed for the offset segment
-   */
-  private void computeOffsetSegment(LineSegment seg, int side, double distance, LineSegment offset)
-  {
-    int sideSign = side == Position.LEFT ? 1 : -1;
-    double dx = seg.p1.x - seg.p0.x;
-    double dy = seg.p1.y - seg.p0.y;
-    double len = Math.sqrt(dx * dx + dy * dy);
-    // u is the vector that is the length of the offset, in the direction of the segment
-    double ux = sideSign * distance * dx / len;
-    double uy = sideSign * distance * dy / len;
-    offset.p0.x = seg.p0.x - uy;
-    offset.p0.y = seg.p0.y + ux;
-    offset.p1.x = seg.p1.x - uy;
-    offset.p1.y = seg.p1.y + ux;
-  }
-
-  /**
-   * Add an end cap around point p1, terminating a line segment coming from p0
-   */
-  private void addLineEndCap(Coordinate p0, Coordinate p1)
-  {
-    LineSegment seg = new LineSegment(p0, p1);
-
-    LineSegment offsetL = new LineSegment();
-    computeOffsetSegment(seg, Position.LEFT, distance, offsetL);
-    LineSegment offsetR = new LineSegment();
-    computeOffsetSegment(seg, Position.RIGHT, distance, offsetR);
-
-    double dx = p1.x - p0.x;
-    double dy = p1.y - p0.y;
-    double angle = Math.atan2(dy, dx);
-
-    switch (bufParams.getEndCapStyle()) {
-      case BufferParameters.CAP_ROUND:
-        // add offset seg points with a fillet between them
-      	vertexList.addPt(offsetL.p1);
-        addFillet(p1, angle + Math.PI / 2, angle - Math.PI / 2, CGAlgorithms.CLOCKWISE, distance);
-        vertexList.addPt(offsetR.p1);
-        break;
-      case BufferParameters.CAP_FLAT:
-        // only offset segment points are added
-      	vertexList.addPt(offsetL.p1);
-      	vertexList.addPt(offsetR.p1);
-        break;
-      case BufferParameters.CAP_SQUARE:
-        // add a square defined by extensions of the offset segment endpoints
-        Coordinate squareCapSideOffset = new Coordinate();
-        squareCapSideOffset.x = Math.abs(distance) * Math.cos(angle);
-        squareCapSideOffset.y = Math.abs(distance) * Math.sin(angle);
-
-        Coordinate squareCapLOffset = new Coordinate(
-            offsetL.p1.x + squareCapSideOffset.x,
-            offsetL.p1.y + squareCapSideOffset.y);
-        Coordinate squareCapROffset = new Coordinate(
-            offsetR.p1.x + squareCapSideOffset.x,
-            offsetR.p1.y + squareCapSideOffset.y);
-        vertexList.addPt(squareCapLOffset);
-        vertexList.addPt(squareCapROffset);
-        break;
-
-    }
-  }
-  /**
-   * Adds a mitre join connecting the two reflex offset segments.
-   * The mitre will be beveled if it exceeds the mitre ratio limit.
-   * 
-   * @param offset0 the first offset segment
-   * @param offset1 the second offset segment
-   * @param distance the offset distance
-   */
-  private void addMitreJoin(Coordinate p, 
-  		LineSegment offset0, 
-  		LineSegment offset1,
-  		double distance)
-  {
-  	boolean isMitreWithinLimit = true;
-  	Coordinate intPt = null;
-  
-  	/**
-  	 * This computation is unstable if the offset segments are nearly collinear.
-  	 * Howver, this situation should have been eliminated earlier by the check for 
-  	 * whether the offset segment endpoints are almost coincident
-  	 */
-  	try {
-  	 intPt = HCoordinate.intersection(offset0.p0, 
-  			offset0.p1, offset1.p0, offset1.p1);
-  	 
-  	 double mitreRatio = distance <= 0.0 ? 1.0
-  			 : intPt.distance(p) / Math.abs(distance);
-  	 
-  	 if (mitreRatio > bufParams.getMitreLimit())
-  		 isMitreWithinLimit = false;
-  	}
-  	catch (NotRepresentableException ex) {
-  		intPt = new Coordinate(0,0);
-  		isMitreWithinLimit = false;
-  	}
-  	
-  	if (isMitreWithinLimit) {
-  		vertexList.addPt(intPt);
-  	}
-  	else {
-  		addLimitedMitreJoin(offset0, offset1, distance, bufParams.getMitreLimit());
-//  		addBevelJoin(offset0, offset1);
-  	}
-  }
-  
-  
-  /**
-   * Adds a limited mitre join connecting the two reflex offset segments.
-   * A limited mitre is a mitre which is beveled at the distance
-   * determined by the mitre ratio limit.
-   * 
-   * @param offset0 the first offset segment
-   * @param offset1 the second offset segment
-   * @param distance the offset distance
-   * @param mitreLimit the mitre limit ratio
-   */
-  private void addLimitedMitreJoin( 
-  		LineSegment offset0, 
-  		LineSegment offset1,
-  		double distance,
-  		double mitreLimit)
-  {
-  	Coordinate basePt = seg0.p1;
-  	
-  	double ang0 = Angle.angle(basePt, seg0.p0);
-  	double ang1 = Angle.angle(basePt, seg1.p1);
-  	
-  	// oriented angle between segments
-  	double angDiff = Angle.angleBetweenOriented(seg0.p0, basePt, seg1.p1);
-  	// half of the interior angle
-  	double angDiffHalf = angDiff / 2;
-  
-  	// angle for bisector of the interior angle between the segments
-  	double midAng = Angle.normalize(ang0 + angDiffHalf);
-  	// rotating this by PI gives the bisector of the reflex angle
-  	double mitreMidAng = Angle.normalize(midAng + Math.PI);
-  	
-  	// the miterLimit determines the distance to the mitre bevel
-  	double mitreDist = mitreLimit * distance;
-  	// the bevel delta is the difference between the buffer distance
-  	// and half of the length of the bevel segment
-  	double bevelDelta = mitreDist * Math.abs(Math.sin(angDiffHalf));
-  	double bevelHalfLen = distance - bevelDelta;
-
-  	// compute the midpoint of the bevel segment
-  	double bevelMidX = basePt.x + mitreDist * Math.cos(mitreMidAng);
-  	double bevelMidY = basePt.y + mitreDist * Math.sin(mitreMidAng);
-  	Coordinate bevelMidPt = new Coordinate(bevelMidX, bevelMidY);
-  	
-  	// compute the mitre midline segment from the corner point to the bevel segment midpoint
-  	LineSegment mitreMidLine = new LineSegment(basePt, bevelMidPt);
-  	
-  	// finally the bevel segment endpoints are computed as offsets from 
-    // the mitre midline
-  	Coordinate bevelEndLeft = mitreMidLine.pointAlongOffset(1.0, bevelHalfLen);
-  	Coordinate bevelEndRight = mitreMidLine.pointAlongOffset(1.0, -bevelHalfLen);
-  	
-  	if (side == Position.LEFT) {
-  		vertexList.addPt(bevelEndLeft);
-  		vertexList.addPt(bevelEndRight);
-  	}
-  	else {
-  		vertexList.addPt(bevelEndRight);
-  		vertexList.addPt(bevelEndLeft);  		
-  	}
-  }
-  
-  /**
-   * Adds a bevel join connecting the two offset segments
-   * around a reflex corner.
-   * 
-   * @param offset0 the first offset segment
-   * @param offset1 the second offset segment
-   */
-  private void addBevelJoin( 
-  		LineSegment offset0, 
-  		LineSegment offset1)
-  {
-		 vertexList.addPt(offset0.p1);
-     vertexList.addPt(offset1.p0);				
-  }
-  
-  
-  /**
-   * Add points for a circular fillet around a reflex corner.
-   * Adds the start and end points
-   * 
-   * @param p base point of curve
-   * @param p0 start point of fillet curve
-   * @param p1 endpoint of fillet curve
-   * @param direction the orientation of the fillet
-   * @param radius the radius of the fillet
-   */
-  private void addFillet(Coordinate p, Coordinate p0, Coordinate p1, int direction, double radius)
-  {
-    double dx0 = p0.x - p.x;
-    double dy0 = p0.y - p.y;
-    double startAngle = Math.atan2(dy0, dx0);
-    double dx1 = p1.x - p.x;
-    double dy1 = p1.y - p.y;
-    double endAngle = Math.atan2(dy1, dx1);
-
-    if (direction == CGAlgorithms.CLOCKWISE) {
-      if (startAngle <= endAngle) startAngle += 2.0 * Math.PI;
-    }
-    else {    // direction == COUNTERCLOCKWISE
-      if (startAngle >= endAngle) startAngle -= 2.0 * Math.PI;
-    }
-    vertexList.addPt(p0);
-    addFillet(p, startAngle, endAngle, direction, radius);
-    vertexList.addPt(p1);
-  }
-
-  /**
-   * Adds points for a circular fillet arc
-   * between two specified angles.  
-   * The start and end point for the fillet are not added -
-   * the caller must add them if required.
-   *
-   * @param direction is -1 for a CW angle, 1 for a CCW angle
-   * @param radius the radius of the fillet
-   */
-  private void addFillet(Coordinate p, double startAngle, double endAngle, int direction, double radius)
-  {
-    int directionFactor = direction == CGAlgorithms.CLOCKWISE ? -1 : 1;
-
-    double totalAngle = Math.abs(startAngle - endAngle);
-    int nSegs = (int) (totalAngle / filletAngleQuantum + 0.5);
-
-    if (nSegs < 1) return;    // no segments because angle is less than increment - nothing to do!
-
-    double initAngle, currAngleInc;
-
-    // choose angle increment so that each segment has equal length
-    initAngle = 0.0;
-    currAngleInc = totalAngle / nSegs;
-
-    double currAngle = initAngle;
-    Coordinate pt = new Coordinate();
-    while (currAngle < totalAngle) {
-      double angle = startAngle + directionFactor * currAngle;
-      pt.x = p.x + radius * Math.cos(angle);
-      pt.y = p.y + radius * Math.sin(angle);
-      vertexList.addPt(pt);
-      currAngle += currAngleInc;
-    }
-  }
-
-
-  /**
-   * Adds a CW circle around a point
-   */
-  private void addCircle(Coordinate p, double distance)
-  {
-    // add start point
-    Coordinate pt = new Coordinate(p.x + distance, p.y);
-    vertexList.addPt(pt);
-    addFillet(p, 0.0, 2.0 * Math.PI, -1, distance);
-    vertexList.closeRing();
-  }
-
-  /**
-   * Adds a CW square around a point
-   */
-  private void addSquare(Coordinate p, double distance)
-  {
-    // add start point
-  	vertexList.addPt(new Coordinate(p.x + distance, p.y + distance));
-  	vertexList.addPt(new Coordinate(p.x + distance, p.y - distance));
-  	vertexList.addPt(new Coordinate(p.x - distance, p.y - distance));
-  	vertexList.addPt(new Coordinate(p.x - distance, p.y + distance));
-  	vertexList.addPt(new Coordinate(p.x + distance, p.y + distance));
-  }
-}
diff --git a/src/com/vividsolutions/jts/operation/buffer/OffsetCurveBuilder.java b/src/com/vividsolutions/jts/operation/buffer/OffsetCurveBuilder.java
index 5270a22..a610ad8 100644
--- a/src/com/vividsolutions/jts/operation/buffer/OffsetCurveBuilder.java
+++ b/src/com/vividsolutions/jts/operation/buffer/OffsetCurveBuilder.java
@@ -32,10 +32,11 @@
  */
 package com.vividsolutions.jts.operation.buffer;
 
-import java.util.*;
-import com.vividsolutions.jts.geom.*;
-import com.vividsolutions.jts.algorithm.*;
-import com.vividsolutions.jts.geomgraph.*;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateArrays;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.PrecisionModel;
+import com.vividsolutions.jts.geomgraph.Position;
 
 /**
  * Computes the raw offset curve for a
@@ -83,7 +84,7 @@ public class OffsetCurveBuilder
    * @param distance the offset distance
    * 
    * @return a Coordinate array representing the curve
-   * @return null if the curve is empty
+   * or null if the curve is empty
    */
   public Coordinate[] getLineCurve(Coordinate[] inputPts, double distance)
   {
@@ -116,7 +117,7 @@ public class OffsetCurveBuilder
    * as well as rings.
    *
    * @return a Coordinate array representing the curve
-   * @return null if the curve is empty
+   * or null if the curve is empty
    */
   public Coordinate[] getRingCurve(Coordinate[] inputPts, int side, double distance)
   {
diff --git a/src/com/vividsolutions/jts/operation/buffer/OffsetCurveSetBuilder.java b/src/com/vividsolutions/jts/operation/buffer/OffsetCurveSetBuilder.java
index a9022f6..f491a5d 100644
--- a/src/com/vividsolutions/jts/operation/buffer/OffsetCurveSetBuilder.java
+++ b/src/com/vividsolutions/jts/operation/buffer/OffsetCurveSetBuilder.java
@@ -144,6 +144,10 @@ public class OffsetCurveSetBuilder {
     Coordinate[] coord = CoordinateArrays.removeRepeatedPoints(line.getCoordinates());
     Coordinate[] curve = curveBuilder.getLineCurve(coord, distance);
     addCurve(curve, Location.EXTERIOR, Location.INTERIOR);
+
+    // TESTING
+    //Coordinate[] curveTrim = BufferCurveLoopPruner.prune(curve); 
+    //addCurve(curveTrim, Location.EXTERIOR, Location.INTERIOR);
   }
 
   private void addPolygon(Polygon p)
diff --git a/src/com/vividsolutions/jts/operation/buffer/OffsetSegmentGenerator.java b/src/com/vividsolutions/jts/operation/buffer/OffsetSegmentGenerator.java
index b48a956..8b45f17 100644
--- a/src/com/vividsolutions/jts/operation/buffer/OffsetSegmentGenerator.java
+++ b/src/com/vividsolutions/jts/operation/buffer/OffsetSegmentGenerator.java
@@ -42,12 +42,13 @@ import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.LineSegment;
 import com.vividsolutions.jts.geom.PrecisionModel;
 import com.vividsolutions.jts.geomgraph.Position;
+import com.vividsolutions.jts.util.Debug;
 
 /**
  * Generates segments which form an offset curve.
  * Supports all end cap and join options 
  * provided for buffering.
- * Implements various heuristics to 
+ * This algorithm implements various heuristics to 
  * produce smoother, simpler curves which are
  * still within a reasonable tolerance of the 
  * true curve.
@@ -147,8 +148,8 @@ class OffsetSegmentGenerator
    * (relative to the offset distance).
    * In this case the generated offset curve will contain self-intersections
    * and heuristic closing segments.
-   * This is expected behaviour in the case of buffer curves. 
-   * For pure offset curves,
+   * This is expected behaviour in the case of Buffer curves. 
+   * For pure Offset Curves,
    * the output needs to be further treated 
    * before it can be used. 
    * 
@@ -183,7 +184,8 @@ class OffsetSegmentGenerator
 
   public Coordinate[] getCoordinates()
   {
-    return segList.getCoordinates();
+    Coordinate[] pts = segList.getCoordinates();
+    return pts;
   }
   
   public void closeRing()
diff --git a/src/com/vividsolutions/jts/operation/buffer/SubgraphDepthLocater.java b/src/com/vividsolutions/jts/operation/buffer/SubgraphDepthLocater.java
index 35dbcc2..5d60fb7 100644
--- a/src/com/vividsolutions/jts/operation/buffer/SubgraphDepthLocater.java
+++ b/src/com/vividsolutions/jts/operation/buffer/SubgraphDepthLocater.java
@@ -192,7 +192,7 @@ public class SubgraphDepthLocater
      * </pre>
      *
      * @param obj
-     * @return
+     * @return the comparison value
      */
     public int compareTo(Object obj)
     {
diff --git a/src/com/vividsolutions/jts/operation/buffer/validate/BufferDistanceValidator.java b/src/com/vividsolutions/jts/operation/buffer/validate/BufferDistanceValidator.java
index 2990531..d64ba01 100644
--- a/src/com/vividsolutions/jts/operation/buffer/validate/BufferDistanceValidator.java
+++ b/src/com/vividsolutions/jts/operation/buffer/validate/BufferDistanceValidator.java
@@ -129,7 +129,7 @@ public class BufferDistanceValidator
    * of the distance discrepancy.
    * 
    * @return a geometric error indicator
-   * @return null if no error was found
+   * or null if no error was found
    */
   public Geometry getErrorIndicator()
   {
diff --git a/src/com/vividsolutions/jts/operation/buffer/validate/BufferResultValidator.java b/src/com/vividsolutions/jts/operation/buffer/validate/BufferResultValidator.java
index b2548b3..7daddbb 100644
--- a/src/com/vividsolutions/jts/operation/buffer/validate/BufferResultValidator.java
+++ b/src/com/vividsolutions/jts/operation/buffer/validate/BufferResultValidator.java
@@ -75,7 +75,7 @@ public class BufferResultValidator
    * @param distance
    * @param result
    * @return an appropriate error message
-   * @return null if the buffer is valid
+   * or null if the buffer is valid
    */
   public static String isValidMsg(Geometry g, double distance, Geometry result)
   {
@@ -132,7 +132,7 @@ public class BufferResultValidator
    * of the discrepancy.
    * 
    * @return a geometric error indicator
-   * @return null if no error was found
+   * or null if no error was found
    */
   public Geometry getErrorIndicator()
   {
diff --git a/src/com/vividsolutions/jts/operation/distance/DistanceOp.java b/src/com/vividsolutions/jts/operation/distance/DistanceOp.java
index 09f5248..fec6410 100644
--- a/src/com/vividsolutions/jts/operation/distance/DistanceOp.java
+++ b/src/com/vividsolutions/jts/operation/distance/DistanceOp.java
@@ -149,7 +149,7 @@ public class DistanceOp
    * Report the distance between the nearest points on the input geometries.
    *
    * @return the distance between the geometries
-   * @return 0 if either input geometry is empty
+   * or 0 if either input geometry is empty
    * @throws IllegalArgumentException if either input geometry is null
    */
   public double distance()
diff --git a/src/com/vividsolutions/jts/operation/distance/FacetSequence.java b/src/com/vividsolutions/jts/operation/distance/FacetSequence.java
index b2a4a2d..3395cfd 100644
--- a/src/com/vividsolutions/jts/operation/distance/FacetSequence.java
+++ b/src/com/vividsolutions/jts/operation/distance/FacetSequence.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.operation.distance;
 
 import com.vividsolutions.jts.algorithm.CGAlgorithms;
diff --git a/src/com/vividsolutions/jts/operation/distance/FacetSequenceTreeBuilder.java b/src/com/vividsolutions/jts/operation/distance/FacetSequenceTreeBuilder.java
index 0d360ac..448d1a5 100644
--- a/src/com/vividsolutions/jts/operation/distance/FacetSequenceTreeBuilder.java
+++ b/src/com/vividsolutions/jts/operation/distance/FacetSequenceTreeBuilder.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.operation.distance;
 
 import java.util.ArrayList;
@@ -70,4 +103,4 @@ public class FacetSequenceTreeBuilder {
       i = i + FACET_SEQUENCE_SIZE;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/operation/distance/IndexedFacetDistance.java b/src/com/vividsolutions/jts/operation/distance/IndexedFacetDistance.java
index ba348e2..b9f4b99 100644
--- a/src/com/vividsolutions/jts/operation/distance/IndexedFacetDistance.java
+++ b/src/com/vividsolutions/jts/operation/distance/IndexedFacetDistance.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.operation.distance;
 
 import com.vividsolutions.jts.geom.Geometry;
@@ -125,9 +158,9 @@ public class IndexedFacetDistance
    * Tests whether the base geometry lies within
    * a specified distance of the given geometry.
    * 
-   * @param g the geomtry to test
-   * @param maximumDistance the maximum distance to test
-   * @return true if the geometry lies with the specified distance
+//   * @param g the geometry to test
+//   * @param maximumDistance the maximum distance to test
+//   * @return true if the geometry lies with the specified distance
    */
   // TODO: implement this
   /*
diff --git a/src/com/vividsolutions/jts/operation/distance3d/AxisPlaneCoordinateSequence.java b/src/com/vividsolutions/jts/operation/distance3d/AxisPlaneCoordinateSequence.java
new file mode 100644
index 0000000..3cee2c2
--- /dev/null
+++ b/src/com/vividsolutions/jts/operation/distance3d/AxisPlaneCoordinateSequence.java
@@ -0,0 +1,159 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
+package com.vividsolutions.jts.operation.distance3d;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.Envelope;
+
+/**
+ * A CoordinateSequence wrapper which 
+ * projects 3D coordinates into one of the
+ * three Cartesian axis planes,
+ * using the standard orthonormal projection
+ * (i.e. simply selecting the appropriate ordinates into the XY ordinates).
+ * The projected data is represented as 2D coordinates.
+ * 
+ * @author mdavis
+ *
+ */
+public class AxisPlaneCoordinateSequence implements CoordinateSequence {
+
+	/**
+	 * Creates a wrapper projecting to the XY plane.
+	 * 
+	 * @param seq the sequence to be projected
+	 * @return a sequence which projects coordinates
+	 */
+	public static CoordinateSequence projectToXY(CoordinateSequence seq)
+	{
+		/**
+		 * This is just a no-op, but return a wrapper
+		 * to allow better testing
+		 */
+		return new AxisPlaneCoordinateSequence(seq, XY_INDEX);
+	}
+	
+	/**
+	 * Creates a wrapper projecting to the XZ plane.
+	 * 
+	 * @param seq the sequence to be projected
+	 * @return a sequence which projects coordinates
+	 */
+	public static CoordinateSequence projectToXZ(CoordinateSequence seq)
+	{
+		return new AxisPlaneCoordinateSequence(seq, XZ_INDEX);
+	}
+	
+	/**
+	 * Creates a wrapper projecting to the YZ plane.
+	 * 
+	 * @param seq the sequence to be projected
+	 * @return a sequence which projects coordinates
+	 */
+	public static CoordinateSequence projectToYZ(CoordinateSequence seq)
+	{
+		return new AxisPlaneCoordinateSequence(seq, YZ_INDEX);
+	}
+	
+	private static int[] XY_INDEX = new int[] { 0,1 };
+	private static int[] XZ_INDEX = new int[] { 0,2 };
+	private static int[] YZ_INDEX = new int[] { 1,2 };
+	
+	private CoordinateSequence seq;
+	private int[] indexMap;
+	
+	private AxisPlaneCoordinateSequence(CoordinateSequence seq, int[] indexMap) {
+		this.seq = seq;
+		this.indexMap = indexMap;
+	}
+
+	public int getDimension() {
+		return 2;
+	}
+
+	public Coordinate getCoordinate(int i) {
+		return getCoordinateCopy(i);
+	}
+
+	public Coordinate getCoordinateCopy(int i) {
+		return new Coordinate(getX(i), getY(i), getZ(i));
+	}
+
+	public void getCoordinate(int index, Coordinate coord) {
+		coord.x = getOrdinate(index, X);
+		coord.y = getOrdinate(index, Y);
+		coord.z = getOrdinate(index, Z);
+	}
+
+	public double getX(int index) {
+		return getOrdinate(index, X);
+	}
+
+	public double getY(int index) {
+		return getOrdinate(index, Y);
+	}
+
+	public double getZ(int index) {
+		return getOrdinate(index, Z);
+	}
+
+	public double getOrdinate(int index, int ordinateIndex) {
+		// Z ord is always 0
+		if (ordinateIndex > 1) return 0;
+		return seq.getOrdinate(index, indexMap[ordinateIndex]);
+	}
+
+	public int size() {
+		return seq.size();
+	}
+
+	public void setOrdinate(int index, int ordinateIndex, double value) {
+		throw new UnsupportedOperationException();
+	}
+
+	public Coordinate[] toCoordinateArray() {
+		throw new UnsupportedOperationException();
+	}
+
+	public Envelope expandEnvelope(Envelope env) {
+		throw new UnsupportedOperationException();
+	}
+
+	public Object clone()
+	{
+		throw new UnsupportedOperationException();		
+	}
+
+}
diff --git a/src/com/vividsolutions/jts/operation/distance3d/Distance3DOp.java b/src/com/vividsolutions/jts/operation/distance3d/Distance3DOp.java
new file mode 100644
index 0000000..8baed30
--- /dev/null
+++ b/src/com/vividsolutions/jts/operation/distance3d/Distance3DOp.java
@@ -0,0 +1,583 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.distance3d;
+
+import com.vividsolutions.jts.algorithm.CGAlgorithms3D;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.LineSegment;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.operation.distance.GeometryLocation;
+
+/**
+ * Find two points on two {@link Geometry}s which lie within a given distance,
+ * or else are the nearest points on the geometries (in which case this also
+ * provides the distance between the geometries).
+ * <p>
+ * The distance computation also finds a pair of points in the input geometries
+ * which have the minimum distance between them. If a point lies in the interior
+ * of a line segment, the coordinate computed is a close approximation to the
+ * exact point.
+ * <p>
+ * The algorithms used are straightforward O(n^2) comparisons. This worst-case
+ * performance could be improved on by using Voronoi techniques or spatial
+ * indexes.
+ * 
+ * @version 1.7
+ */
+public class Distance3DOp {
+	/**
+	 * Compute the distance between the nearest points of two geometries.
+	 * 
+	 * @param g0
+	 *            a {@link Geometry}
+	 * @param g1
+	 *            another {@link Geometry}
+	 * @return the distance between the geometries
+	 */
+	public static double distance(Geometry g0, Geometry g1) {
+		Distance3DOp distOp = new Distance3DOp(g0, g1);
+		return distOp.distance();
+	}
+
+	/**
+	 * Test whether two geometries lie within a given distance of each other.
+	 * 
+	 * @param g0
+	 *            a {@link Geometry}
+	 * @param g1
+	 *            another {@link Geometry}
+	 * @param distance
+	 *            the distance to test
+	 * @return true if g0.distance(g1) <= distance
+	 */
+	public static boolean isWithinDistance(Geometry g0, Geometry g1,
+			double distance) {
+		Distance3DOp distOp = new Distance3DOp(g0, g1, distance);
+		return distOp.distance() <= distance;
+	}
+
+	/**
+	 * Compute the the nearest points of two geometries. The points are
+	 * presented in the same order as the input Geometries.
+	 * 
+	 * @param g0
+	 *            a {@link Geometry}
+	 * @param g1
+	 *            another {@link Geometry}
+	 * @return the nearest points in the geometries
+	 */
+	public static Coordinate[] nearestPoints(Geometry g0, Geometry g1) {
+		Distance3DOp distOp = new Distance3DOp(g0, g1);
+		return distOp.nearestPoints();
+	}
+
+	// input
+	private Geometry[] geom;
+	private double terminateDistance = 0.0;
+	// working
+	private GeometryLocation[] minDistanceLocation;
+	private double minDistance = Double.MAX_VALUE;
+	private boolean isDone = false;
+
+	/**
+	 * Constructs a DistanceOp that computes the distance and nearest points
+	 * between the two specified geometries.
+	 * 
+	 * @param g0
+	 *            a Geometry
+	 * @param g1
+	 *            a Geometry
+	 */
+	public Distance3DOp(Geometry g0, Geometry g1) {
+		this(g0, g1, 0.0);
+	}
+
+	/**
+	 * Constructs a DistanceOp that computes the distance and nearest points
+	 * between the two specified geometries.
+	 * 
+	 * @param g0
+	 *            a Geometry
+	 * @param g1
+	 *            a Geometry
+	 * @param terminateDistance
+	 *            the distance on which to terminate the search
+	 */
+	public Distance3DOp(Geometry g0, Geometry g1, double terminateDistance) {
+		this.geom = new Geometry[2];
+		geom[0] = g0;
+		geom[1] = g1;
+		this.terminateDistance = terminateDistance;
+	}
+
+	/**
+	 * Report the distance between the nearest points on the input geometries.
+	 * 
+	 * @return the distance between the geometries, or 0 if either input geometry is empty
+	 * @throws IllegalArgumentException
+	 *             if either input geometry is null
+	 */
+	public double distance() {
+		if (geom[0] == null || geom[1] == null)
+			throw new IllegalArgumentException(
+					"null geometries are not supported");
+		if (geom[0].isEmpty() || geom[1].isEmpty())
+			return 0.0;
+
+		computeMinDistance();
+		return minDistance;
+	}
+
+	/**
+	 * Report the coordinates of the nearest points in the input geometries. The
+	 * points are presented in the same order as the input Geometries.
+	 * 
+	 * @return a pair of {@link Coordinate}s of the nearest points
+	 */
+	public Coordinate[] nearestPoints() {
+		computeMinDistance();
+		Coordinate[] nearestPts = new Coordinate[] {
+				minDistanceLocation[0].getCoordinate(),
+				minDistanceLocation[1].getCoordinate() };
+		return nearestPts;
+	}
+
+	/**
+	 * Report the locations of the nearest points in the input geometries. The
+	 * locations are presented in the same order as the input Geometries.
+	 * 
+	 * @return a pair of {@link GeometryLocation}s for the nearest points
+	 */
+	public GeometryLocation[] nearestLocations() {
+		computeMinDistance();
+		return minDistanceLocation;
+	}
+
+	private void updateDistance(double dist,
+			GeometryLocation loc0, GeometryLocation loc1,
+			boolean flip) {
+		this.minDistance = dist;
+		int index = flip ? 1 : 0;
+		minDistanceLocation[index] = loc0;
+		minDistanceLocation[1-index] = loc1;
+		if (minDistance < terminateDistance)
+			isDone = true;
+	}
+
+	private void computeMinDistance() {
+		// only compute once
+		if (minDistanceLocation != null)
+			return;
+		minDistanceLocation = new GeometryLocation[2];
+		
+		int geomIndex = mostPolygonalIndex();
+		boolean flip = geomIndex == 0;
+		computeMinDistanceMultiMulti(geom[geomIndex], geom[1-geomIndex], flip);
+	}
+
+	/**
+	 * Finds the index of the "most polygonal" input geometry.
+	 * This optimizes the computation of the best-fit plane, 
+	 * since it is cached only for the left-hand geometry.
+	 * 
+	 * @return the index of the most polygonal geometry
+	 */
+	private int mostPolygonalIndex() {
+		int dim0 = geom[0].getDimension();
+		int dim1 = geom[1].getDimension();
+		if (dim0 >= 2 && dim1 >= 2) {
+			if (geom[0].getNumPoints() > geom[1].getNumPoints())
+				return 0;
+			return 1;
+		}
+		// no more than one is dim 2
+		if (dim0 >= 2) return 0;
+		if (dim1 >= 2) return 1;
+		// both dim <= 1 - don't flip
+		return 0;
+	}
+
+	private void computeMinDistanceMultiMulti(Geometry g0, Geometry g1, boolean flip) {
+		if (g0 instanceof GeometryCollection) {
+			int n = g0.getNumGeometries();
+			for (int i = 0; i < n; i++) {
+				Geometry g = g0.getGeometryN(i);
+				computeMinDistanceMultiMulti(g, g1, flip);
+				if (isDone)	return;
+			}
+		}
+		else {
+			// handle case of multigeom component being empty
+			if (g0.isEmpty())
+				return;
+			
+			// compute planar polygon only once for efficiency
+			if (g0 instanceof Polygon) {
+				computeMinDistanceOneMulti(polyPlane(g0), g1, flip);
+			}
+			else 
+				computeMinDistanceOneMulti(g0, g1, flip);
+		}
+	}
+	
+	private void computeMinDistanceOneMulti(Geometry g0, Geometry g1, boolean flip) {
+		if (g1 instanceof GeometryCollection) {
+			int n = g1.getNumGeometries();
+			for (int i = 0; i < n; i++) {
+				Geometry g = g1.getGeometryN(i);
+				computeMinDistanceOneMulti(g0, g, flip);
+				if (isDone)	return;
+			}
+		}
+		else {
+			computeMinDistance(g0, g1, flip);
+		}
+	}
+
+	private void computeMinDistanceOneMulti(PlanarPolygon3D poly, Geometry geom, boolean flip) {
+		if (geom instanceof GeometryCollection) {
+			int n = geom.getNumGeometries();
+			for (int i = 0; i < n; i++) {
+				Geometry g = geom.getGeometryN(i);
+				computeMinDistanceOneMulti(poly, g, flip);
+				if (isDone)	return;
+			}
+		}
+		else {
+			if (geom instanceof Point) {
+				computeMinDistancePolygonPoint(poly, (Point) geom, flip);
+				return;
+			}
+			if (geom instanceof LineString) {
+				computeMinDistancePolygonLine(poly, (LineString) geom, flip);
+				return;
+			}
+			if (geom instanceof Polygon) {
+				computeMinDistancePolygonPolygon(poly, (Polygon) geom, flip);
+				return;
+			}
+		}
+	}
+
+	/**
+	 * Convenience method to create a Plane3DPolygon
+	 * @param poly
+	 * @return
+	 */
+	private static PlanarPolygon3D polyPlane(Geometry poly)
+	{
+		return new PlanarPolygon3D((Polygon) poly);
+	}
+	
+	private void computeMinDistance(Geometry g0, Geometry g1, boolean flip) {
+		if (g0 instanceof Point) {
+			if (g1 instanceof Point) {
+				computeMinDistancePointPoint((Point) g0, (Point) g1, flip);
+				return;
+			}
+			if (g1 instanceof LineString) {
+				computeMinDistanceLinePoint((LineString) g1, (Point) g0, ! flip);
+				return;
+			}
+			if (g1 instanceof Polygon) {
+				computeMinDistancePolygonPoint(polyPlane(g1), (Point) g0, ! flip);
+				return;
+			}
+		}
+		if (g0 instanceof LineString) {
+			if (g1 instanceof Point) {
+				computeMinDistanceLinePoint((LineString) g0, (Point) g1, flip);
+				return;
+			}
+			if (g1 instanceof LineString) {
+				computeMinDistanceLineLine((LineString) g0, (LineString) g1, flip);
+				return;
+			}
+			if (g1 instanceof Polygon) {
+				computeMinDistancePolygonLine(polyPlane(g1), (LineString) g0, ! flip);
+				return;
+			}
+		}
+		if (g0 instanceof Polygon) {
+			if (g1 instanceof Point) {
+				computeMinDistancePolygonPoint(polyPlane(g0), (Point) g1, flip);
+				return;
+			}
+			if (g1 instanceof LineString) {
+				computeMinDistancePolygonLine(polyPlane(g0), (LineString) g1, flip);
+				return;
+			}
+			if (g1 instanceof Polygon) {
+				computeMinDistancePolygonPolygon(polyPlane(g0), (Polygon) g1, flip);
+				return;
+			}
+		}
+	}
+
+	/**
+	 * Computes distance between two polygons.
+	 * 
+	 * To compute the distance, compute the distance
+	 * between the rings of one polygon and the other polygon,
+	 * and vice-versa.
+	 * If the polygons intersect, then at least one ring must
+	 * intersect the other polygon.
+	 * Note that it is NOT sufficient to test only the shell rings. 
+	 * A counter-example is a "figure-8" polygon A 
+	 * and a simple polygon B at right angles to A, with the ring of B
+	 * passing through the holes of A.
+	 * The polygons intersect,
+	 * but A's shell does not intersect B, and B's shell does not intersect A.
+	 *  
+	 * @param poly0
+	 * @param poly1
+	 * @param geomIndex
+	 */
+	private void computeMinDistancePolygonPolygon(PlanarPolygon3D poly0, Polygon poly1,
+			boolean flip) {
+		computeMinDistancePolygonRings(poly0, poly1, flip);
+		if (isDone) return;
+		PlanarPolygon3D polyPlane1 = new PlanarPolygon3D(poly1);
+		computeMinDistancePolygonRings(polyPlane1, poly0.getPolygon(), flip);
+	}
+
+	/**
+	 * Compute distance between a polygon and the rings of another.
+	 * 
+	 * @param poly
+	 * @param ringPoly
+	 * @param geomIndex
+	 */
+	private void computeMinDistancePolygonRings(PlanarPolygon3D poly, Polygon ringPoly,
+			boolean flip) {
+		// compute shell ring
+		computeMinDistancePolygonLine(poly, ringPoly.getExteriorRing(), flip);
+		if (isDone) return;
+		// compute hole rings
+		int nHole = ringPoly.getNumInteriorRing();
+		for (int i = 0; i < nHole; i++) {
+			computeMinDistancePolygonLine(poly, ringPoly.getInteriorRingN(i), flip);
+			if (isDone) return;
+		}
+	}
+
+	private void computeMinDistancePolygonLine(PlanarPolygon3D poly,LineString line, 
+			boolean flip) {
+		
+		// first test if line intersects polygon
+		Coordinate intPt = intersection(poly, line);
+		if (intPt != null) {
+			updateDistance(0,
+					new GeometryLocation(poly.getPolygon(), 0, intPt),
+					new GeometryLocation(line, 0, intPt),
+					flip
+			);
+			return;
+		}
+		
+		// if no intersection, then compute line distance to polygon rings
+		computeMinDistanceLineLine(poly.getPolygon().getExteriorRing(), line, flip);
+		if (isDone) return;
+		int nHole = poly.getPolygon().getNumInteriorRing();
+		for (int i = 0; i < nHole; i++) {
+			computeMinDistanceLineLine(poly.getPolygon().getInteriorRingN(i), line, flip);
+			if (isDone) return;
+		}
+	}
+
+	private Coordinate intersection(PlanarPolygon3D poly,LineString line) {
+		CoordinateSequence seq = line.getCoordinateSequence();
+		if (seq.size() == 0)
+			return null;
+
+		// start point of line
+		Coordinate p0 = new Coordinate();
+		seq.getCoordinate(0, p0);
+		double d0 = poly.getPlane().orientedDistance(p0);
+		
+		// for each segment in the line
+		Coordinate p1 = new Coordinate();
+		for (int i = 0; i < seq.size() - 1; i++) {
+			seq.getCoordinate(i, p0);
+			seq.getCoordinate(i + 1, p1);
+			double d1 = poly.getPlane().orientedDistance(p1);
+
+			/**
+			 * If the oriented distances of the segment endpoints have the same sign, 
+			 * the segment does not cross the plane, and is skipped.
+			 */
+			if (d0 * d1 > 0)
+				continue;
+
+			/**
+			 * Compute segment-plane intersection point
+			 * which is then used for a point-in-polygon test.
+			 * The endpoint distances to the plane d0 and d1 
+			 * give the proportional distance of the intersection point 
+			 * along the segment.
+			 */
+			Coordinate intPt = segmentPoint(p0, p1, d0, d1);
+			// Coordinate intPt = polyPlane.intersection(p0, p1, s0, s1);
+			if (poly.intersects(intPt)) {
+				return intPt;
+			}
+
+			// shift to next segment
+			d0 = d1;
+		}
+		return null;
+	}
+
+	private void computeMinDistancePolygonPoint(PlanarPolygon3D polyPlane, Point point, 
+			boolean flip) {
+		Coordinate pt = point.getCoordinate();
+		
+		LineString shell = polyPlane.getPolygon().getExteriorRing();
+		if (polyPlane.intersects(pt, shell)) {
+			// point is either inside or in a hole
+			
+			int nHole = polyPlane.getPolygon().getNumInteriorRing();
+			for (int i = 0; i < nHole; i++) {
+				LineString hole = polyPlane.getPolygon().getInteriorRingN(i);
+				if (polyPlane.intersects(pt, hole)) {
+					computeMinDistanceLinePoint(hole, point, flip);
+					return;
+				}
+			}
+			// point is in interior of polygon
+			// distance is distance to polygon plane
+			double dist = Math.abs(polyPlane.getPlane().orientedDistance(pt));
+			updateDistance(dist,
+					new GeometryLocation(polyPlane.getPolygon(), 0, pt),
+					new GeometryLocation(point, 0, pt),
+					flip
+			);
+		}
+		// point is outside polygon, so compute distance to shell linework
+		computeMinDistanceLinePoint(shell, point, flip);
+	}
+
+	private void computeMinDistanceLineLine(LineString line0, LineString line1,
+			boolean flip) {
+		Coordinate[] coord0 = line0.getCoordinates();
+		Coordinate[] coord1 = line1.getCoordinates();
+		// brute force approach!
+		for (int i = 0; i < coord0.length - 1; i++) {
+			for (int j = 0; j < coord1.length - 1; j++) {
+				double dist = CGAlgorithms3D.distanceSegmentSegment(coord0[i],
+						coord0[i + 1], coord1[j], coord1[j + 1]);
+				if (dist < minDistance) {
+					minDistance = dist;
+					// TODO: compute closest pts in 3D
+					LineSegment seg0 = new LineSegment(coord0[i], coord0[i + 1]);
+					LineSegment seg1 = new LineSegment(coord1[j], coord1[j + 1]);
+					Coordinate[] closestPt = seg0.closestPoints(seg1);
+					updateDistance(dist,
+							new GeometryLocation(line0, i, closestPt[0]),
+							new GeometryLocation(line1, j, closestPt[1]),
+							flip
+					);
+				}
+				if (isDone)	return;
+			}
+		}
+	}
+
+	private void computeMinDistanceLinePoint(LineString line,Point point, 
+			boolean flip) {
+		Coordinate[] lineCoord = line.getCoordinates();
+		Coordinate coord = point.getCoordinate();
+		// brute force approach!
+		for (int i = 0; i < lineCoord.length - 1; i++) {
+			double dist = CGAlgorithms3D.distancePointSegment(coord, lineCoord[i],
+					lineCoord[i + 1]);
+			if (dist < minDistance) {
+				LineSegment seg = new LineSegment(lineCoord[i], lineCoord[i + 1]);
+				Coordinate segClosestPoint = seg.closestPoint(coord);
+				updateDistance(dist,
+						new GeometryLocation(line, i, segClosestPoint),
+						new GeometryLocation(point, 0, coord),
+						flip);
+			}
+			if (isDone)	return;
+		}
+	}
+
+	private void computeMinDistancePointPoint(Point point0, Point point1, boolean flip) {
+		double dist = CGAlgorithms3D.distance(
+				point0.getCoordinate(),
+				point1.getCoordinate());
+		if (dist < minDistance) {
+			updateDistance(dist,
+					new GeometryLocation(point0, 0,	point0.getCoordinate()),
+					new GeometryLocation(point1, 0,	point1.getCoordinate()),
+					flip);
+		}
+	}
+
+	/**
+	 * Computes a point at a distance along a segment
+	 * specified by two relatively proportional values. 
+	 * The fractional distance along the segment is d0/(d0+d1).
+	 * 
+	 * @param p0
+	 *            start point of the segment
+	 * @param p1
+	 *            end point of the segment
+	 * @param d0
+	 *            proportional distance from start point to computed point
+	 * @param d1
+	 *            proportional distance from computed point to end point
+	 * @return the computed point
+	 */
+	private static Coordinate segmentPoint(Coordinate p0, Coordinate p1, double d0,
+			double d1) {
+		if (d0 <= 0) return new Coordinate(p0);
+		if (d1 <= 0) return new Coordinate(p1);
+		
+		double f = Math.abs(d0) / (Math.abs(d0) + Math.abs(d1));
+		double intx = p0.x + f * (p1.x - p0.x);
+		double inty = p0.y + f * (p1.y - p0.y);
+		double intz = p0.z + f * (p1.z - p0.z);
+		return new Coordinate(intx, inty, intz);
+	}
+
+
+
+
+}
diff --git a/src/com/vividsolutions/jts/operation/distance3d/PlanarPolygon3D.java b/src/com/vividsolutions/jts/operation/distance3d/PlanarPolygon3D.java
new file mode 100644
index 0000000..73e8e03
--- /dev/null
+++ b/src/com/vividsolutions/jts/operation/distance3d/PlanarPolygon3D.java
@@ -0,0 +1,195 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
+package com.vividsolutions.jts.operation.distance3d;
+
+import com.vividsolutions.jts.algorithm.RayCrossingCounter;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.Location;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.math.Plane3D;
+import com.vividsolutions.jts.math.Vector3D;
+
+/**
+ * Models a polygon lying in a plane in 3-dimensional Cartesian space.
+ * The polyogn representation is supplied
+ * by a {@link Polygon},
+ * containing coordinates with XYZ ordinates.
+ * 3D polygons are assumed to lie in a single plane.
+ * The plane best fitting the polygon coordinates is
+ * computed and is represented by a {@link Plane3D}.
+ * 
+ * @author mdavis
+ *
+ */
+public class PlanarPolygon3D {
+
+	private Plane3D plane;
+	private Polygon poly;
+	private int facingPlane = -1;
+
+	public PlanarPolygon3D(Polygon poly) {
+		this.poly = poly;
+		plane = findBestFitPlane(poly);
+		facingPlane = plane.closestAxisPlane();
+	}
+
+	/**
+	 * Finds a best-fit plane for the polygon, 
+	 * by sampling a few points from the exterior ring.
+	 * <p>
+	 * The algorithm used is Newell's algorithm:
+	 * - a base point for the plane is determined from the average of all vertices
+	 * - the normal vector is determined by
+	 *   computing the area of the projections on each of the axis planes
+	 * 
+	 * @param poly the polygon to determine the plane for
+	 * @return the best-fit plane
+	 */
+	private Plane3D findBestFitPlane(Polygon poly) 
+	{
+		CoordinateSequence seq = poly.getExteriorRing().getCoordinateSequence();
+		Coordinate basePt = averagePoint(seq);
+		Vector3D normal = averageNormal(seq);
+		return new Plane3D(normal, basePt);
+	}
+
+	/**
+	 * Computes an average normal vector from a list of polygon coordinates.
+	 * Uses Newell's method, which is based
+	 * on the fact that the vector with components
+	 * equal to the areas of the projection of the polygon onto 
+	 * the Cartesian axis planes is normal.
+	 * 
+	 * @param seq the sequence of coordinates for the polygon
+	 * @return a normal vector
+	 */
+	private Vector3D averageNormal(CoordinateSequence seq) 
+	{
+		int n = seq.size();
+		Coordinate sum = new Coordinate(0,0,0);
+		Coordinate p1 = new Coordinate(0,0,0);
+		Coordinate p2 = new Coordinate(0,0,0);
+		for (int i = 0; i < n - 1; i++) {
+			seq.getCoordinate(i, p1);
+			seq.getCoordinate(i+1, p2);
+			sum.x += (p1.y - p2.y)*(p1.z + p2.z);
+			sum.y += (p1.z - p2.z)*(p1.x + p2.x);
+			sum.z += (p1.x - p2.x)*(p1.y + p2.y);
+		}
+		sum.x /= n;
+		sum.y /= n;
+		sum.z /= n;
+		Vector3D norm = Vector3D.create(sum).normalize();
+		return norm;
+	}
+
+	/**
+	 * Computes a point which is the average of all coordinates
+	 * in a sequence.
+	 * If the sequence lies in a single plane,
+	 * the computed point also lies in the plane.
+	 * 
+	 * @param seq a coordinate sequence
+	 * @return a Coordinate with averaged ordinates
+	 */
+	private Coordinate averagePoint(CoordinateSequence seq) {
+		Coordinate a = new Coordinate(0,0,0);
+		int n = seq.size();
+		for (int i = 0; i < n; i++) {
+			a.x += seq.getOrdinate(i, CoordinateSequence.X);
+			a.y += seq.getOrdinate(i, CoordinateSequence.Y);
+			a.z += seq.getOrdinate(i, CoordinateSequence.Z);
+		}
+		a.x /= n;
+		a.y /= n;
+		a.z /= n;
+		return a;
+	}
+
+	public Plane3D getPlane() {
+		return plane;
+	}
+
+	public Polygon getPolygon() {
+		return poly;
+	}
+
+	public boolean intersects(Coordinate intPt) {
+		if (Location.EXTERIOR == locate(intPt, poly.getExteriorRing()))
+			return false;
+		
+		for (int i = 0; i < poly.getNumInteriorRing(); i++) {
+			if (Location.INTERIOR == locate(intPt, poly.getInteriorRingN(i)))
+				return false;
+		}
+		return true;
+	}
+
+	private int locate(Coordinate pt, LineString ring) {
+		CoordinateSequence seq = ring.getCoordinateSequence();
+		CoordinateSequence seqProj = project(seq, facingPlane);
+		Coordinate ptProj = project(pt, facingPlane);
+		return RayCrossingCounter.locatePointInRing(ptProj, seqProj);
+	}
+	
+	public boolean intersects(Coordinate pt, LineString ring) {
+		CoordinateSequence seq = ring.getCoordinateSequence();
+		CoordinateSequence seqProj = project(seq, facingPlane);
+		Coordinate ptProj = project(pt, facingPlane);
+		return Location.EXTERIOR != RayCrossingCounter.locatePointInRing(ptProj, seqProj);
+	}
+	
+	private static CoordinateSequence project(CoordinateSequence seq, int facingPlane)
+	{
+		switch (facingPlane) {
+		case Plane3D.XY_PLANE: return AxisPlaneCoordinateSequence.projectToXY(seq);
+		case Plane3D.XZ_PLANE: return AxisPlaneCoordinateSequence.projectToXZ(seq);
+		default: return AxisPlaneCoordinateSequence.projectToYZ(seq);
+		}
+	}
+	
+	private static Coordinate project(Coordinate p, int facingPlane)
+	{
+		switch (facingPlane) {
+		case Plane3D.XY_PLANE: return new Coordinate(p.x, p.y);
+		case Plane3D.XZ_PLANE: return new Coordinate(p.x, p.z);
+		// Plane3D.YZ
+		default: return new Coordinate(p.y, p.z);
+		}
+	}
+	
+
+}
diff --git a/src/com/vividsolutions/jts/operation/linemerge/LineMergeDirectedEdge.java b/src/com/vividsolutions/jts/operation/linemerge/LineMergeDirectedEdge.java
index c056f35..00a104e 100644
--- a/src/com/vividsolutions/jts/operation/linemerge/LineMergeDirectedEdge.java
+++ b/src/com/vividsolutions/jts/operation/linemerge/LineMergeDirectedEdge.java
@@ -64,7 +64,7 @@ public class LineMergeDirectedEdge extends DirectedEdge {
   /**
    * Returns the directed edge that starts at this directed edge's end point, or null
    * if there are zero or multiple directed edges starting there.  
-   * @return
+   * @return the directed edge
    */
   public LineMergeDirectedEdge getNext() {
     if (getToNode().getDegree() != 2) {
diff --git a/src/com/vividsolutions/jts/operation/linemerge/LineSequencer.java b/src/com/vividsolutions/jts/operation/linemerge/LineSequencer.java
index e2f3c5e..9cf35e9 100644
--- a/src/com/vividsolutions/jts/operation/linemerge/LineSequencer.java
+++ b/src/com/vividsolutions/jts/operation/linemerge/LineSequencer.java
@@ -76,7 +76,7 @@ import com.vividsolutions.jts.util.Assert;
  * For a connected set of edges in a graph,
  * <i>Euler's Theorem</i> states that there is a sequence containing each edge once
  * <b>if and only if</b> there are no more than 2 nodes of odd degree.
- * If it is not possible to find a sequence, the {@link #isSequenceable} method
+ * If it is not possible to find a sequence, the {@link #isSequenceable()} method
  * will return <code>false</code>.
  *
  * @version 1.7
diff --git a/src/com/vividsolutions/jts/operation/overlay/ConsistentPolygonRingChecker.java b/src/com/vividsolutions/jts/operation/overlay/ConsistentPolygonRingChecker.java
index 3b02caf..182b1c7 100644
--- a/src/com/vividsolutions/jts/operation/overlay/ConsistentPolygonRingChecker.java
+++ b/src/com/vividsolutions/jts/operation/overlay/ConsistentPolygonRingChecker.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.operation.overlay;
 
 import java.util.*;
@@ -124,4 +157,4 @@ public class ConsistentPolygonRingChecker
 
 
 
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/operation/overlay/OverlayOp.java b/src/com/vividsolutions/jts/operation/overlay/OverlayOp.java
index 8e5f724..13bc41f 100644
--- a/src/com/vividsolutions/jts/operation/overlay/OverlayOp.java
+++ b/src/com/vividsolutions/jts/operation/overlay/OverlayOp.java
@@ -544,19 +544,40 @@ public class OverlayOp
     geomList.addAll(resultLineList);
     geomList.addAll(resultPolyList);
     
-    /*
+    //*
     if (geomList.isEmpty())
-    	return createEmptyResult(opcode);
-    */
+    	return createEmptyResult(opcode, arg[0].getGeometry(), arg[1].getGeometry(), geomFact);
+    //*/
     
     // build the most specific geometry possible
     return geomFact.buildGeometry(geomList);
   }
 
-  private Geometry createEmptyResult(int opCode)
+  /**
+   * Creates an empty result geometry of the appropriate dimension,
+   * based on the dimensions of the inputs.
+   * The created geometry is always an atomic geometry, 
+   * not a collection.
+   * <p>
+   * Implements the following rules:
+   * <ul>
+   * <li><code>intersection</code> - result has the dimension of the lowest input dimension
+   * <li><code>union</code> - result has the dimension of the highest input dimension
+   * <li><code>difference</code> - result has the dimension of the left-hand input
+   * <li><code>symDifference</code> - result has the dimension of the highest input dimension
+   * (since symDifference is the union of the differences).
+   * <li>
+   * 
+   * @param opCode the overlay operation being performed
+   * @param a an input geometry
+   * @param b an input geometry
+   * @param geomFact the geometry factory being used for the operation
+   * @return an empty atomic geometry of the appropriate dimension
+   */
+  public static Geometry createEmptyResult(int opCode, Geometry a, Geometry b, GeometryFactory geomFact)
   {
   	Geometry result = null;
-  	switch (resultDimension(opCode, arg[0].getGeometry(), arg[1].getGeometry())) {
+  	switch (resultDimension(opCode, a, b)) {
   	case -1:
   		result = geomFact.createGeometryCollection(new Geometry[0]);
   		break;
@@ -573,7 +594,7 @@ public class OverlayOp
 		return result;
   }
   
-  private int resultDimension(int opCode, Geometry g0, Geometry g1)
+  private static int resultDimension(int opCode, Geometry g0, Geometry g1)
   {
   	int dim0 = g0.getDimension();
   	int dim1 = g1.getDimension();
@@ -590,6 +611,13 @@ public class OverlayOp
   		resultDimension = dim0;
   		break;
   	case SYMDIFFERENCE: 
+  	  /**
+  	   * This result is chosen because
+  	   * <pre>
+  	   * SymDiff = Union(Diff(A, B), Diff(B, A)
+  	   * </pre>
+  	   * and Union has the dimension of the highest-dimension argument.
+  	   */
   		resultDimension = Math.max(dim0, dim1);
   		break;
   	}
diff --git a/src/com/vividsolutions/jts/operation/overlay/PolygonBuilder.java b/src/com/vividsolutions/jts/operation/overlay/PolygonBuilder.java
index bd2ec6f..493e850 100644
--- a/src/com/vividsolutions/jts/operation/overlay/PolygonBuilder.java
+++ b/src/com/vividsolutions/jts/operation/overlay/PolygonBuilder.java
@@ -144,7 +144,7 @@ public class PolygonBuilder {
    * no shell is returned.
    *
    * @return the shell EdgeRing, if there is one
-   * @return null, if all the rings are holes
+   * or null, if all the rings are holes
    */
   private EdgeRing findShell(List minEdgeRings)
   {
@@ -240,7 +240,7 @@ public class PolygonBuilder {
    * (which is guaranteed to be the case if the hole does not touch its shell)
    *
    * @return containing EdgeRing, if there is one
-   * @return null if no containing EdgeRing is found
+   * or null if no containing EdgeRing is found
    */
   private EdgeRing findEdgeRingContaining(EdgeRing testEr, List shellList)
   {
diff --git a/src/com/vividsolutions/jts/operation/overlay/snap/GeometrySnapper.java b/src/com/vividsolutions/jts/operation/overlay/snap/GeometrySnapper.java
index 49e8f71..fc0b313 100644
--- a/src/com/vividsolutions/jts/operation/overlay/snap/GeometrySnapper.java
+++ b/src/com/vividsolutions/jts/operation/overlay/snap/GeometrySnapper.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.operation.overlay.snap;
 
 import java.util.*;
@@ -131,7 +164,8 @@ public class GeometrySnapper
    * of the source geometry
    * to the vertices of the given snap geometry.
    *
-   * @param snapGeom a geometry to snap the source to
+   *@param snapTolerance the snapping tolerance
+   *@param cleanResult whether the result should be made valid
    * @return a new snapped Geometry
    */
   public Geometry snapToSelf(double snapTolerance, boolean cleanResult)
diff --git a/src/com/vividsolutions/jts/operation/overlay/snap/LineStringSnapper.java b/src/com/vividsolutions/jts/operation/overlay/snap/LineStringSnapper.java
index 4fbc07b..08992ce 100644
--- a/src/com/vividsolutions/jts/operation/overlay/snap/LineStringSnapper.java
+++ b/src/com/vividsolutions/jts/operation/overlay/snap/LineStringSnapper.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.operation.overlay.snap;
 
 import com.vividsolutions.jts.geom.*;
@@ -28,9 +61,9 @@ public class LineStringSnapper
    * @param srcLine a LineString to snap (may be empty)
    * @param snapTolerance the snap tolerance to use
    */
-  public LineStringSnapper(LineString srcLline, double snapTolerance)
+  public LineStringSnapper(LineString srcLine, double snapTolerance)
   {
-    this(srcLline.getCoordinates(), snapTolerance);
+    this(srcLine.getCoordinates(), snapTolerance);
   }
 
   /**
@@ -169,7 +202,7 @@ public class LineStringSnapper
    * @param snapPt the point to snap to
    * @param srcCoords the source segment coordinates
    * @return the index of the snapped segment
-   * @return -1 if no segment snaps to the snap point
+   * or -1 if no segment snaps to the snap point
    */
   private int findSegmentIndexToSnap(Coordinate snapPt, CoordinateList srcCoords)
   {
diff --git a/src/com/vividsolutions/jts/operation/overlay/snap/SnapIfNeededOverlayOp.java b/src/com/vividsolutions/jts/operation/overlay/snap/SnapIfNeededOverlayOp.java
index 161ba69..121eebc 100644
--- a/src/com/vividsolutions/jts/operation/overlay/snap/SnapIfNeededOverlayOp.java
+++ b/src/com/vividsolutions/jts/operation/overlay/snap/SnapIfNeededOverlayOp.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.operation.overlay.snap;
 
 import com.vividsolutions.jts.geom.*;
@@ -59,13 +92,13 @@ public class SnapIfNeededOverlayOp
     boolean isSuccess = false;
     RuntimeException savedException = null;
     try {
+      // try basic operation with input geometries
       result = OverlayOp.overlayOp(geom[0], geom[1], opCode); 
       boolean isValid = true;
       // not needed if noding validation is used
 //      boolean isValid = OverlayResultValidator.isValid(geom[0], geom[1], OverlayOp.INTERSECTION, result);
       if (isValid)
       	isSuccess = true;
-    
     }
     catch (RuntimeException ex) {
     	savedException = ex;
@@ -88,4 +121,4 @@ public class SnapIfNeededOverlayOp
     }
     return result;
   }
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/operation/overlay/snap/SnapOverlayOp.java b/src/com/vividsolutions/jts/operation/overlay/snap/SnapOverlayOp.java
index 95a6fed..e637bda 100644
--- a/src/com/vividsolutions/jts/operation/overlay/snap/SnapOverlayOp.java
+++ b/src/com/vividsolutions/jts/operation/overlay/snap/SnapOverlayOp.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.operation.overlay.snap;
 
 import com.vividsolutions.jts.geom.*;
@@ -123,4 +156,4 @@ public class SnapOverlayOp
   		System.out.println("Snapped geometry is invalid");
   	}
   }
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/operation/overlay/validate/FuzzyPointLocator.java b/src/com/vividsolutions/jts/operation/overlay/validate/FuzzyPointLocator.java
index 6b78876..ceec353 100644
--- a/src/com/vividsolutions/jts/operation/overlay/validate/FuzzyPointLocator.java
+++ b/src/com/vividsolutions/jts/operation/overlay/validate/FuzzyPointLocator.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.operation.overlay.validate;
 
 import java.util.*;
@@ -115,4 +148,4 @@ class PolygonalLineworkExtracter
 	 * @return a List of LineStrings
 	 */
 	public List getLinework() { return linework; }
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/operation/overlay/validate/OffsetPointGenerator.java b/src/com/vividsolutions/jts/operation/overlay/validate/OffsetPointGenerator.java
index 833c8d7..4c20bae 100644
--- a/src/com/vividsolutions/jts/operation/overlay/validate/OffsetPointGenerator.java
+++ b/src/com/vividsolutions/jts/operation/overlay/validate/OffsetPointGenerator.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.operation.overlay.validate;
 
 import java.util.*;
@@ -97,4 +130,4 @@ public class OffsetPointGenerator
     }
   }
 
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/operation/polygonize/EdgeRing.java b/src/com/vividsolutions/jts/operation/polygonize/EdgeRing.java
index 7d4fc65..83847af 100644
--- a/src/com/vividsolutions/jts/operation/polygonize/EdgeRing.java
+++ b/src/com/vividsolutions/jts/operation/polygonize/EdgeRing.java
@@ -60,7 +60,7 @@ class EdgeRing {
    * (which is guaranteed to be the case if the hole does not touch its shell)
    *
    * @return containing EdgeRing, if there is one
-   * @return null if no containing EdgeRing is found
+   * or null if no containing EdgeRing is found
    */
   public static EdgeRing findEdgeRingContaining(EdgeRing testEr, List shellList)
   {
@@ -69,27 +69,28 @@ class EdgeRing {
     Coordinate testPt = testRing.getCoordinateN(0);
 
     EdgeRing minShell = null;
-    Envelope minEnv = null;
+    Envelope minShellEnv = null;
     for (Iterator it = shellList.iterator(); it.hasNext(); ) {
       EdgeRing tryShell = (EdgeRing) it.next();
-      LinearRing tryRing = tryShell.getRing();
-      Envelope tryEnv = tryRing.getEnvelopeInternal();
-      if (minShell != null) minEnv = minShell.getRing().getEnvelopeInternal();
-      boolean isContained = false;
+      LinearRing tryShellRing = tryShell.getRing();
+      Envelope tryShellEnv = tryShellRing.getEnvelopeInternal();
       // the hole envelope cannot equal the shell envelope
-      if (tryEnv.equals(testEnv))
-        continue;
-
-//      testPt = ptNotInList(testRing.getCoordinates(), tryRing.getCoordinates());
-      testPt = CoordinateArrays.ptNotInList(testRing.getCoordinates(), tryRing.getCoordinates());
-      if (tryEnv.contains(testEnv)
-          && CGAlgorithms.isPointInRing(testPt, tryRing.getCoordinates()) )
+      // (also guards against testing rings against themselves)
+      if (tryShellEnv.equals(testEnv)) continue;
+      // hole must be contained in shell
+      if (! tryShellEnv.contains(testEnv)) continue;
+      
+      testPt = CoordinateArrays.ptNotInList(testRing.getCoordinates(), tryShellRing.getCoordinates());
+      boolean isContained = false;
+      if (CGAlgorithms.isPointInRing(testPt, tryShellRing.getCoordinates()) )
         isContained = true;
+
       // check if this new containing ring is smaller than the current minimum ring
       if (isContained) {
         if (minShell == null
-            || minEnv.contains(tryEnv)) {
+            || minShellEnv.contains(tryShellEnv)) {
           minShell = tryShell;
+          minShellEnv = minShell.getRing().getEnvelopeInternal();
         }
       }
     }
@@ -101,7 +102,9 @@ class EdgeRing {
    * @param testPts the {@link Coordinate}s to test
    * @param pts an array of {@link Coordinate}s to test the input points against
    * @return a {@link Coordinate} from <code>testPts</code> which is not in <code>pts</code>,
-   * @return null if there is no coordinate not in the list
+   * or null if there is no coordinate not in the list
+   * 
+   * @deprecated Use CoordinateArrays.ptNotInList instead
    */
   public static Coordinate ptNotInList(Coordinate[] testPts, Coordinate[] pts)
   {
@@ -120,6 +123,8 @@ class EdgeRing {
    * @param pt a {@link Coordinate} for the test point
    * @param pts an array of {@link Coordinate}s to test
    * @return <code>true</code> if the point is in the array
+   * 
+   * @deprecated
    */
   public static boolean isInList(Coordinate pt, Coordinate[] pts)
   {
diff --git a/src/com/vividsolutions/jts/operation/polygonize/PolygonizeGraph.java b/src/com/vividsolutions/jts/operation/polygonize/PolygonizeGraph.java
index 4ba52bd..af3deac 100644
--- a/src/com/vividsolutions/jts/operation/polygonize/PolygonizeGraph.java
+++ b/src/com/vividsolutions/jts/operation/polygonize/PolygonizeGraph.java
@@ -404,7 +404,7 @@ class PolygonizeGraph
    * In order to handle large recursion depths efficiently,
    * an explicit recursion stack is used
    *
-   * @return a List containing the {@link LineStrings} that formed dangles
+   * @return a List containing the {@link LineString}s that formed dangles
    */
   public Collection deleteDangles()
   {
diff --git a/src/com/vividsolutions/jts/operation/predicate/RectangleContains.java b/src/com/vividsolutions/jts/operation/predicate/RectangleContains.java
index f86a6e0..f953b1d 100644
--- a/src/com/vividsolutions/jts/operation/predicate/RectangleContains.java
+++ b/src/com/vividsolutions/jts/operation/predicate/RectangleContains.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.operation.predicate;
 
 import com.vividsolutions.jts.geom.*;
@@ -149,4 +182,4 @@ public class RectangleContains {
     return false;
   }
 
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/operation/predicate/RectangleIntersects.java b/src/com/vividsolutions/jts/operation/predicate/RectangleIntersects.java
index ab17d39..52f77fc 100644
--- a/src/com/vividsolutions/jts/operation/predicate/RectangleIntersects.java
+++ b/src/com/vividsolutions/jts/operation/predicate/RectangleIntersects.java
@@ -1,31 +1,67 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.operation.predicate;
 
 import java.util.*;
+
 import com.vividsolutions.jts.geom.*;
 import com.vividsolutions.jts.algorithm.*;
 import com.vividsolutions.jts.algorithm.locate.SimplePointInAreaLocator;
 import com.vividsolutions.jts.geom.util.*;
 
 /**
- * Optimized implementation of the <tt>intersects</tt> spatial predicate 
- * for cases where one {@link Geometry} is a rectangle.
- * This class works for all input geometries, including
- * {@link GeometryCollection}s.
+ * Implementation of the <tt>intersects</tt> spatial predicate
+ * optimized for the case where one {@link Geometry} is a rectangle. 
+ * This class works for all
+ * input geometries, including {@link GeometryCollection}s.
  * <p>
- * As a further optimization,
- * this class can be used to test 
- * many geometries against a single
- * rectangle in a slightly more efficient way.
- *
+ * As a further optimization, 
+ * this class can be used in batch style
+ * to test many geometries
+ * against a single rectangle.
+ * 
  * @version 1.7
  */
-public class RectangleIntersects 
+public class RectangleIntersects
 {
   /**
    * Tests whether a rectangle intersects a given geometry.
    * 
-   * @param rectangle a rectangular Polygon
-   * @param b a Geometry of any type
+   * @param rectangle
+   *          a rectangular Polygon
+   * @param b
+   *          a Geometry of any type
    * @return true if the geometries intersect
    */
   public static boolean intersects(Polygon rectangle, Geometry b)
@@ -35,38 +71,56 @@ public class RectangleIntersects
   }
 
   private Polygon rectangle;
+
   private Envelope rectEnv;
 
   /**
    * Create a new intersects computer for a rectangle.
-   *
-   * @param rectangle a rectangular geometry
+   * 
+   * @param rectangle
+   *          a rectangular Polygon
    */
-  public RectangleIntersects(Polygon rectangle) {
+  public RectangleIntersects(Polygon rectangle)
+  {
     this.rectangle = rectangle;
     rectEnv = rectangle.getEnvelopeInternal();
   }
 
+  /**
+   * Tests whether the given Geometry intersects
+   * the query rectangle.
+   * 
+   * @param geom the Geometry to test (may be of any type)
+   * @return true if the geometry intersects the query rectangle
+   */
   public boolean intersects(Geometry geom)
   {
-    if (! rectEnv.intersects(geom.getEnvelopeInternal()))
-        return false;
-    // test envelope relationships
+    if (!rectEnv.intersects(geom.getEnvelopeInternal()))
+      return false;
+
+    /**
+     * Test if rectangle envelope intersects any component envelope.
+     * This handles Point components as well
+     */
     EnvelopeIntersectsVisitor visitor = new EnvelopeIntersectsVisitor(rectEnv);
     visitor.applyTo(geom);
     if (visitor.intersects())
       return true;
 
-    // test if any rectangle corner is contained in the target
-    ContainsPointVisitor ecpVisitor = new ContainsPointVisitor(rectangle);
+    /**
+     * Test if any rectangle vertex is contained in the target geometry
+     */
+    GeometryContainsPointVisitor ecpVisitor = new GeometryContainsPointVisitor(rectangle);
     ecpVisitor.applyTo(geom);
     if (ecpVisitor.containsPoint())
       return true;
 
-    // test if any lines intersect
-    LineIntersectsVisitor liVisitor = new LineIntersectsVisitor(rectangle);
-    liVisitor.applyTo(geom);
-    if (liVisitor.intersects())
+    /**
+     * Test if any target geometry line segment intersects the rectangle
+     */
+    RectangleIntersectsSegmentVisitor riVisitor = new RectangleIntersectsSegmentVisitor(rectangle);
+    riVisitor.applyTo(geom);
+    if (riVisitor.intersects())
       return true;
 
     return false;
@@ -74,17 +128,16 @@ public class RectangleIntersects
 }
 
 /**
- * Tests whether it can be concluded
- * that a rectangle intersects a geometry,
- * based on the locations of the envelope(s) of the geometry.
- *
+ * Tests whether it can be concluded that a rectangle intersects a geometry,
+ * based on the relationship of the envelope(s) of the geometry.
+ * 
  * @author Martin Davis
  * @version 1.7
  */
-class EnvelopeIntersectsVisitor
-    extends ShortCircuitedGeometryVisitor
+class EnvelopeIntersectsVisitor extends ShortCircuitedGeometryVisitor
 {
   private Envelope rectEnv;
+
   private boolean intersects = false;
 
   public EnvelopeIntersectsVisitor(Envelope rectEnv)
@@ -93,35 +146,37 @@ class EnvelopeIntersectsVisitor
   }
 
   /**
-   * Reports whether it can be concluded that an intersection occurs,
+   * Reports whether it can be concluded that an intersection occurs, 
    * or whether further testing is required.
-   *
-   * @return <code>true</code> if an intersection must occur
-   * <code>false</code> if no conclusion can be made
+   * 
+   * @return true if an intersection must occur 
+   * or false if no conclusion about intersection can be made
    */
-  public boolean intersects() { return intersects; }
+  public boolean intersects()
+  {
+    return intersects;
+  }
 
   protected void visit(Geometry element)
   {
     Envelope elementEnv = element.getEnvelopeInternal();
-    // disjoint
-    if (! rectEnv.intersects(elementEnv)) {
+
+    // disjoint => no intersection
+    if (!rectEnv.intersects(elementEnv)) {
       return;
     }
-    // fully contained - must intersect
+    // rectangle contains target env => must intersect
     if (rectEnv.contains(elementEnv)) {
       intersects = true;
       return;
     }
     /**
-     * Since the envelopes intersect and the test element is connected,
-     * if the test envelope is completely bisected by an edge of the rectangle
-     * the element and the rectangle must touch
-     * (This is basically an application of the Jordan Curve Theorem).
-     * The alternative situation is that
-     * the test envelope is "on a corner" of the rectangle envelope,
-     * i.e. is not completely bisected.
-     * In this case it is not possible to make a conclusion
+     * Since the envelopes intersect and the test element is connected, if the
+     * test envelope is completely bisected by an edge of the rectangle the
+     * element and the rectangle must touch (This is basically an application of
+     * the Jordan Curve Theorem). The alternative situation is that the test
+     * envelope is "on a corner" of the rectangle envelope, i.e. is not
+     * completely bisected. In this case it is not possible to make a conclusion
      * about the presence of an intersection.
      */
     if (elementEnv.getMinX() >= rectEnv.getMinX()
@@ -136,127 +191,163 @@ class EnvelopeIntersectsVisitor
     }
   }
 
-  protected boolean isDone() {
+  protected boolean isDone()
+  {
     return intersects == true;
   }
 }
 
 /**
- * Tests whether it can be concluded
- * that a geometry contains a corner point of a rectangle.
- *
+ * A visitor which tests whether it can be 
+ * concluded that a geometry contains a vertex of
+ * a query geometry.
+ * 
  * @author Martin Davis
  * @version 1.7
  */
-class ContainsPointVisitor
-    extends ShortCircuitedGeometryVisitor
+class GeometryContainsPointVisitor extends ShortCircuitedGeometryVisitor
 {
   private CoordinateSequence rectSeq;
+
   private Envelope rectEnv;
+
   private boolean containsPoint = false;
 
-  public ContainsPointVisitor(Polygon rectangle)
+  public GeometryContainsPointVisitor(Polygon rectangle)
   {
     this.rectSeq = rectangle.getExteriorRing().getCoordinateSequence();
     rectEnv = rectangle.getEnvelopeInternal();
   }
 
   /**
-   * Reports whether it can be concluded that a corner
-   * point of the rectangle is contained in the geometry,
-   * or whether further testing is required.
-   *
-   * @return <code>true</code> if a corner point is contained
-   * <code>false</code> if no conclusion can be made
+   * Reports whether it can be concluded that a corner point of the rectangle is
+   * contained in the geometry, or whether further testing is required.
+   * 
+   * @return true if a corner point is contained 
+   * or false if no conclusion about intersection can be made
    */
-  public boolean containsPoint() { return containsPoint; }
+  public boolean containsPoint()
+  {
+    return containsPoint;
+  }
 
   protected void visit(Geometry geom)
   {
     // if test geometry is not polygonal this check is not needed
-    if (! (geom instanceof Polygon))
+    if (!(geom instanceof Polygon))
       return;
-    
+
     // skip if envelopes do not intersect
     Envelope elementEnv = geom.getEnvelopeInternal();
-    if (! rectEnv.intersects(elementEnv))
+    if (!rectEnv.intersects(elementEnv))
       return;
-    
+
     // test each corner of rectangle for inclusion
     Coordinate rectPt = new Coordinate();
     for (int i = 0; i < 4; i++) {
       rectSeq.getCoordinate(i, rectPt);
-      if (! elementEnv.contains(rectPt))
+      if (!elementEnv.contains(rectPt))
         continue;
-      // check rect point in poly (rect is known not to touch polygon at this point)
-      if (SimplePointInAreaLocator.containsPointInPolygon(rectPt, (Polygon) geom)) {
+      // check rect point in poly (rect is known not to touch polygon at this
+      // point)
+      if (SimplePointInAreaLocator.containsPointInPolygon(rectPt,
+          (Polygon) geom)) {
         containsPoint = true;
         return;
       }
     }
   }
 
-  protected boolean isDone() {
+  protected boolean isDone()
+  {
     return containsPoint == true;
   }
 }
 
+
 /**
- * Tests whether any line segment of a geometry intersects a given rectangle.
- * Optimizes the algorithm used based on the number of line segments in the
- * test geometry.
- *
+ * A visitor to test for intersection between the query
+ * rectangle and the line segments of the geometry.
+ * 
  * @author Martin Davis
- * @version 1.7
+ *
  */
-class LineIntersectsVisitor
-    extends ShortCircuitedGeometryVisitor
+class RectangleIntersectsSegmentVisitor extends ShortCircuitedGeometryVisitor
 {
-  private LineString rectLine;
   private Envelope rectEnv;
-  private boolean intersects = false;
+  private RectangleLineIntersector rectIntersector;
 
-  public LineIntersectsVisitor(Polygon rectangle)
+  private boolean hasIntersection = false;
+  private Coordinate p0 = new Coordinate();
+  private Coordinate p1 = new Coordinate();
+
+  /**
+   * Creates a visitor for checking rectangle intersection
+   * with segments
+   * 
+   * @param rectangle the query rectangle 
+   */
+  public RectangleIntersectsSegmentVisitor(Polygon rectangle)
   {
-    this.rectLine = rectangle.getExteriorRing();
     rectEnv = rectangle.getEnvelopeInternal();
+    rectIntersector = new RectangleLineIntersector(rectEnv);
   }
 
-
   /**
    * Reports whether any segment intersection exists.
-   *
-   * @return <code>true</code> if a segment intersection exists
-   * <code>false</code> if no segment intersection exists
+   * 
+   * @return true if a segment intersection exists
+   * or false if no segment intersection exists
    */
-  public boolean intersects() { return intersects; }
+  public boolean intersects()
+  {
+    return hasIntersection;
+  }
 
   protected void visit(Geometry geom)
   {
+    /**
+     * It may be the case that the rectangle and the 
+     * envelope of the geometry component are disjoint,
+     * so it is worth checking this simple condition.
+     */
     Envelope elementEnv = geom.getEnvelopeInternal();
-    
-    // check for envelope intersection
-    if (! rectEnv.intersects(elementEnv))
+    if (!rectEnv.intersects(elementEnv))
       return;
     
-    computeSegmentIntersection(geom);
+    // check segment intersections
+    // get all lines from geometry component
+    // (there may be more than one if it's a multi-ring polygon)
+    List lines = LinearComponentExtracter.getLines(geom);
+    checkIntersectionWithLineStrings(lines);
   }
 
-  private void computeSegmentIntersection(Geometry geom)
+  private void checkIntersectionWithLineStrings(List lines)
   {
-    // check segment intersection
-    // get all lines from geom (e.g. if it's a multi-ring polygon)
-    List lines = LinearComponentExtracter.getLines(geom);
-    SegmentIntersectionTester si = new SegmentIntersectionTester();
-    boolean hasIntersection = si.hasIntersectionWithLineStrings(rectLine, lines);
-    if (hasIntersection) {
-      intersects = true;
-      return;
+    for (Iterator i = lines.iterator(); i.hasNext(); ) {
+      LineString testLine = (LineString) i.next();
+      checkIntersectionWithSegments(testLine);
+      if (hasIntersection)
+        return;
     }
   }
 
-  protected boolean isDone() {
-    return intersects == true;
+  private void checkIntersectionWithSegments(LineString testLine)
+  {
+    CoordinateSequence seq1 = testLine.getCoordinateSequence();
+    for (int j = 1; j < seq1.size(); j++) {
+      seq1.getCoordinate(j - 1, p0);
+      seq1.getCoordinate(j,     p1);
+
+      if (rectIntersector.intersects(p0, p1)) {
+        hasIntersection = true;
+        return;
+      }
+    }
   }
-}
 
+  protected boolean isDone()
+  {
+    return hasIntersection == true;
+  }
+}
diff --git a/src/com/vividsolutions/jts/operation/predicate/SegmentIntersectionTester.java b/src/com/vividsolutions/jts/operation/predicate/SegmentIntersectionTester.java
deleted file mode 100644
index 60e8478..0000000
--- a/src/com/vividsolutions/jts/operation/predicate/SegmentIntersectionTester.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package com.vividsolutions.jts.operation.predicate;
-
-import java.util.*;
-import com.vividsolutions.jts.algorithm.*;
-import com.vividsolutions.jts.geom.*;
-
-/**
- * Tests if any of the segments in a
- * {@link LineString} intersect any segment in a set of {@link LineString}s.
- * <p>
- * The algorithm is optimized for use when the first input has smaller extent
- * than the set of test lines.
- * The code is short-circuited to return as soon an intersection is found.
- *
- * @version 1.7
- */
-public class SegmentIntersectionTester 
-{
-  // for intersection testing, don't need to set precision model
-  private LineIntersector li = new RobustLineIntersector();
-
-  private boolean hasIntersection = false;
-  private Coordinate pt00 = new Coordinate();
-  private Coordinate pt01 = new Coordinate();
-  private Coordinate pt10 = new Coordinate();
-  private Coordinate pt11 = new Coordinate();
-
-  public SegmentIntersectionTester() {
-  }
-
-  public boolean hasIntersectionWithLineStrings(LineString line, List lines)
-  {
-    for (Iterator i = lines.iterator(); i.hasNext(); ) {
-      LineString testLine = (LineString) i.next();
-      //hasIntersection(line, testLine);
-      hasIntersectionWithEnvelopeFilter(line, testLine);
-      if (hasIntersection)
-        break;
-    }
-    return hasIntersection;
-  }
-
-  /**
-   * Tests the segments of a LineString against the segs in 
-   * another LineString for intersection.
-   * Uses the envelope of the query LineString
-   * to filter before testing segments directly.
-   * This is optimized for the case when the query
-   * LineString is a rectangle.
-   * 
-   * Testing shows this is somewhat faster than not checking the envelope.
-   * 
-   * @param line
-   * @param testLine
-   * @return
-   */
-  private boolean hasIntersectionWithEnvelopeFilter(LineString line, LineString testLine) {
-    CoordinateSequence seq0 = line.getCoordinateSequence();
-    CoordinateSequence seq1 = testLine.getCoordinateSequence();
-    Envelope lineEnv = line.getEnvelopeInternal();
-    
-    for (int i = 1; i < seq1.size() && ! hasIntersection; i++) {
-      seq1.getCoordinate(i - 1, pt10);
-      seq1.getCoordinate(i, pt11);
-      
-      // skip test if segment does not intersect query envelope
-      if (! lineEnv.intersects(new Envelope(pt10, pt11)))
-        continue;
-      
-      for (int j = 1; j < seq0.size() && ! hasIntersection; j++) {
-        seq0.getCoordinate(j - 1, pt00);
-        seq0.getCoordinate(j, pt01);
-
-        li.computeIntersection(pt00, pt01, pt10, pt11);
-        if (li.hasIntersection())
-          hasIntersection = true;
-      }
-    }
-    return hasIntersection;
-  }
-  
-  private boolean hasIntersection(LineString line, LineString testLine) {
-    CoordinateSequence seq0 = line.getCoordinateSequence();
-    CoordinateSequence seq1 = testLine.getCoordinateSequence();
-    for (int i = 1; i < seq0.size() && ! hasIntersection; i++) {
-      seq0.getCoordinate(i - 1, pt00);
-      seq0.getCoordinate(i, pt01);
-      for (int j = 1; j < seq1.size() && ! hasIntersection; j++) {
-        seq1.getCoordinate(j - 1, pt10);
-        seq1.getCoordinate(j, pt11);
-
-        li.computeIntersection(pt00, pt01, pt10, pt11);
-        if (li.hasIntersection())
-          hasIntersection = true;
-      }
-    }
-    return hasIntersection;
-  }
-
-}
\ No newline at end of file
diff --git a/src/com/vividsolutions/jts/operation/relate/RelateOp.java b/src/com/vividsolutions/jts/operation/relate/RelateOp.java
index 65c0268..10d9f0e 100644
--- a/src/com/vividsolutions/jts/operation/relate/RelateOp.java
+++ b/src/com/vividsolutions/jts/operation/relate/RelateOp.java
@@ -46,12 +46,20 @@ import com.vividsolutions.jts.operation.GeometryGraphOperation;
 import java.util.*;
 
 /**
- * Implements the SFS <tt>relate()</tt> operation on two {@link Geometry}s.
- * This class supports specifying a custom {@link BoundaryNodeRule}
+ * Implements the SFS <tt>relate()</tt> generalized spatial predicate on two {@link Geometry}s.
+ * <b>
+ * The class supports specifying a custom {@link BoundaryNodeRule}
  * to be used during the relate computation.
  * <p>
+ * If named spatial predicates are used on the result {@link IntersectionMatrix}
+ * of the RelateOp, the result may or not be affected by the 
+ * choice of <tt>BoundaryNodeRule</tt>, depending on the exact nature of the pattern.
+ * For instance, {@link IntersectionMatrix#isIntersects()} is insensitive 
+ * to the choice of <tt>BoundaryNodeRule</tt>, 
+ * whereas {@link IntersectionMatrix#isTouches(int, int)} is affected by the rule chosen.
+ * <p>
  * <b>Note:</b> custom Boundary Node Rules do not (currently)
- * affect the results of other Geometry methods (such
+ * affect the results of other {@link Geometry} methods (such
  * as {@link Geometry#getBoundary}.  The results of
  * these methods may not be consistent with the relationship computed by
  * a custom Boundary Node Rule.
diff --git a/src/com/vividsolutions/jts/operation/union/CascadedPolygonUnion.java b/src/com/vividsolutions/jts/operation/union/CascadedPolygonUnion.java
index 14e4f6b..edd8989 100644
--- a/src/com/vividsolutions/jts/operation/union/CascadedPolygonUnion.java
+++ b/src/com/vividsolutions/jts/operation/union/CascadedPolygonUnion.java
@@ -41,18 +41,25 @@ import com.vividsolutions.jts.index.strtree.STRtree;
 /**
  * Provides an efficient method of unioning a collection of 
  * {@link Polygonal} geometrys.
- * This algorithm is faster and likely more robust than
+ * The geometries are indexed using a spatial index, 
+ * and unioned recursively in index order.
+ * For geometries with a high degree of overlap,
+ * this has the effect of reducing the number of vertices
+ * early in the process, which increases speed
+ * and robustness.
+ * <p>
+ * This algorithm is faster and more robust than
  * the simple iterated approach of 
  * repeatedly unioning each polygon to a result geometry.
  * <p>
  * The <tt>buffer(0)</tt> trick is sometimes faster, but can be less robust and 
- * can sometimes take an exceptionally long time to complete.
+ * can sometimes take a long time to complete.
  * This is particularly the case where there is a high degree of overlap
  * between the polygons.  In this case, <tt>buffer(0)</tt> is forced to compute
  * with <i>all</i> line segments from the outset, 
  * whereas cascading can eliminate many segments
  * at each stage of processing.
- * The best case for buffer(0) is the trivial case
+ * The best situation for using <tt>buffer(0)</tt> is the trivial case
  * where there is <i>no</i> overlap between the input geometries. 
  * However, this case is likely rare in practice.
  * 
@@ -80,7 +87,7 @@ public class CascadedPolygonUnion
 	 * Creates a new instance to union
 	 * the given collection of {@link Geometry}s.
 	 * 
-	 * @param geoms a collection of {@link Polygonal} {@link Geometry}s
+	 * @param polys a collection of {@link Polygonal} {@link Geometry}s
 	 */
 	public CascadedPolygonUnion(Collection polys)
 	{
@@ -100,7 +107,7 @@ public class CascadedPolygonUnion
 	 * Computes the union of the input geometries.
 	 * 
 	 * @return the union of the input geometries
-	 * @return null if no input geometries were provided
+	 * or null if no input geometries were provided
 	 */
 	public Geometry union()
 	{
@@ -197,9 +204,9 @@ public class CascadedPolygonUnion
    * Unions a section of a list using a recursive binary union on each half
    * of the section.
    * 
-   * @param geoms
-   * @param start
-   * @param end
+   * @param geoms the list of geometries containing the section to union
+   * @param start the start index of the section
+   * @param end the index after the end of the section
    * @return the union of the list section
    */
   private Geometry binaryUnion(List geoms, int start, int end)
@@ -220,6 +227,15 @@ public class CascadedPolygonUnion
   	}
   }
   
+  /**
+   * Gets the element at a given list index, or
+   * null if the index is out of range.
+   * 
+   * @param list
+   * @param index
+   * @return the geometry at the given index
+   * or null if the index is out of range
+   */
   private static Geometry getGeometry(List list, int index)
   {
   	if (index >= list.size()) return null;
@@ -252,12 +268,12 @@ public class CascadedPolygonUnion
   
   /**
    * Computes the union of two geometries, 
-   * either of both of which may be null.
+   * either or both of which may be null.
    * 
    * @param g0 a Geometry
    * @param g1 a Geometry
    * @return the union of the input(s)
-   * @return null if both inputs are null
+   * or null if both inputs are null
    */
   private Geometry unionSafe(Geometry g0, Geometry g1)
   {
@@ -269,8 +285,6 @@ public class CascadedPolygonUnion
   	if (g1 == null)
   		return (Geometry) g0.clone();
   	
-  	// what if both are null?  Maybe return empty GC?
-  	
   	return unionOptimized(g0, g1);
   }
   
@@ -304,7 +318,8 @@ public class CascadedPolygonUnion
   
   
   /**
-   * Unions two polygonal geometries.
+   * Unions two polygonal geometries, restricting computation 
+   * to the envelope intersection where possible.
    * The case of MultiPolygons is optimized to union only 
    * the polygons which lie in the intersection of the two geometry's envelopes.
    * Polygons outside this region can simply be combined with the union result,
@@ -366,6 +381,30 @@ public class CascadedPolygonUnion
   	*/
   	
   	//return bufferUnion(g0, g1);
-  	return g0.union(g1);
+  	return restrictToPolygons(g0.union(g1));
+  }
+  
+  /**
+   * Computes a {@link Geometry} containing only {@link Polygonal} components.
+   * Extracts the {@link Polygon}s from the input 
+   * and returns them as an appropriate {@link Polygonal} geometry.
+   * <p>
+   * If the input is already <tt>Polygonal</tt>, it is returned unchanged.
+   * <p>
+   * A particular use case is to filter out non-polygonal components
+   * returned from an overlay operation.  
+   * 
+   * @param g the geometry to filter
+   * @return a Polygonal geometry
+   */
+  private static Geometry restrictToPolygons(Geometry g)
+  {
+    if (g instanceof Polygonal) {
+      return g;
+    }
+    List polygons = PolygonExtracter.getPolygons(g);
+    if (polygons.size() == 1) 
+      return (Polygon) polygons.get(0);
+    return g.getFactory().createMultiPolygon(GeometryFactory.toPolygonArray(polygons));
   }
 }
diff --git a/src/com/vividsolutions/jts/operation/union/PointGeometryUnion.java b/src/com/vividsolutions/jts/operation/union/PointGeometryUnion.java
index e6c96b3..caee28d 100644
--- a/src/com/vividsolutions/jts/operation/union/PointGeometryUnion.java
+++ b/src/com/vividsolutions/jts/operation/union/PointGeometryUnion.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.operation.union;
 
 import com.vividsolutions.jts.algorithm.*;
diff --git a/src/com/vividsolutions/jts/operation/union/UnaryUnionOp.java b/src/com/vividsolutions/jts/operation/union/UnaryUnionOp.java
index 707c7a1..715a126 100644
--- a/src/com/vividsolutions/jts/operation/union/UnaryUnionOp.java
+++ b/src/com/vividsolutions/jts/operation/union/UnaryUnionOp.java
@@ -36,6 +36,7 @@ package com.vividsolutions.jts.operation.union;
 import java.util.*;
 import com.vividsolutions.jts.geom.*;
 import com.vividsolutions.jts.geom.util.*;
+import com.vividsolutions.jts.operation.linemerge.LineMerger;
 import com.vividsolutions.jts.operation.overlay.OverlayOp;
 import com.vividsolutions.jts.operation.overlay.snap.SnapIfNeededOverlayOp;
 
@@ -48,13 +49,14 @@ import com.vividsolutions.jts.operation.overlay.snap.SnapIfNeededOverlayOp;
  * <p>
  * The result obeys the following contract:
  * <ul>
- * <li>Unioning a set of overlapping {@link Polygons}s has the effect of
+ * <li>Unioning a set of overlapping {@link Polygon}s has the effect of
  * merging the areas (i.e. the same effect as 
  * iteratively unioning all individual polygons together).
  * 
  * <li>Unioning a set of {@link LineString}s has the effect of <b>noding</b> 
  * and <b>dissolving</b> the input linework.
- * In this context "fully noded" means that there will be a node or endpoint in the result 
+ * In this context "fully noded" means that there will be 
+ * an endpoint or node in the result 
  * for every endpoint or line segment crossing in the input.
  * "Dissolved" means that any duplicate (i.e. coincident) line segments or portions
  * of line segments will be reduced to a single line segment in the result.  
@@ -62,7 +64,7 @@ import com.vividsolutions.jts.operation.overlay.snap.SnapIfNeededOverlayOp;
  * {@link Geometry#union(Geometry)} operation.
  * If <b>merged</b> linework is required, the {@link LineMerger} class can be used.
  * 
- * <li>Unioning a set of {@link Points}s has the effect of merging
+ * <li>Unioning a set of {@link Point}s has the effect of merging
  * all identical points (producing a set with no duplicates).
  * </ul>
  * 
@@ -143,7 +145,7 @@ public class UnaryUnionOp
 	 * If no input geometries were provided, a POINT EMPTY is returned.
 	 * 
 	 * @return a Geometry containing the union
-	 * @return an empty GEOMETRYCOLLECTION if no geometries were provided in the input
+	 * or an empty GEOMETRYCOLLECTION if no geometries were provided in the input
 	 */
 	public Geometry union()
 	{
@@ -200,7 +202,7 @@ public class UnaryUnionOp
    * @param g0 a Geometry
    * @param g1 a Geometry
    * @return the union of the input(s)
-   * @return null if both inputs are null
+   * or null if both inputs are null
    */
   private Geometry unionWithNull(Geometry g0, Geometry g1)
   {
diff --git a/src/com/vividsolutions/jts/operation/union/UnionInteracting.java b/src/com/vividsolutions/jts/operation/union/UnionInteracting.java
index 165fe09..c321424 100644
--- a/src/com/vividsolutions/jts/operation/union/UnionInteracting.java
+++ b/src/com/vividsolutions/jts/operation/union/UnionInteracting.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.operation.union;
 
 import java.util.ArrayList;
diff --git a/src/com/vividsolutions/jts/operation/valid/IsValidOp.java b/src/com/vividsolutions/jts/operation/valid/IsValidOp.java
index 1452c6d..367eec4 100644
--- a/src/com/vividsolutions/jts/operation/valid/IsValidOp.java
+++ b/src/com/vividsolutions/jts/operation/valid/IsValidOp.java
@@ -142,12 +142,26 @@ public class IsValidOp
     isSelfTouchingRingFormingHoleValid = isValid;
   }
 
+  /**
+   * Computes the validity of the geometry,
+   * and returns <tt>true</tt> if it is valid.
+   * 
+   * @return true if the geometry is valid
+   */
   public boolean isValid()
   {
     checkValid(parentGeometry);
     return validErr == null;
   }
 
+  /**
+   * Computes the validity of the geometry,
+   * and if not valid returns the validation error for the geometry,
+   * or null if the geometry is valid.
+   * 
+   * @return the validation error, if the geometry is invalid
+   * or null if the geometry is valid
+   */
   public TopologyValidationError getValidationError()
   {
     checkValid(parentGeometry);
diff --git a/src/com/vividsolutions/jts/planargraph/PlanarGraph.java b/src/com/vividsolutions/jts/planargraph/PlanarGraph.java
index 43e5a1c..810819c 100644
--- a/src/com/vividsolutions/jts/planargraph/PlanarGraph.java
+++ b/src/com/vividsolutions/jts/planargraph/PlanarGraph.java
@@ -69,7 +69,7 @@ public abstract class PlanarGraph
    *
    * @param pt the location to query
    * @return the node found
-   * @return <code>null</code> if this graph contains no node at the location
+   * or <code>null</code> if this graph contains no node at the location
    */
   public Node findNode(Coordinate pt)
   {
diff --git a/src/com/vividsolutions/jts/planargraph/Subgraph.java b/src/com/vividsolutions/jts/planargraph/Subgraph.java
index 85723d0..34b3a0f 100644
--- a/src/com/vividsolutions/jts/planargraph/Subgraph.java
+++ b/src/com/vividsolutions/jts/planargraph/Subgraph.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.planargraph;
 
 import java.util.*;
@@ -88,4 +121,4 @@ public class Subgraph
    */
   public boolean contains(Edge e) { return edges.contains(e); }
 
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/planargraph/algorithm/ConnectedSubgraphFinder.java b/src/com/vividsolutions/jts/planargraph/algorithm/ConnectedSubgraphFinder.java
index 90630cd..3b4b966 100644
--- a/src/com/vividsolutions/jts/planargraph/algorithm/ConnectedSubgraphFinder.java
+++ b/src/com/vividsolutions/jts/planargraph/algorithm/ConnectedSubgraphFinder.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.planargraph.algorithm;
 
 import java.util.*;
@@ -71,4 +104,4 @@ public class ConnectedSubgraphFinder
     }
   }
 
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/precision/CoordinatePrecisionReducerFilter.java b/src/com/vividsolutions/jts/precision/CoordinatePrecisionReducerFilter.java
index a81313c..5d4f6ef 100644
--- a/src/com/vividsolutions/jts/precision/CoordinatePrecisionReducerFilter.java
+++ b/src/com/vividsolutions/jts/precision/CoordinatePrecisionReducerFilter.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.precision;
 
 import com.vividsolutions.jts.geom.*;
diff --git a/src/com/vividsolutions/jts/precision/GeometryPrecisionReducer.java b/src/com/vividsolutions/jts/precision/GeometryPrecisionReducer.java
index 577d8dd..52189ea 100644
--- a/src/com/vividsolutions/jts/precision/GeometryPrecisionReducer.java
+++ b/src/com/vividsolutions/jts/precision/GeometryPrecisionReducer.java
@@ -191,24 +191,34 @@ public class GeometryPrecisionReducer
   	
   	Geometry finalGeom = bufGeom;
   	if (! changePrecisionModel) {
-  		PrecisionModel originalPM = geom.getFactory().getPrecisionModel();
-  		finalGeom = changePM(bufGeom, originalPM);
+  	  // a slick way to copy the geometry with the original precision factory
+  		finalGeom = geom.getFactory().createGeometry(bufGeom);
   	}
   	return finalGeom;
   }
   
-  private Geometry changePM(Geometry geom, PrecisionModel pm)
+  /**
+   * Duplicates a geometry to one that uses a different PrecisionModel,
+   * without changing any coordinate values.
+   * 
+   * @param geom the geometry to duplicate
+   * @param newPM the precision model to use
+   * @return the geometry value with a new precision model
+   */
+  private Geometry changePM(Geometry geom, PrecisionModel newPM)
   {
-  	GeometryEditor geomEditor = createEditor(geom.getFactory(), pm);
+  	GeometryEditor geomEditor = createEditor(geom.getFactory(), newPM);
+  	// this operation changes the PM for the entire geometry tree
   	return geomEditor.edit(geom, new GeometryEditor.NoOpGeometryOperation());
   }
   
-  private GeometryEditor createEditor(GeometryFactory geomFactory, PrecisionModel pm)
+  private GeometryEditor createEditor(GeometryFactory geomFactory, PrecisionModel newPM)
   {
-  	if (geomFactory.getPrecisionModel() == pm)
+    // no need to change if precision model is the same
+  	if (geomFactory.getPrecisionModel() == newPM)
   		return new GeometryEditor();
   	// otherwise create a geometry editor which changes PrecisionModel
-  	GeometryFactory newFactory = createFactory(geomFactory, targetPM);
+  	GeometryFactory newFactory = createFactory(geomFactory, newPM);
   	GeometryEditor geomEdit = new GeometryEditor(newFactory);
     return geomEdit;
   }
diff --git a/src/com/vividsolutions/jts/precision/MinimumClearance.java b/src/com/vividsolutions/jts/precision/MinimumClearance.java
index 2735f8c..e30f812 100644
--- a/src/com/vividsolutions/jts/precision/MinimumClearance.java
+++ b/src/com/vividsolutions/jts/precision/MinimumClearance.java
@@ -142,7 +142,7 @@ public class MinimumClearance
    * 
    * @param g the input geometry
    * @return the value of the minimum clearance distance
-   * @return <tt>LINESTRING EMPTY</tt> if no Minimum Clearance distance exists
+   * or <tt>LINESTRING EMPTY</tt> if no Minimum Clearance distance exists
    */
   public static Geometry getLine(Geometry g)
   {
@@ -173,7 +173,7 @@ public class MinimumClearance
    * <tt>Double.MAX_VALUE</tt> is returned.
    * 
    * @return the value of the minimum clearance distance
-   * @return <tt>Double.MAX_VALUE</tt> if no Minimum Clearance distance exists
+   * or <tt>Double.MAX_VALUE</tt> if no Minimum Clearance distance exists
    */
   public double getDistance()
   {
@@ -190,7 +190,7 @@ public class MinimumClearance
    * <tt>LINESTRING EMPTY</tt> is returned.
    * 
    * @return the value of the minimum clearance distance
-   * @return <tt>LINESTRING EMPTY</tt> if no Minimum Clearance distance exists
+   * or <tt>LINESTRING EMPTY</tt> if no Minimum Clearance distance exists
    */
   public LineString getLine()
   {
diff --git a/src/com/vividsolutions/jts/shape/GeometricShapeBuilder.java b/src/com/vividsolutions/jts/shape/GeometricShapeBuilder.java
index 60b18bb..a089bf2 100644
--- a/src/com/vividsolutions/jts/shape/GeometricShapeBuilder.java
+++ b/src/com/vividsolutions/jts/shape/GeometricShapeBuilder.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.shape;
 
 import com.vividsolutions.jts.geom.*;
diff --git a/src/com/vividsolutions/jts/shape/fractal/KochSnowflakeBuilder.java b/src/com/vividsolutions/jts/shape/fractal/KochSnowflakeBuilder.java
index ec4f2bd..5c261f8 100644
--- a/src/com/vividsolutions/jts/shape/fractal/KochSnowflakeBuilder.java
+++ b/src/com/vividsolutions/jts/shape/fractal/KochSnowflakeBuilder.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.shape.fractal;
 
 import com.vividsolutions.jts.geom.*;
diff --git a/src/com/vividsolutions/jts/shape/fractal/SierpinskiCarpetBuilder.java b/src/com/vividsolutions/jts/shape/fractal/SierpinskiCarpetBuilder.java
index 5253447..720e447 100644
--- a/src/com/vividsolutions/jts/shape/fractal/SierpinskiCarpetBuilder.java
+++ b/src/com/vividsolutions/jts/shape/fractal/SierpinskiCarpetBuilder.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.shape.fractal;
 
 import java.util.*;
diff --git a/src/com/vividsolutions/jts/shape/random/RandomPointsBuilder.java b/src/com/vividsolutions/jts/shape/random/RandomPointsBuilder.java
index 0e17c09..c6f6b9e 100644
--- a/src/com/vividsolutions/jts/shape/random/RandomPointsBuilder.java
+++ b/src/com/vividsolutions/jts/shape/random/RandomPointsBuilder.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.shape.random;
 
 import com.vividsolutions.jts.algorithm.locate.IndexedPointInAreaLocator;
@@ -42,7 +75,7 @@ extends GeometricShapeBuilder
    * Sets a polygonal mask.
    * 
    * @param mask
-   * @ throws IllegalArgumentException if the mask is not polygonal
+   * @throws IllegalArgumentException if the mask is not polygonal
    */
   public void setExtent(Geometry mask)
   {
diff --git a/src/com/vividsolutions/jts/shape/random/RandomPointsInGridBuilder.java b/src/com/vividsolutions/jts/shape/random/RandomPointsInGridBuilder.java
index 46c160b..25f86e2 100644
--- a/src/com/vividsolutions/jts/shape/random/RandomPointsInGridBuilder.java
+++ b/src/com/vividsolutions/jts/shape/random/RandomPointsInGridBuilder.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.shape.random;
 
 import java.util.ArrayList;
@@ -42,19 +75,43 @@ extends GeometricShapeBuilder
   	super(geomFact);
   }
 
+  /**
+   * Sets whether generated points are constrained to lie
+   * within a circle contained within each grid cell.
+   * This provides greater separation between points
+   * in adjacent cells.
+   * <p>
+   * The default is to not be constrained to a circle.
+   * @param isConstrainedToCircle
+   */
   public void setConstrainedToCircle(boolean isConstrainedToCircle)
   {
   	this.isConstrainedToCircle = isConstrainedToCircle;
   }
   
+  /**
+   * Sets the fraction of the grid cell side which will be treated as
+   * a gutter, in which no points will be created.
+   * The provided value is clamped to the range [0.0, 1.0].
+   * 
+   * @param gutterFraction
+   */
   public void setGutterFraction(double gutterFraction)
   {
   	this.gutterFraction = gutterFraction;
   }
   
+  /**
+   * Gets the {@link MultiPoint} containing the generated point
+   * 
+   * @return a MultiPoint
+   */
   public Geometry getGeometry()
   {
-    int nCells = (int) Math.sqrt(numPts) + 1;
+    int nCells = (int) Math.sqrt(numPts);
+    // ensure that at least numPts points are generated
+    if (nCells * nCells < numPts)
+      nCells += 1;
 
     double gridDX = getExtent().getWidth() / nCells;
     double gridDY = getExtent().getHeight() / nCells;
@@ -66,22 +123,22 @@ extends GeometricShapeBuilder
     double cellDX = cellFrac * gridDX;
     double cellDY = cellFrac * gridDY;
     	
-    List pts = new ArrayList();
-
+    Coordinate[] pts = new Coordinate[nCells * nCells];
+    int index = 0;
     for (int i = 0; i < nCells; i++) {
       for (int j = 0; j < nCells; j++) {
       	double orgX = getExtent().getMinX() + i * gridDX + gutterOffsetX;
       	double orgY = getExtent().getMinY() + j * gridDY + gutterOffsetY;
-        pts.add(randomPointInCell(orgX, orgY, cellDX, cellDY));
+        pts[index++] = randomPointInCell(orgX, orgY, cellDX, cellDY);
       }
     }
-    return geomFactory.createMultiPoint(CoordinateArrays.toCoordinateArray(pts));
+    return geomFactory.createMultiPoint(pts);
   }
   
   private Coordinate randomPointInCell(double orgX, double orgY, double xLen, double yLen)
   {
   	if (isConstrainedToCircle) {
-  		randomPointInCircle(
+  		return randomPointInCircle(
   				orgX, 
   				orgY, 
   				xLen, yLen);
@@ -99,7 +156,7 @@ extends GeometricShapeBuilder
   private static Coordinate randomPointInCircle(double orgX, double orgY, double width, double height)
   {
   	double centreX = orgX + width/2;
-  	double centreY = orgX + height/2;
+  	double centreY = orgY + height/2;
   		
   	double rndAng = 2 * Math.PI * Math.random();
   	double rndRadius = Math.random();
diff --git a/src/com/vividsolutions/jts/simplify/DouglasPeuckerLineSimplifier.java b/src/com/vividsolutions/jts/simplify/DouglasPeuckerLineSimplifier.java
index 552de40..eb4415a 100644
--- a/src/com/vividsolutions/jts/simplify/DouglasPeuckerLineSimplifier.java
+++ b/src/com/vividsolutions/jts/simplify/DouglasPeuckerLineSimplifier.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.simplify;
 
 import java.util.*;
diff --git a/src/com/vividsolutions/jts/simplify/DouglasPeuckerSimplifier.java b/src/com/vividsolutions/jts/simplify/DouglasPeuckerSimplifier.java
index 69545e9..38c4bdb 100644
--- a/src/com/vividsolutions/jts/simplify/DouglasPeuckerSimplifier.java
+++ b/src/com/vividsolutions/jts/simplify/DouglasPeuckerSimplifier.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.simplify;
 
 import java.util.*;
@@ -8,6 +41,8 @@ import com.vividsolutions.jts.geom.util.*;
  * Simplifies a {@link Geometry} using the standard Douglas-Peucker algorithm.
  * Ensures that any polygonal geometries returned are valid.
  * Simple lines are not guaranteed to remain simple after simplification.
+ * All geometry types are handled. 
+ * Empty and point geometries are returned unchanged.
  * <p>
  * Note that in general D-P does not preserve topology -
  * e.g. polygons can be split, collapse to lines or disappear
@@ -72,6 +107,9 @@ public class DouglasPeuckerSimplifier
   
   public Geometry getResultGeometry()
   {
+    // empty input produces an empty result
+    if (inputGeom.isEmpty()) return (Geometry) inputGeom.clone();
+    
     return (new DPTransformer(isEnsureValidTopology)).transform(inputGeom);
   }
 
diff --git a/src/com/vividsolutions/jts/simplify/LineSegmentIndex.java b/src/com/vividsolutions/jts/simplify/LineSegmentIndex.java
index 92c92e7..6c520c3 100644
--- a/src/com/vividsolutions/jts/simplify/LineSegmentIndex.java
+++ b/src/com/vividsolutions/jts/simplify/LineSegmentIndex.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.simplify;
 
 import java.util.*;
diff --git a/src/com/vividsolutions/jts/simplify/TaggedLineSegment.java b/src/com/vividsolutions/jts/simplify/TaggedLineSegment.java
index 9db92b1..2e2ca0f 100644
--- a/src/com/vividsolutions/jts/simplify/TaggedLineSegment.java
+++ b/src/com/vividsolutions/jts/simplify/TaggedLineSegment.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.simplify;
 
 import com.vividsolutions.jts.geom.*;
@@ -25,4 +58,4 @@ class TaggedLineSegment
 
   public Geometry getParent() { return parent; }
   public int getIndex() { return index; }
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/simplify/TaggedLineString.java b/src/com/vividsolutions/jts/simplify/TaggedLineString.java
index 378d262..d748907 100644
--- a/src/com/vividsolutions/jts/simplify/TaggedLineString.java
+++ b/src/com/vividsolutions/jts/simplify/TaggedLineString.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.simplify;
 
 import java.util.*;
@@ -5,7 +38,6 @@ import com.vividsolutions.jts.geom.*;
 
 /**
  * Represents a {@link LineString} which can be modified to a simplified shape.  
- * Every line segment in the parent LineString is represented as a {@link TaggedLineSegment}.
  * This class provides an attribute which specifies the minimum allowable length
  * for the modified result.
  * 
@@ -83,4 +115,4 @@ class TaggedLineString
   }
 
 
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/simplify/TaggedLineStringSimplifier.java b/src/com/vividsolutions/jts/simplify/TaggedLineStringSimplifier.java
index 7ae7210..e0eb075 100644
--- a/src/com/vividsolutions/jts/simplify/TaggedLineStringSimplifier.java
+++ b/src/com/vividsolutions/jts/simplify/TaggedLineStringSimplifier.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.simplify;
 
 import java.util.*;
@@ -13,9 +46,9 @@ import com.vividsolutions.jts.util.Debug;
  * @author Martin Davis
  * @version 1.7
  */
-class TaggedLineStringSimplifier
+public class TaggedLineStringSimplifier
 {
-  private static LineIntersector li = new RobustLineIntersector();
+  private LineIntersector li = new RobustLineIntersector();
   private LineSegmentIndex inputIndex = new LineSegmentIndex();
   private LineSegmentIndex outputIndex = new LineSegmentIndex();
   private TaggedLineString line;
@@ -40,7 +73,13 @@ class TaggedLineStringSimplifier
     this.distanceTolerance = distanceTolerance;
   }
 
-  public void simplify(TaggedLineString line)
+  /**
+   * Simplifies the given {@link TaggedLineString}
+   * using the distance tolerance specified.
+   * 
+   * @param line the linestring to simplify
+   */
+  void simplify(TaggedLineString line)
   {
     this.line = line;
     linePts = line.getParentCoordinates();
@@ -209,4 +248,4 @@ class TaggedLineStringSimplifier
       inputIndex.remove(seg);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/simplify/TaggedLinesSimplifier.java b/src/com/vividsolutions/jts/simplify/TaggedLinesSimplifier.java
index 15be2fc..7d99368 100644
--- a/src/com/vividsolutions/jts/simplify/TaggedLinesSimplifier.java
+++ b/src/com/vividsolutions/jts/simplify/TaggedLinesSimplifier.java
@@ -1,10 +1,43 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.simplify;
 
-import java.util.*;
-import com.vividsolutions.jts.algorithm.*;
+import java.util.Collection;
+import java.util.Iterator;
 
 /**
- * Simplifies a collection of {@link TaggedLineString}s, preserving topology
+ * Simplifies a collection of TaggedLineStrings, preserving topology
  * (in the sense that no new intersections are introduced).
  * This class is essentially just a container for the common
  * indexes used by {@link TaggedLineStringSimplifier}.
@@ -32,7 +65,7 @@ class TaggedLinesSimplifier
   }
 
   /**
-   * Simplify a collection of {@link TaggedLineString}s
+   * Simplify a collection of TaggedLineStrings
    *
    * @param taggedLines the collection of lines to simplify
    */
@@ -48,4 +81,4 @@ class TaggedLinesSimplifier
     }
   }
 
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/simplify/TopologyPreservingSimplifier.java b/src/com/vividsolutions/jts/simplify/TopologyPreservingSimplifier.java
index 756977b..1017cb0 100644
--- a/src/com/vividsolutions/jts/simplify/TopologyPreservingSimplifier.java
+++ b/src/com/vividsolutions/jts/simplify/TopologyPreservingSimplifier.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.simplify;
 
 import java.util.*;
@@ -6,22 +39,38 @@ import com.vividsolutions.jts.geom.util.*;
 import com.vividsolutions.jts.util.Debug;
 
 /**
- * Simplifies a geometry, ensuring that
+ * Simplifies a geometry and ensures that
  * the result is a valid geometry having the
- * same dimension and number of components as the input.
- * The simplification uses a maximum distance difference algorithm
- * similar to the one used in the Douglas-Peucker algorithm.
+ * same dimension and number of components as the input,
+ * and with the components having the same topological 
+ * relationship.
  * <p>
- * In particular, if the input is an areal geometry
+ * If the input is a polygonal geometry
  * ( {@link Polygon} or {@link MultiPolygon} ):
  * <ul>
- * <li>The result has the same number of shells and holes (rings) as the input,
- * in the same order
- * <li>The result rings touch at <b>no more</b> than the number of touching point in the input
+ * <li>The result has the same number of shells and holes as the input,
+ * with the same topological structure
+ * <li>The result rings touch at <b>no more</b> than the number of touching points in the input
  * (although they may touch at fewer points).  
- * (The key implication of this constraint is that the 
- * output will be topologically valid if the input was.) 
+ * The key implication of this statement is that if the 
+ * input is topologically valid, so is the simplified output. 
  * </ul>
+ * For linear geometries, if the input does not contain
+ * any intersecting line segments, this property
+ * will be preserved in the output.
+ * <p>
+ * For all geometry types, the result will contain 
+ * enough vertices to ensure validity.  For polygons
+ * and closed linear geometries, the result will have at
+ * least 4 vertices; for open linestrings the result
+ * will have at least 2 vertices.
+ * <p>
+ * All geometry types are handled. 
+ * Empty and point geometries are returned unchanged.
+ * <p>
+ * The simplification uses a maximum-distance difference algorithm
+ * similar to the Douglas-Peucker algorithm.
+ *
  * <h3>KNOWN BUGS</h3>
  * <ul>
  * <li>If a small hole is very near an edge, it is possible for the edge to be moved by
@@ -69,7 +118,11 @@ public class TopologyPreservingSimplifier
     lineSimplifier.setDistanceTolerance(distanceTolerance);
   }
 
-  public Geometry getResultGeometry() {
+  public Geometry getResultGeometry() 
+  {
+    // empty input produces an empty result
+    if (inputGeom.isEmpty()) return (Geometry) inputGeom.clone();
+    
     linestringMap = new HashMap();
     inputGeom.apply(new LineStringMapBuilderFilter());
     lineSimplifier.simplify(linestringMap.values());
@@ -92,18 +145,33 @@ public class TopologyPreservingSimplifier
     }
   }
 
+  /**
+   * A filter to add linear geometries to the linestring map 
+   * with the appropriate minimum size constraint.
+   * Closed {@link LineString}s (including {@link LinearRing}s
+   * have a minimum output size constraint of 4, 
+   * to ensure the output is valid.
+   * For all other linestrings, the minimum size is 2 points.
+   * 
+   * @author Martin Davis
+   *
+   */
   class LineStringMapBuilderFilter
       implements GeometryComponentFilter
   {
+    /**
+     * Filters linear geometries.
+     * 
+     * geom a geometry of any type 
+     */
     public void filter(Geometry geom)
     {
-      if (geom instanceof LinearRing) {
-        TaggedLineString taggedLine = new TaggedLineString((LineString) geom, 4);
-        linestringMap.put(geom, taggedLine);
-      }
-      else if (geom instanceof LineString) {
-        TaggedLineString taggedLine = new TaggedLineString((LineString) geom, 2);
-        linestringMap.put(geom, taggedLine);
+      if (geom instanceof LineString) {
+        LineString line = (LineString) geom;
+        int minSize = ((LineString) line).isClosed() ? 4 : 2;
+        
+        TaggedLineString taggedLine = new TaggedLineString((LineString) line, minSize);
+        linestringMap.put(line, taggedLine);
       }
     }
   }
diff --git a/src/com/vividsolutions/jts/triangulate/ConformingDelaunayTriangulationBuilder.java b/src/com/vividsolutions/jts/triangulate/ConformingDelaunayTriangulationBuilder.java
index 3988bfe..bd8689c 100644
--- a/src/com/vividsolutions/jts/triangulate/ConformingDelaunayTriangulationBuilder.java
+++ b/src/com/vividsolutions/jts/triangulate/ConformingDelaunayTriangulationBuilder.java
@@ -53,7 +53,7 @@ public class ConformingDelaunayTriangulationBuilder
 	private double tolerance = 0.0;
 	private QuadEdgeSubdivision subdiv = null;
 
-	private Map vertexMap = new TreeMap();
+	private Map constraintVertexMap = new TreeMap();
 	
 	public ConformingDelaunayTriangulationBuilder()
 	{
@@ -62,6 +62,10 @@ public class ConformingDelaunayTriangulationBuilder
 	/**
 	 * Sets the sites (point or vertices) which will be triangulated.
 	 * All vertices of the given geometry will be used as sites.
+	 * The site vertices do not have to contain the constraint
+	 * vertices as well; any site vertices which are 
+	 * identical to a constraint vertex will be removed
+	 * from the site vertex set.
 	 * 
 	 * @param geom the geometry from which the sites will be extracted.
 	 */
@@ -73,6 +77,8 @@ public class ConformingDelaunayTriangulationBuilder
 	/**
 	 * Sets the linear constraints to be conformed to.
 	 * All linear components in the input will be used as constraints.
+	 * The constraint vertices do not have to be disjoint from 
+	 * the site vertices.
 	 * 
 	 * @param constraintLines the lines to constraint to
 	 */
@@ -100,29 +106,30 @@ public class ConformingDelaunayTriangulationBuilder
 
 		Envelope siteEnv = DelaunayTriangulationBuilder.envelope(siteCoords);
 		
-		List sites = createConstraintVertices(siteCoords);
-		
 		List segments = new ArrayList();
 		if (constraintLines != null) {
 			siteEnv.expandToInclude(constraintLines.getEnvelopeInternal());
 			createVertices(constraintLines);
 			segments = createConstraintSegments(constraintLines);
 		}
-		
+    List sites = createSiteVertices(siteCoords);
+
 		ConformingDelaunayTriangulator cdt = new ConformingDelaunayTriangulator(sites, tolerance);
 		
-		cdt.setConstraints(segments, new ArrayList(vertexMap.values()));
+		cdt.setConstraints(segments, new ArrayList(constraintVertexMap.values()));
 		
 		cdt.formInitialDelaunay();
 		cdt.enforceConstraints();
 		subdiv = cdt.getSubdivision();
 	}
 	
-	private static List createConstraintVertices(Collection coords)
+	private List createSiteVertices(Collection coords)
 	{
 		List verts = new ArrayList();
 		for (Iterator i = coords.iterator(); i.hasNext(); ) {
 			Coordinate coord = (Coordinate) i.next();
+			if (constraintVertexMap.containsKey(coord)) 
+			  continue;
 			verts.add(new ConstraintVertex(coord));
 		}
 		return verts;
@@ -133,7 +140,7 @@ public class ConformingDelaunayTriangulationBuilder
 		Coordinate[] coords = geom.getCoordinates();
 		for (int i = 0; i < coords.length; i++) {
 			Vertex v = new ConstraintVertex(coords[i]);
-			vertexMap.put(coords[i], v);
+			constraintVertexMap.put(coords[i], v);
 		}
 	}
 	
diff --git a/src/com/vividsolutions/jts/triangulate/ConformingDelaunayTriangulator.java b/src/com/vividsolutions/jts/triangulate/ConformingDelaunayTriangulator.java
index 2d64754..71361e5 100644
--- a/src/com/vividsolutions/jts/triangulate/ConformingDelaunayTriangulator.java
+++ b/src/com/vividsolutions/jts/triangulate/ConformingDelaunayTriangulator.java
@@ -174,7 +174,7 @@ public class ConformingDelaunayTriangulator
 	/**
 	 * Gets the <tt>ConstraintVertexFactory</tt> used to create new constraint vertices at split points.
 	 * 
-	 * @return
+	 * @return a new constraint vertex
 	 */
 	public ConstraintVertexFactory getVertexFactory() {
 		return vertexFactory;
@@ -521,7 +521,7 @@ public class ConformingDelaunayTriangulator
 	 * @param q
 	 *          end of the line segment
 	 * @return a point which is non-Gabriel
-	 * @return null if no point is non-Gabriel
+	 * or null if no point is non-Gabriel
 	 */
 	private Coordinate findNonGabrielPoint(Segment seg) {
 		Coordinate p = seg.getStart();
diff --git a/src/com/vividsolutions/jts/triangulate/DelaunayTriangulationBuilder.java b/src/com/vividsolutions/jts/triangulate/DelaunayTriangulationBuilder.java
index d0f31d5..3b6ebfa 100644
--- a/src/com/vividsolutions/jts/triangulate/DelaunayTriangulationBuilder.java
+++ b/src/com/vividsolutions/jts/triangulate/DelaunayTriangulationBuilder.java
@@ -63,8 +63,9 @@ public class DelaunayTriangulationBuilder
 	
 	public static CoordinateList unique(Coordinate[] coords)
 	{
-		Arrays.sort(coords);
-		CoordinateList coordList = new CoordinateList(coords, false);
+	  Coordinate[] coordsCopy = CoordinateArrays.copyDeep(coords);
+		Arrays.sort(coordsCopy);
+		CoordinateList coordList = new CoordinateList(coordsCopy, false);
 		return coordList;
 	}
 	
@@ -112,7 +113,7 @@ public class DelaunayTriangulationBuilder
 	}
 	
 	/**
-	 * Sets the sites (point or vertices) which will be triangulated.
+	 * Sets the sites (vertices) which will be triangulated.
 	 * All vertices of the given geometry will be used as sites.
 	 * 
 	 * @param geom the geometry from which the sites will be extracted.
@@ -124,10 +125,10 @@ public class DelaunayTriangulationBuilder
 	}
 	
 	/**
-	 * Sets the sites (point or vertices) which will be triangulated
+	 * Sets the sites (vertices) which will be triangulated
 	 * from a collection of {@link Coordinate}s.
 	 * 
-	 * @param geom a collection of Coordinates.
+	 * @param coords a collection of Coordinates.
 	 */
 	public void setSites(Collection coords)
 	{
diff --git a/src/com/vividsolutions/jts/triangulate/NonEncroachingSplitPointFinder.java b/src/com/vividsolutions/jts/triangulate/NonEncroachingSplitPointFinder.java
index 7639051..9efc7f7 100644
--- a/src/com/vividsolutions/jts/triangulate/NonEncroachingSplitPointFinder.java
+++ b/src/com/vividsolutions/jts/triangulate/NonEncroachingSplitPointFinder.java
@@ -84,7 +84,7 @@ public class NonEncroachingSplitPointFinder implements ConstraintSplitPointFinde
      * 
      * @param seg
      * @param encroachPt
-     * @return
+     * @return a split point on the segment
      */
     public static Coordinate projectedSplitPoint(Segment seg, Coordinate encroachPt) {
         LineSegment lineSeg = seg.getLineSegment();
diff --git a/src/com/vividsolutions/jts/triangulate/VertexTaggedGeometryDataMapper.java b/src/com/vividsolutions/jts/triangulate/VertexTaggedGeometryDataMapper.java
index 94b75f7..3535981 100644
--- a/src/com/vividsolutions/jts/triangulate/VertexTaggedGeometryDataMapper.java
+++ b/src/com/vividsolutions/jts/triangulate/VertexTaggedGeometryDataMapper.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.triangulate;
 
 import java.util.*;
@@ -11,7 +44,7 @@ import com.vividsolutions.jts.geom.*;
  * <p>
  * This class can be used in conjunction with {@link VoronoiDiagramBuilder}
  * to transfer data objects from the input site geometries
- * to the constructed Voronou polygons.
+ * to the constructed Voronoi polygons.
  * 
  * @author Martin Davis
  * @see VoronoiDiagramBuilder
diff --git a/src/com/vividsolutions/jts/triangulate/VoronoiDiagramBuilder.java b/src/com/vividsolutions/jts/triangulate/VoronoiDiagramBuilder.java
index dbc9d08..bc3e382 100644
--- a/src/com/vividsolutions/jts/triangulate/VoronoiDiagramBuilder.java
+++ b/src/com/vividsolutions/jts/triangulate/VoronoiDiagramBuilder.java
@@ -79,7 +79,7 @@ public class VoronoiDiagramBuilder
 	 * Sets the sites (point or vertices) which will be diagrammed
 	 * from a collection of {@link Coordinate}s.
 	 * 
-	 * @param geom a collection of Coordinates.
+	 * @param coords a collection of Coordinates.
 	 */
 	public void setSites(Collection coords)
 	{
diff --git a/src/com/vividsolutions/jts/triangulate/quadedge/QuadEdge.java b/src/com/vividsolutions/jts/triangulate/quadedge/QuadEdge.java
index c94fb5e..928161b 100644
--- a/src/com/vividsolutions/jts/triangulate/quadedge/QuadEdge.java
+++ b/src/com/vividsolutions/jts/triangulate/quadedge/QuadEdge.java
@@ -222,7 +222,7 @@ public class QuadEdge
     /**
      * Sets the connected edge
      * 
-     * @param nextEdge edge
+     * @param next edge
      */
     public void setNext(QuadEdge next) {
         this.next = next;
diff --git a/src/com/vividsolutions/jts/triangulate/quadedge/QuadEdgeSubdivision.java b/src/com/vividsolutions/jts/triangulate/quadedge/QuadEdgeSubdivision.java
index b59c2c2..a03fc6b 100644
--- a/src/com/vividsolutions/jts/triangulate/quadedge/QuadEdgeSubdivision.java
+++ b/src/com/vividsolutions/jts/triangulate/quadedge/QuadEdgeSubdivision.java
@@ -197,7 +197,7 @@ public class QuadEdgeSubdivision {
 	 * 
 	 * @param o
 	 * @param d
-	 * @return
+	 * @return a new quadedge
 	 */
 	public QuadEdge makeEdge(Vertex o, Vertex d) {
 		QuadEdge q = QuadEdge.makeEdge(o, d);
@@ -212,7 +212,7 @@ public class QuadEdgeSubdivision {
 	 * 
 	 * @param a
 	 * @param b
-	 * @return
+	 * @return a quadedge
 	 */
 	public QuadEdge connect(QuadEdge a, QuadEdge b) {
 		QuadEdge q = QuadEdge.connect(a, b);
@@ -312,9 +312,9 @@ public class QuadEdgeSubdivision {
 	 * Finds a quadedge of a triangle containing a location 
 	 * specified by a {@link Vertex}, if one exists.
 	 * 
-	 * @param x the vertex to locate
+	 * @param v the vertex to locate
 	 * @return a quadedge on the edge of a triangle which touches or contains the location
-	 * @return null if no such triangle exists
+	 * or null if no such triangle exists
 	 */
 	public QuadEdge locate(Vertex v) {
 		return locator.locate(v);
@@ -326,7 +326,7 @@ public class QuadEdgeSubdivision {
 	 * 
 	 * @param p the Coordinate to locate
 	 * @return a quadedge on the edge of a triangle which touches or contains the location
-	 * @return null if no such triangle exists
+	 * or null if no such triangle exists
 	 */
 	public QuadEdge locate(Coordinate p) {
 		return locator.locate(new Vertex(p));
@@ -339,7 +339,7 @@ public class QuadEdgeSubdivision {
 	 * @param p0 a coordinate
 	 * @param p1 another coordinate
 	 * @return the edge joining the coordinates, if present
-	 * @return null if no such edge exists
+	 * or null if no such edge exists
 	 */
 	public QuadEdge locate(Coordinate p0, Coordinate p1) {
 		// find an edge containing one of the points
@@ -536,7 +536,7 @@ public class QuadEdgeSubdivision {
    * Returning a quadedge for each vertex
    * is more efficient than 
    * the alternative of finding the actual vertices
-   * using {@link #getVertices) and then locating 
+   * using {@link #getVertices} and then locating 
    * quadedges attached to them.
    * 
    * @param includeFrame true if the frame vertices should be included
@@ -681,7 +681,7 @@ public class QuadEdgeSubdivision {
 	 * @param edgeStack
 	 * @param includeFrame
 	 * @return the visited triangle edges
-	 * @return null if the triangle should not be visited (for instance, if it is
+	 * or null if the triangle should not be visited (for instance, if it is
 	 *         outer)
 	 */
 	private QuadEdge[] fetchTriangleToVisit(QuadEdge edge, Stack edgeStack,
@@ -865,7 +865,7 @@ public class QuadEdgeSubdivision {
 	 * Gets the cells in the Voronoi diagram for this triangulation.
 	 * The cells are returned as a {@link GeometryCollection} of {@link Polygon}s
    * <p>
-   * The userData of each polygon is set to be the {@link Coordinate)
+   * The userData of each polygon is set to be the {@link Coordinate}
    * of the cell site.  This allows easily associating external 
    * data associated with the sites to the cells.
 	 * 
@@ -882,7 +882,7 @@ public class QuadEdgeSubdivision {
 	 * Gets a List of {@link Polygon}s for the Voronoi cells 
 	 * of this triangulation.
    * <p>
-   * The userData of each polygon is set to be the {@link Coordinate)
+   * The userData of each polygon is set to be the {@link Coordinate}
    * of the cell site.  This allows easily associating external 
    * data associated with the sites to the cells.
 	 * 
@@ -912,7 +912,7 @@ public class QuadEdgeSubdivision {
    * Gets the Voronoi cell around a site specified
    * by the origin of a QuadEdge.
    * <p>
-   * The userData of the polygon is set to be the {@link Coordinate)
+   * The userData of the polygon is set to be the {@link Coordinate}
    * of the site.  This allows attaching external 
    * data associated with the site to this cell polygon.
    * 
diff --git a/src/com/vividsolutions/jts/triangulate/quadedge/QuadEdgeTriangle.java b/src/com/vividsolutions/jts/triangulate/quadedge/QuadEdgeTriangle.java
index ab10fd0..daa1924 100644
--- a/src/com/vividsolutions/jts/triangulate/quadedge/QuadEdgeTriangle.java
+++ b/src/com/vividsolutions/jts/triangulate/quadedge/QuadEdgeTriangle.java
@@ -137,7 +137,7 @@ public class QuadEdgeTriangle
 	 * index.
 	 * 
 	 * @param index
-	 * @return
+	 * @return the next index
 	 */
 	public static int nextIndex(int index) {
 		return index = (index + 1) % 3;
@@ -220,7 +220,7 @@ public class QuadEdgeTriangle
 	 * @param e
 	 *          a QuadEdge
 	 * @return the index of the edge in this triangle
-	 * @return -1 if the edge is not an edge of this triangle
+	 * or -1 if the edge is not an edge of this triangle
 	 */
 	public int getEdgeIndex(QuadEdge e) {
 		for (int i = 0; i < 3; i++) {
@@ -236,7 +236,7 @@ public class QuadEdgeTriangle
 	 * @param v
 	 *          the vertex to find the edge for
 	 * @return the index of the edge starting at the vertex
-	 * @return -1 if the vertex is not in the triangle
+	 * or -1 if the vertex is not in the triangle
 	 */
 	public int getEdgeIndex(Vertex v) {
 		for (int i = 0; i < 3; i++) {
diff --git a/src/com/vividsolutions/jts/triangulate/quadedge/TrianglePredicate.java b/src/com/vividsolutions/jts/triangulate/quadedge/TrianglePredicate.java
index 1f49663..ac82e60 100644
--- a/src/com/vividsolutions/jts/triangulate/quadedge/TrianglePredicate.java
+++ b/src/com/vividsolutions/jts/triangulate/quadedge/TrianglePredicate.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.triangulate.quadedge;
 
 import com.vividsolutions.jts.geom.Coordinate;
@@ -30,7 +63,7 @@ public class TrianglePredicate
    * @param a a vertex of the triangle
    * @param b a vertex of the triangle
    * @param c a vertex of the triangle
-   * @param P the point to test
+   * @param p the point to test
    * @return true if this point is inside the circle defined by the points a, b, c
    */
   public static boolean isInCircleNonRobust(
@@ -49,7 +82,7 @@ public class TrianglePredicate
    * Tests if a point is inside the circle defined by 
    * the triangle with vertices a, b, c (oriented counter-clockwise). 
    * This test uses simple
-   * double-precision arithmetic, and thus is not 10% robust.
+   * double-precision arithmetic, and thus is not 100% robust.
    * However, by using normalization to the origin
    * it provides improved robustness and increased performance.
    * <p>
@@ -59,7 +92,7 @@ public class TrianglePredicate
    * @param a a vertex of the triangle
    * @param b a vertex of the triangle
    * @param c a vertex of the triangle
-   * @param P the point to test
+   * @param p the point to test
    * @return true if this point is inside the circle defined by the points a, b, c
    */
   public static boolean isInCircleNormalized(
@@ -104,7 +137,7 @@ public class TrianglePredicate
    * @param a a vertex of the triangle
    * @param b a vertex of the triangle
    * @param c a vertex of the triangle
-   * @param P the point to test
+   * @param p the point to test
    * @return true if this point is inside the circle defined by the points a, b, c
    */
   public static boolean isInCircleRobust(
@@ -124,7 +157,7 @@ public class TrianglePredicate
    * @param a a vertex of the triangle
    * @param b a vertex of the triangle
    * @param c a vertex of the triangle
-   * @param P the point to test
+   * @param p the point to test
    * @return true if this point is inside the circle defined by the points a, b, c
    */
   public static boolean isInCircleDDSlow(
diff --git a/src/com/vividsolutions/jts/triangulate/quadedge/Vertex.java b/src/com/vividsolutions/jts/triangulate/quadedge/Vertex.java
index 8796875..ec29542 100644
--- a/src/com/vividsolutions/jts/triangulate/quadedge/Vertex.java
+++ b/src/com/vividsolutions/jts/triangulate/quadedge/Vertex.java
@@ -42,11 +42,17 @@ import com.vividsolutions.jts.algorithm.*;
 
 /**
  * Models a site (node) in a {@link QuadEdgeSubdivision}. 
- * The sites can be points on a lineString representing a
+ * The sites can be points on a line string representing a
  * linear site. 
+ * <p>
  * The vertex can be considered as a vector with a norm, length, inner product, cross
  * product, etc. Additionally, point relations (e.g., is a point to the left of a line, the circle
  * defined by this point and two others, etc.) are also defined in this class.
+ * <p>
+ * It is common to want to attach user-defined data to 
+ * the vertices of a subdivision.  
+ * One way to do this is to subclass <tt>Vertex</tt>
+ * to carry any desired information.
  * 
  * @author David Skea
  * @author Martin Davis
@@ -149,7 +155,7 @@ public class Vertex
     /**
      * Computes the inner or dot product
      * 
-     * @param v, a vertex
+     * @param v a vertex
      * @return returns the dot product u.v
      */
     double dot(Vertex v) {
@@ -159,7 +165,7 @@ public class Vertex
     /**
      * Computes the scalar product c(v)
      * 
-     * @param v, a vertex
+     * @param v a vertex
      * @return returns the scaled vector
      */
     Vertex times(double c) {
@@ -324,7 +330,7 @@ public class Vertex
     }
 
     /**
-     * For this vertex enclosed in a triangle defined by three verticies v0, v1 and v2, interpolate
+     * For this vertex enclosed in a triangle defined by three vertices v0, v1 and v2, interpolate
      * a z value from the surrounding vertices.
      */
     public double interpolateZValue(Vertex v0, Vertex v1, Vertex v2) {
@@ -344,7 +350,17 @@ public class Vertex
     }
 
     /**
-     * Interpolates the Z value of a point enclosed in a 3D triangle.
+     * Interpolates the Z-value (height) of a point enclosed in a triangle
+     * whose vertices all have Z values.
+     * The containing triangle must not be degenerate
+     * (in other words, the three vertices must enclose a 
+     * non-zero area).
+     * 
+     * @param p the point to interpolate the Z value of
+     * @param v0 a vertex of a triangle containing the p
+     * @param v1 a vertex of a triangle containing the p
+     * @param v2 a vertex of a triangle containing the p
+     * @return the interpolated Z-value (height) of the point  
      */
     public static double interpolateZ(Coordinate p, Coordinate v0, Coordinate v1, Coordinate v2) {
         double x0 = v0.x;
@@ -368,7 +384,7 @@ public class Vertex
      * @param p
      * @param p0
      * @param p1
-     * @return
+     * @return the interpolated Z value
      */
     public static double interpolateZ(Coordinate p, Coordinate p0, Coordinate p1) {
         double segLen = p0.distance(p1);
diff --git a/src/com/vividsolutions/jts/util/CollectionUtil.java b/src/com/vividsolutions/jts/util/CollectionUtil.java
index cb6b349..82c9d9c 100644
--- a/src/com/vividsolutions/jts/util/CollectionUtil.java
+++ b/src/com/vividsolutions/jts/util/CollectionUtil.java
@@ -1,3 +1,36 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+
 package com.vividsolutions.jts.util;
 
 import java.util.*;
@@ -64,4 +97,4 @@ public class CollectionUtil
     }
     return result;
   }
-}
\ No newline at end of file
+}
diff --git a/src/com/vividsolutions/jts/util/GeometricShapeFactory.java b/src/com/vividsolutions/jts/util/GeometricShapeFactory.java
index 987d291..89c28ad 100644
--- a/src/com/vividsolutions/jts/util/GeometricShapeFactory.java
+++ b/src/com/vividsolutions/jts/util/GeometricShapeFactory.java
@@ -413,7 +413,13 @@ public class GeometricShapeFactory
     public Coordinate getBase() { return base; }
     
     public void setCentre(Coordinate centre)  {  this.centre = centre;    }
-    public Coordinate getCentre() { return centre; }
+    public Coordinate getCentre() 
+    { 
+      if (centre == null) {
+        centre = new Coordinate(base.x + width/2, base.y + height/2);
+      }
+      return centre; 
+    }
    
     public void setSize(double size)
     {
diff --git a/src/com/vividsolutions/jts/util/Memory.java b/src/com/vividsolutions/jts/util/Memory.java
index d9c4a99..552497b 100644
--- a/src/com/vividsolutions/jts/util/Memory.java
+++ b/src/com/vividsolutions/jts/util/Memory.java
@@ -33,7 +33,7 @@
 package com.vividsolutions.jts.util;
 
 /**
- * Utility functions to report memory usage.
+ * Utility functions to report JVM memory usage.
  * 
  * @author mbdavis
  *
diff --git a/src/com/vividsolutions/jts/util/PriorityQueue.java b/src/com/vividsolutions/jts/util/PriorityQueue.java
index 6b3d4af..5ce720b 100644
--- a/src/com/vividsolutions/jts/util/PriorityQueue.java
+++ b/src/com/vividsolutions/jts/util/PriorityQueue.java
@@ -115,8 +115,7 @@ public class PriorityQueue
 
   /**
    * Remove the smallest item from the priority queue.
-   * @return the smallest item.
-   * @return null if empty
+   * @return the smallest item, or null if empty
    */
   public Object poll() 
   {
diff --git a/testxml/external/GEOSBuffer.xml b/testxml/external/GEOSBuffer.xml
index 1965b0d..ceeac78 100644
--- a/testxml/external/GEOSBuffer.xml
+++ b/testxml/external/GEOSBuffer.xml
@@ -44,4 +44,16 @@ MULTIPOLYGON (((2350000.0000000000000000 1488707.0969169281888753, 2349964.40041
 </test>
 </case>
 
+<case>
+  <desc>GEOS #605 - smallest case.  Works in JTS, but triggers fixed-precision fallback.</desc>
+  <a>
+    LINESTRING (365851.1186 6133776.04159, 366074.9243 6134077.56523, 375141.3101 6138794.83236, 373718.87248 6137668.4963, 373346.64754 6137433.71166638, 366752.527 6134568.1015, 360775.41757 6127074.35479, 360762.97098 6127054.06482, 365851.11862 6133776.04159, 366074.92434 6134077.56523, 366360.99154 6134339.22803, 366752.52702 6134568.1015, 373346.64754 6137433.71166638, 373718.87248 6137668.4963, 375295.49858 6138886.9262, 373718.87248 6137668.4963, 373346.64754 6137433.71166, 36682 [...]
+  </a>
+<test>
+  <op name="buffer" arg1="A" arg2="1000.0">
+    POLYGON ((355917.67656 6124381.22758, 355939.27747 6124576.05034, 355998.46805 6124762.91656, 356092.97404 6124934.64636, 356219.16428 6125084.64146, 356372.19022 6125207.13868, 359638.80782 6127332.78479, 360038.85848 6127754.60444, 360042.83714 6127759.59265, 365050.94349 6134375.82647, 365271.94686 6134673.57465, 365271.94782 6134673.57567, 365399.99268 6134815.44547, 365686.05988 6135077.10827, 365731.38144 6135110.49622, 365766.07316 6135142.63065, 365855.41384 6135201.86967, 36 [...]
+  </op>
+</test>
+</case>
+
 </run>
diff --git a/testxml/external/TestBufferJagged.xml b/testxml/external/TestBufferJagged.xml
new file mode 100644
index 0000000..0fbd610
--- /dev/null
+++ b/testxml/external/TestBufferJagged.xml
@@ -0,0 +1,75 @@
+<run>
+<precisionModel type="FLOATING"/>
+<resultMatcher>com.vividsolutions.jtstest.testrunner.BufferResultMatcher</resultMatcher>
+
+<case>
+
+  <desc>
+Test case from Safe Software. 
+See http://trac.osgeo.org/geos/wiki/BufferRobustness
+ </desc>
+
+  <a>
+    POLYGON ((99736.4572496327 -2239219.11305743, 99736.6573549178 -2239219.11305743, 99736.6573549178 -2239219.01300479, 99736.5573022753 -2239219.01300479, 99736.5573022753 -2239218.8128995, 99736.6573549178 -2239218.8128995, 99736.6573549178 -2239218.91295215, 99736.7574075604 -2239218.91295215, 99736.7574075604 -2239219.01300479, 99736.8574602029 -2239219.01300479, 99736.8574602029 -2239219.11305743, 99736.9575128455 -2239219.11305743, 99736.9575128455 -2239219.21311007, 99737.057565 [...]
+  </a>
+
+  <test>
+    <desc>buffer-0.35: see http://trac.osgeo.org/geos/wiki/BufferRobustness</desc>
+    <op name="buffer" arg1="a" arg2="0.35">
+      POLYGON ((99725.2015115944 -2239210.264040296, 99725.2015115944 -2239209.90821432, 99725.20823674626 -2239209.839932707, 99725.22815375803 -2239209.7742751185, 99725.26049723009 -2239209.7137647383, 99725.3015642369 -2239209.663724446, 99725.3015642369 -2239209.60805639, 99725.30649139937 -2239209.5580300703, 99725.3015642369 -2239209.50800375, 99725.3015642369 -2239209.4079511, 99725.30828938876 -2239209.339669487, 99725.32820640053 -2239209.2740118983, 99725.3605498726 -2239209.2 [...]
+  (99729.4984977109 -2239209.7583196, 99729.5536172965 -2239209.7583196, 99729.60421676433 -2239209.763303213, 99729.60628785078 -2239209.7607795866, 99729.60868865077 -2239209.758809301, 99729.61055301856 -2239209.739880057, 99729.63047003033 -2239209.6742224684, 99729.6628135024 -2239209.613712088, 99729.70388050929 -2239209.5636717957, 99729.70388050929 -2239209.50800375, 99729.70880767224 -2239209.457977425, 99729.70388050929 -2239209.4079511, 99729.70388050929 -2239209.352283054, 99 [...]
+    </op>
+  </test>
+
+  <test>
+    <desc>buffer-0.75: see http://trac.osgeo.org/geos/wiki/BufferRobustness</desc>
+    <op name="buffer" arg1="a" arg2="0.75">
+      POLYGON((99724.80151159 -2239210.14114081,99724.80151159 -2239209.90821432,99724.81592263 -2239209.76189657,99724.85860194 -2239209.62120174,99724.9042938714 -2239209.53571816,99724.90156424 -2239209.50800375,99724.90156424 -2239209.4079511,99724.91597528 -2239209.26163336,99724.95865459 -2239209.12093853,99725.02796203 -2239208.99127343,99725.0428380369 -2239208.97314696,99725.05870723 -2239208.92083324,99725.12801467 -2239208.79116814,99725.22128679 -2239208.67751573,99725.276240 [...]
+    </op>
+  </test>
+
+  <test>
+    <desc>buffer-1.01 (#494)</desc>
+    <op name="buffer" arg1="a" arg2="1.01">
+      POLYGON ((99724.5415116 -2239210.07866999,99724.5415116 -2239209.9082143,99724.5609185 -2239209.7111731,99724.6183933 -2239209.521704,99724.6415642 -2239209.4783543,99724.6415642 -2239209.4079511,99724.6609711 -2239209.2109099,99724.7184459 -2239209.0214408,99724.8094364244 -2239208.85120953,99724.8184986 -2239208.8213356,99724.9118326 -2239208.6467199,99725.037439 -2239208.493668,99725.0923925052 -2239208.44856881,99725.1374917 -2239208.3936153,99725.19244517 -2239208.34851617,997 [...]
+    </op>
+  </test>
+
+  <test>
+    <desc>buffer-1.1</desc>
+    <op name="buffer" arg1="a" arg2="1.1">
+      POLYGON ((99724.45151159 -2239210.0570456,99724.45151159 -2239209.90821432,99724.47264779 -2239209.69361496,99724.53524411 -2239209.48726254,99724.55156424 -2239209.45672972,99724.55156424 -2239209.4079511,99724.57270043 -2239209.19335175,99724.63529675 -2239208.98699933,99724.7262871367 -2239208.81676829,99724.73534939 -2239208.78689404,99724.83700031 -2239208.59671856,99724.97379942 -2239208.43002836,99725.0287529111 -2239208.38492919,99725.07385206 -2239208.32997572,99725.128805 [...]
+    </op>
+  </test>
+
+  <test>
+    <desc>buffer-1.5</desc>
+    <op name="buffer" arg1="a" arg2="1.5">
+POLYGON ((99723.95146 -2239211.2089, 99723.95146 -2239210.50853, 99723.98028 -2239210.21589, 99724.05151 -2239209.98109, 99724.05151 -2239209.90821, 99724.08033 -2239209.61558, 99724.15553 -2239209.3677, 99724.18039 -2239209.11532, 99724.26574 -2239208.83393, 99724.35674 -2239208.66369, 99724.3658 -2239208.63382, 99724.50441 -2239208.37449, 99724.69096 -2239208.14719, 99724.7459 -2239208.1021, 99724.79101 -2239208.04713, 99724.84597 -2239208.00203, 99724.89106 -2239207.94708, 99724.94601 [...]
+    </op>
+  </test>
+
+  <test>
+    <desc>buffer-2</desc>
+    <op name="buffer" arg1="a" arg2="2">
+POLYGON ((99723.45146 -2239211.2089, 99723.45146 -2239210.50853, 99723.48989 -2239210.11835, 99723.55151 -2239209.91521, 99723.55151 -2239209.90821, 99723.58994 -2239209.51803, 99723.66513 -2239209.27016, 99723.68999 -2239209.01777, 99723.80381 -2239208.64258, 99723.8948 -2239208.47236, 99723.90386 -2239208.44248, 99724.08868 -2239208.09671, 99724.3374 -2239207.79363, 99724.39237 -2239207.74852, 99724.43746 -2239207.69358, 99724.49241 -2239207.64848, 99724.53751 -2239207.59353, 99724.592 [...]
+</op>
+  </test>
+
+  <test>
+    <desc>buffer-5</desc>
+    <op name="buffer" arg1="a" arg2="5">
+POLYGON ((99720.45146 -2239211.2089, 99720.45146 -2239210.50853, 99720.54753 -2239209.53308, 99720.60814 -2239209.33328, 99720.64759 -2239208.93276, 99720.72278 -2239208.68488, 99720.74764 -2239208.4325, 99721.03217 -2239207.49453, 99721.12316 -2239207.32431, 99721.13222 -2239207.29443, 99721.59427 -2239206.42999, 99722.21608 -2239205.67231, 99722.27106 -2239205.62719, 99722.31614 -2239205.57226, 99722.37109 -2239205.52716, 99722.41619 -2239205.47221, 99722.47112 -2239205.42713, 99722.51 [...]
+    </op>
+  </test>
+
+  <test>
+    <desc>buffer-10</desc>
+    <op name="buffer" arg1="a" arg2="10">
+      POLYGON((99739.3044617493 -2239228.93117449,99739.008469 -2239229.020963,99737.057565 -2239229.21311,99736.957513 -2239229.21311,99735.00661 -2239229.020963,99734.7587215452 -2239228.94576679,99734.506346 -2239228.92091,99732.630415 -2239228.351853,99732.2899489618 -2239228.16987015,99732.230205 -2239228.151747,99730.501337 -2239227.227648,99730.4848796373 -2239227.2141418,99728.62831 -2239226.650958,99728.5893723796 -2239226.63014541,99728.328152 -2239226.550905,99726.599284 -2239 [...]
+    </op>
+  </test>
+
+</case>
+
+</run>
diff --git a/testxml/external/TestValid.xml b/testxml/external/TestValid.xml
new file mode 100644
index 0000000..cb0eb22
--- /dev/null
+++ b/testxml/external/TestValid.xml
@@ -0,0 +1,26 @@
+<run>
+  <precisionModel type="FLOATING"/>
+
+<case>
+<desc>Robustness issue when validating polygon with nearly parallel edges separated by small distance
+(self-intersection).  
+Fixed by extended-precision determinant.
+http://trac.osgeo.org/geos/ticket/588
+</desc>
+<a>
+POLYGON ((
+ -86.3958130146539250 114.3482370100377900,
+ 55.7321237336437390 -44.8146215164960250,
+ 87.9271046586986810 -10.5302909001479530,
+ 87.9271046586986810 -10.5302909001479570,
+ 138.3490775437400700 43.1639042523018260,
+ 64.7285128575111490 156.9678884302379600,
+ -86.3958130146539250 114.3482370100377900))
+</a>
+
+<test>
+<op name="isValid" arg1="A" > true </op>
+</test>
+</case>
+
+</run>
\ No newline at end of file
diff --git a/testxml/failure/TestBufferInsideNonEmpty.xml b/testxml/failure/TestBufferInsideNonEmpty.xml
new file mode 100644
index 0000000..56fbd78
--- /dev/null
+++ b/testxml/failure/TestBufferInsideNonEmpty.xml
@@ -0,0 +1,22 @@
+<run>
+  <desc>Test case from Anders Johansson - JTS list - Nov 29 2011 
+  Inside buffer of a simple rectangular geometry fails - should be empty, but is non-empty.
+  </desc>
+  <precisionModel type="FLOATING"/>
+  <resultMatcher>com.vividsolutions.jtstest.testrunner.BufferResultMatcher</resultMatcher>
+
+<case>
+  <desc>Buffer</desc>
+  <a>
+POLYGON ((0.28 0.38, 0.41 0.21, 0.13 0, 0 0.16, 0.28 0.38))
+</a>
+
+  <test>
+    <op name="buffer" arg1="a" arg2="-.18">
+POLYGON EMPTY
+</op>
+  </test>
+
+</case>
+
+</run>
\ No newline at end of file
diff --git a/testxml/failure/TestOverlay.xml b/testxml/failure/TestOverlay.xml
index 4a1ab5c..9dd618b 100644
--- a/testxml/failure/TestOverlay.xml
+++ b/testxml/failure/TestOverlay.xml
@@ -195,4 +195,31 @@ GEOMETRYCOLLECTION EMPTY
 </test>
 </case>
 
+<case>
+  <desc>
+  JTS list - March 19 2012.
+  Union of two partially-overlapping polygons returns an incorrect result equal to one of inputs (with node added).
+  
+  This is definitely a robustness error, and a particularly insidious one.  At least part of the problem is that while mathematically the point
+	
+	POINT (42.975 -92.25)
+	
+	lies exactly on the line segment
+	
+	LINESTRING (126 -184.5, -9 -34.5)
+	
+the algorithms that JTS uses report that the point lies off the line (and that's with 2 completely different procedures).  This makes me think that possibly the Java text-to-floating point conversion is not converting the numbers precisely (although there may well be something else causing this - I hesitate to blame the core Java library, which must be pretty well tested by now!).
+
+Correct expected result is computed by hand.
+  </desc>
+<a>
+POLYGON ((42.975 -92.25, 100 0, -200 0, 126 -184.5, 42.975 -92.25))</a>
+<b>
+POLYGON ((126 -184.5, -9 -34.5, -200 -300, 126 -184.5))</b>
+<test>
+<op name="intersection" arg1="A" arg2="B">
+POLYGON ((-46.626 -86.802, -200 0, 100 0, 42.975 -92.25, 126 -184.5, -200 -300, -46.626 -86.802))</op>
+</test>
+</case>
+
 </run>
diff --git a/testxml/failure/TestOverlay.xml b/testxml/failure/TestOverlayFailure.xml
similarity index 78%
copy from testxml/failure/TestOverlay.xml
copy to testxml/failure/TestOverlayFailure.xml
index 4a1ab5c..527eb4f 100644
--- a/testxml/failure/TestOverlay.xml
+++ b/testxml/failure/TestOverlayFailure.xml
@@ -195,4 +195,67 @@ GEOMETRYCOLLECTION EMPTY
 </test>
 </case>
 
+<case>
+  <desc>
+  JTS list - March 19 2012.
+  Union of two partially-overlapping polygons returns an incorrect result equal to one of inputs (with node added).
+  
+  This is definitely a robustness error, and a particularly insidious one.  At least part of the problem is that while mathematically the point
+	
+	POINT (42.975 -92.25)
+	
+	lies exactly on the line segment
+	
+	LINESTRING (126 -184.5, -9 -34.5)
+	
+the algorithms that JTS uses report that the point lies off the line (and that's with 2 completely different procedures).  This makes me think that possibly the Java text-to-floating point conversion is not converting the numbers precisely (although there may well be something else causing this - I hesitate to blame the core Java library, which must be pretty well tested by now!).
+
+Correct expected result is computed by hand.
+  </desc>
+<a>
+POLYGON ((42.975 -92.25, 100 0, -200 0, 126 -184.5, 42.975 -92.25))</a>
+<b>
+POLYGON ((126 -184.5, -9 -34.5, -200 -300, 126 -184.5))</b>
+<test>
+<op name="intersection" arg1="A" arg2="B">
+POLYGON ((-46.626 -86.802, -200 0, 100 0, 42.975 -92.25, 126 -184.5, -200 -300, -46.626 -86.802))</op>
+</test>
+</case>
+
+<case>
+  <desc>
+  Personal email - Nov 6 2012
+  Two issues:
+  - Intersection point roundoff causes intersected segment to move across another vertex
+  - Polygon B has a very small hole very near the shell, which prevents snapping from working.
+  </desc>
+<a>
+POLYGON ((3331887.403422648 3661593.7342660464, 3327296.9868580834 3657803.3373506065, 3327296.986858083 3657803.337350607, 3317921.869437724 3650062.1191730825, 3311387.4153281646 3645901.186354534, 3305053.3363020215 3641286.7914633057, 3299086.6115955096 3636933.941773851, 3297499.392954649 3635662.6758946413, 3295324.0128066926 3633920.328315541, 3295045.714079711 3633595.6292730314, 3293565.164852161 3632452.7563738194, 3292474.2338423817 3631621.6423231405, 3286874.8634554786 36274 [...]
+</a>
+<b>
+POLYGON ((3334546.228183764 3663789.1779761068, 3334507.2045345404 3663756.955384199, 3334447.580123011 3663707.7223391435, 3334364.100090413 3663638.791240275, 3334255.5397380586 3663549.150829886, 3334184.017357254 3663490.0933984364, 3334094.3533072392 3663416.0560351987, 3333989.606200989 3663329.5642968463, 3333477.0091599287 3662906.302874714, 3333111.689118296 3662604.650957186, 3332904.0328812357 3662433.18513282, 3332837.148123394 3662377.9570775344, 3317921.869437724 3650062.11 [...]
+</b><test>
+<op name="intersection" arg1="A" arg2="B">
+GEOMETRYCOLLECTION EMPTY</op>
+</test>
+</case>
+
+<case>
+  <desc>
+  http://trac.osgeo.org/postgis/ticket/2055
+  
+  A triangle which has a segment crossing a segment of a hole very near one end.
+  Computed intersection causes a topology failure.
+  </desc>
+<a>
+POLYGON ((184315 319325, 184315 319290, 184276 319290, 184276 319325, 184315 319325), (184311.5625999868 319321, 184304.75 319308.59379998595, 184295.64059999958 319292.90599998087, 184304.75 319308.5937999822, 184311.5625999868 319321))
+</a>
+<b>
+POLYGON ((184299.5210452684 319312.2400717032, 184311.5626000017 319321, 184306.59797855775 319312.2400717032, 184299.5210452684 319312.2400717032))
+</b><test>
+<op name="intersection" arg1="A" arg2="B">
+GEOMETRYCOLLECTION EMPTY</op>
+</test>
+</case>
+
 </run>
diff --git a/testxml/general/TestCentroid.xml b/testxml/general/TestCentroid.xml
index d82fd3a..e43fc17 100644
--- a/testxml/general/TestCentroid.xml
+++ b/testxml/general/TestCentroid.xml
@@ -1,5 +1,11 @@
 <run>
-  <precisionModel scale="1.0" offsetx="0.0" offsety="0.0"/>
+  <!-- <precisionModel scale="1.0" offsetx="0.0" offsety="0.0"/> -->
+
+<case>
+  <desc>P - empty</desc>
+  <a>    POINT EMPTY  </a>
+<test><op name="getCentroid" arg1="A" >    POINT EMPTY   </op></test>
+</case>
 
 <case>
   <desc>P - single point</desc>
@@ -35,7 +41,7 @@
   <desc>L - elongated horseshoe</desc>
   <a>    LINESTRING (80 0, 80 120, 120 120, 120 0))
 	</a>
-<test><op name="getCentroid" arg1="A" >    POINT (100 69)   </op></test>
+<test><op name="getCentroid" arg1="A" >    POINT (100 68.57142857142857)   </op></test>
 </case>
 
 
@@ -76,7 +82,7 @@
 <case>
   <desc>A - box with hole</desc>
   <a>    POLYGON ((0 200, 200 200, 200 0, 0 0, 0 200), (20 180, 80 180, 80 20, 20 20, 20 180)) </a>
-<test><op name="getCentroid" arg1="A" >    POINT (116 100)   </op></test>
+<test><op name="getCentroid" arg1="A" >    POINT (115.78947368421052 100)  </op></test>
 </case>
 
 <case>
@@ -84,7 +90,7 @@
   <a>    POLYGON ((0 0, 0 200, 200 200, 200 0, 0 0), 
   (60 180, 20 180, 20 140, 60 140, 60 180))
 	 </a>
-<test><op name="getCentroid" arg1="A" >    POINT (103 98)   </op></test>
+<test><op name="getCentroid" arg1="A" >    POINT (102.5 97.5)  </op></test>
 </case>
 
 <case>
@@ -109,7 +115,7 @@
   <a>    GEOMETRYCOLLECTION (POLYGON ((0 200, 20 180, 20 140, 60 140, 200 0, 0 0, 0 200)), 
   POLYGON ((200 200, 0 200, 20 180, 60 180, 60 140, 200 0, 200 200))) 
 	</a>
-<test><op name="getCentroid" arg1="A" >    POINT (103 98)   </op></test>
+<test><op name="getCentroid" arg1="A" >    POINT (102.5 97.5)   </op></test>
 </case>
 
 <case>
@@ -117,7 +123,7 @@
   <a>    GEOMETRYCOLLECTION (LINESTRING (80 0, 80 120, 120 120, 120 0), 
   MULTIPOINT ((20 60), (40 80), (60 60)))
 	</a>
-<test><op name="getCentroid" arg1="A" >    POINT (100 69)   </op></test>
+<test><op name="getCentroid" arg1="A" >    POINT (100 68.57142857142857)   </op></test>
 </case>
 
 <case>
@@ -157,6 +163,24 @@
 <test><op name="getCentroid" arg1="A" >    POINT (55 55)   </op></test>
 </case>
 
+<case>
+  <desc>A - empty</desc>
+  <a>    POLYGON EMPTY
+	</a>
+<test><op name="getCentroid" arg1="A" >    POINT EMPTY   </op></test>
+</case>
+
+<case>
+  <desc>A - almost degenerate triangle</desc>
+  <a>    POLYGON((
+56.528666666700 25.2101666667,
+56.529000000000 25.2105000000,
+56.528833333300 25.2103333333,
+56.528666666700 25.2101666667))
+	</a>
+<test><op name="getCentroid" arg1="A" >    POINT (56.52883333335 25.21033333335)  </op></test>
+</case>
+
 
 
 </run>
diff --git a/testxml/general/TestConvexHull.xml b/testxml/general/TestConvexHull.xml
index af5c12e..a522a35 100644
--- a/testxml/general/TestConvexHull.xml
+++ b/testxml/general/TestConvexHull.xml
@@ -1,5 +1,4 @@
 <run>
-  <precisionModel scale="1.0" offsetx="0.0" offsety="0.0"/>
 
 <case>
   <desc>Several points collinear and overlapping</desc>
@@ -172,4 +171,16 @@
 </test>
 </case>
 
+<case>
+  <desc>Almost collinear points, which caused robustness failure in JTS 1.12</desc>
+  <a>
+LINESTRING (0 0, -140.8859438214298 140.88594382142983, -57.309236848216706 57.30923684821671, -190.9188309203678 190.91883092036784, -60 300)
+</a>
+<test>
+  <op name="convexhull" arg1="A">
+    POLYGON ((0 0, -57.309236848216706 57.30923684821671, -190.9188309203678 190.91883092036784, -60 300, 0 0))
+  </op>
+</test>
+</case>
+
 </run>
diff --git a/testxml/general/TestFunctionLA.xml b/testxml/general/TestFunctionLA.xml
index faed675..d48d859 100644
--- a/testxml/general/TestFunctionLA.xml
+++ b/testxml/general/TestFunctionLA.xml
@@ -212,7 +212,7 @@
 </test>
 <test>
   <op name="intersection" pattern="FFFFFFFFF" arg1="A" arg2="B">
-    GEOMETRYCOLLECTION EMPTY
+    LINESTRING EMPTY
   </op>
 </test>
 </case>
diff --git a/testxml/general/TestFunctionLL.xml b/testxml/general/TestFunctionLL.xml
index cca53dc..4b81726 100644
--- a/testxml/general/TestFunctionLL.xml
+++ b/testxml/general/TestFunctionLL.xml
@@ -97,7 +97,7 @@
 </test>
 <test>
   <op name="intersection" arg1="A" arg2="B">
-    GEOMETRYCOLLECTION EMPTY
+    LINESTRING EMPTY
   </op>
 </test>
 <test>
@@ -249,12 +249,12 @@
 </test>
 <test>
   <op name="difference" arg1="A" arg2="B">
-    GEOMETRYCOLLECTION EMPTY
+    LINESTRING EMPTY
   </op>
 </test>
 <test>
   <op name="symdifference" arg1="A" arg2="B">
-    GEOMETRYCOLLECTION EMPTY
+    LINESTRING EMPTY
   </op>
 </test>
 </case>
diff --git a/testxml/general/TestFunctionPP.xml b/testxml/general/TestFunctionPP.xml
index dda33a9..94b9d38 100644
--- a/testxml/general/TestFunctionPP.xml
+++ b/testxml/general/TestFunctionPP.xml
@@ -26,7 +26,7 @@
   </b>
 <test>
   <op name="intersection" arg1="A" arg2="B">
-    GEOMETRYCOLLECTION EMPTY
+    POINT EMPTY
   </op>
 </test>
 <test>
@@ -66,7 +66,7 @@
 </test>
 <test>
   <op name="difference" arg1="A" arg2="B">
-    GEOMETRYCOLLECTION EMPTY
+    POINT EMPTY
   </op>
 </test>
 <test>
@@ -136,12 +136,12 @@
 </test>
 <test>
   <op name="difference" arg1="A" arg2="B">
-    GEOMETRYCOLLECTION EMPTY
+    POINT EMPTY
   </op>
 </test>
 <test>
   <op name="symdifference" arg1="A" arg2="B">
-    GEOMETRYCOLLECTION EMPTY
+    POINT EMPTY
   </op>
 </test>
 </case>
@@ -166,7 +166,7 @@
 </test>
 <test>
   <op name="intersection" arg1="A" arg2="B">
-    GEOMETRYCOLLECTION EMPTY
+    POINT EMPTY
   </op>
 </test>
 <test>
@@ -206,7 +206,7 @@
 </test>
 <test>
   <op name="intersection" arg1="A" arg2="B">
-    GEOMETRYCOLLECTION EMPTY
+    POINT EMPTY
   </op>
 </test>
 <test>
@@ -246,7 +246,7 @@
 </test>
 <test>
   <op name="intersection" arg1="A" arg2="B">
-    GEOMETRYCOLLECTION EMPTY
+    POINT EMPTY
   </op>
 </test>
 <test>
diff --git a/testxml/general/TestInteriorPoint.xml b/testxml/general/TestInteriorPoint.xml
index 08fad0c..dfcc74d 100644
--- a/testxml/general/TestInteriorPoint.xml
+++ b/testxml/general/TestInteriorPoint.xml
@@ -2,6 +2,12 @@
   <precisionModel scale="1.0" offsetx="0.0" offsety="0.0"/>
 
 <case>
+  <desc>P - empty</desc>
+  <a>    POINT EMPTY  </a>
+<test><op name="getInteriorPoint" arg1="A" >    POINT EMPTY   </op></test>
+</case>
+
+<case>
   <desc>P - single point</desc>
   <a>    POINT(10 10)  </a>
 <test><op name="getInteriorPoint" arg1="A" >    POINT(10 10)   </op></test>
@@ -44,6 +50,13 @@
 </case>
 
 <case>
+  <desc>A - empty</desc>
+  <a>    POLYGON EMPTY
+	</a>
+<test><op name="getInteriorPoint" arg1="A" >    POINT EMPTY   </op></test>
+</case>
+
+<case>
   <desc>mA - polygons with holes</desc>
   <a>    MULTIPOLYGON (((60 320, 240 340, 260 100, 20 60, 120 180, 60 320), 
   (200 280, 140 260, 180 160, 240 140, 200 280)), 
diff --git a/testxml/general/TestOverlayEmpty.xml b/testxml/general/TestOverlayEmpty.xml
new file mode 100644
index 0000000..4074881
--- /dev/null
+++ b/testxml/general/TestOverlayEmpty.xml
@@ -0,0 +1,1021 @@
+<run>
+  <desc>  Test type of empty results from overlay operations  </desc>
+
+
+<case>
+  <a> POINT EMPTY </a>
+  <b> POINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT EMPTY </a>
+  <b> LINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT EMPTY </a>
+  <b> POLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT EMPTY </a>
+  <b> POINT (1 1) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT EMPTY </a>
+  <b> LINESTRING (5 5, 6 6) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT EMPTY </a>
+  <b> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT EMPTY </a>
+  <b> MULTIPOINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT EMPTY </a>
+  <b> MULTILINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT EMPTY </a>
+  <b> MULTIPOLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT EMPTY </a>
+  <b> MULTIPOINT ((2 2), (3 3)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT EMPTY </a>
+  <b> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT EMPTY </a>
+  <b> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING EMPTY </a>
+  <b> POINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING EMPTY </a>
+  <b> LINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING EMPTY </a>
+  <b> POLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING EMPTY </a>
+  <b> POINT (1 1) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING EMPTY </a>
+  <b> LINESTRING (5 5, 6 6) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING EMPTY </a>
+  <b> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING EMPTY </a>
+  <b> MULTIPOINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING EMPTY </a>
+  <b> MULTILINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING EMPTY </a>
+  <b> MULTIPOLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING EMPTY </a>
+  <b> MULTIPOINT ((2 2), (3 3)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING EMPTY </a>
+  <b> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING EMPTY </a>
+  <b> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON EMPTY </a>
+  <b> POINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON EMPTY </a>
+  <b> LINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON EMPTY </a>
+  <b> POLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON EMPTY </a>
+  <b> POINT (1 1) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON EMPTY </a>
+  <b> LINESTRING (5 5, 6 6) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON EMPTY </a>
+  <b> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON EMPTY </a>
+  <b> MULTIPOINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON EMPTY </a>
+  <b> MULTILINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON EMPTY </a>
+  <b> MULTIPOLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON EMPTY </a>
+  <b> MULTIPOINT ((2 2), (3 3)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON EMPTY </a>
+  <b> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON EMPTY </a>
+  <b> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT (1 1) </a>
+  <b> POINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT (1 1) </a>
+  <b> LINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT (1 1) </a>
+  <b> POLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT (1 1) </a>
+  <b> POINT (1 1) </b>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT (1 1) </a>
+  <b> LINESTRING (5 5, 6 6) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT (1 1) </a>
+  <b> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT (1 1) </a>
+  <b> MULTIPOINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT (1 1) </a>
+  <b> MULTILINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT (1 1) </a>
+  <b> MULTIPOLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT (1 1) </a>
+  <b> MULTIPOINT ((2 2), (3 3)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT (1 1) </a>
+  <b> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POINT (1 1) </a>
+  <b> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING (5 5, 6 6) </a>
+  <b> POINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING (5 5, 6 6) </a>
+  <b> LINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING (5 5, 6 6) </a>
+  <b> POLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING (5 5, 6 6) </a>
+  <b> POINT (1 1) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING (5 5, 6 6) </a>
+  <b> LINESTRING (5 5, 6 6) </b>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING (5 5, 6 6) </a>
+  <b> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING (5 5, 6 6) </a>
+  <b> MULTIPOINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING (5 5, 6 6) </a>
+  <b> MULTILINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING (5 5, 6 6) </a>
+  <b> MULTIPOLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING (5 5, 6 6) </a>
+  <b> MULTIPOINT ((2 2), (3 3)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING (5 5, 6 6) </a>
+  <b> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> LINESTRING (5 5, 6 6) </a>
+  <b> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </a>
+  <b> POINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </a>
+  <b> LINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </a>
+  <b> POLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </a>
+  <b> POINT (1 1) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </a>
+  <b> LINESTRING (5 5, 6 6) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </a>
+  <b> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </b>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </a>
+  <b> MULTIPOINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </a>
+  <b> MULTILINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </a>
+  <b> MULTIPOLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </a>
+  <b> MULTIPOINT ((2 2), (3 3)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </a>
+  <b> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </a>
+  <b> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT EMPTY </a>
+  <b> POINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT EMPTY </a>
+  <b> LINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT EMPTY </a>
+  <b> POLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT EMPTY </a>
+  <b> POINT (1 1) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT EMPTY </a>
+  <b> LINESTRING (5 5, 6 6) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT EMPTY </a>
+  <b> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT EMPTY </a>
+  <b> MULTIPOINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT EMPTY </a>
+  <b> MULTILINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT EMPTY </a>
+  <b> MULTIPOLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT EMPTY </a>
+  <b> MULTIPOINT ((2 2), (3 3)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT EMPTY </a>
+  <b> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT EMPTY </a>
+  <b> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING EMPTY </a>
+  <b> POINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING EMPTY </a>
+  <b> LINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING EMPTY </a>
+  <b> POLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING EMPTY </a>
+  <b> POINT (1 1) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING EMPTY </a>
+  <b> LINESTRING (5 5, 6 6) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING EMPTY </a>
+  <b> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING EMPTY </a>
+  <b> MULTIPOINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING EMPTY </a>
+  <b> MULTILINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING EMPTY </a>
+  <b> MULTIPOLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING EMPTY </a>
+  <b> MULTIPOINT ((2 2), (3 3)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING EMPTY </a>
+  <b> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING EMPTY </a>
+  <b> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON EMPTY </a>
+  <b> POINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON EMPTY </a>
+  <b> LINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON EMPTY </a>
+  <b> POLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON EMPTY </a>
+  <b> POINT (1 1) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON EMPTY </a>
+  <b> LINESTRING (5 5, 6 6) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON EMPTY </a>
+  <b> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON EMPTY </a>
+  <b> MULTIPOINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON EMPTY </a>
+  <b> MULTILINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON EMPTY </a>
+  <b> MULTIPOLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='union'         arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON EMPTY </a>
+  <b> MULTIPOINT ((2 2), (3 3)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON EMPTY </a>
+  <b> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON EMPTY </a>
+  <b> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT ((2 2), (3 3)) </a>
+  <b> POINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT ((2 2), (3 3)) </a>
+  <b> LINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT ((2 2), (3 3)) </a>
+  <b> POLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT ((2 2), (3 3)) </a>
+  <b> POINT (1 1) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT ((2 2), (3 3)) </a>
+  <b> LINESTRING (5 5, 6 6) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT ((2 2), (3 3)) </a>
+  <b> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT ((2 2), (3 3)) </a>
+  <b> MULTIPOINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT ((2 2), (3 3)) </a>
+  <b> MULTILINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT ((2 2), (3 3)) </a>
+  <b> MULTIPOLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT ((2 2), (3 3)) </a>
+  <b> MULTIPOINT ((2 2), (3 3)) </b>
+<test> <op name='difference'    arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT ((2 2), (3 3)) </a>
+  <b> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOINT ((2 2), (3 3)) </a>
+  <b> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </a>
+  <b> POINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </a>
+  <b> LINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </a>
+  <b> POLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </a>
+  <b> POINT (1 1) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </a>
+  <b> LINESTRING (5 5, 6 6) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </a>
+  <b> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </a>
+  <b> MULTIPOINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </a>
+  <b> MULTILINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </a>
+  <b> MULTIPOLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </a>
+  <b> MULTIPOINT ((2 2), (3 3)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </a>
+  <b> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </b>
+<test> <op name='difference'    arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </a>
+  <b> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </a>
+  <b> POINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </a>
+  <b> LINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </a>
+  <b> POLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </a>
+  <b> POINT (1 1) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </a>
+  <b> LINESTRING (5 5, 6 6) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </a>
+  <b> POLYGON ((20 20, 20 30, 30 30, 30 20, 20 20)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </a>
+  <b> MULTIPOINT EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </a>
+  <b> MULTILINESTRING EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </a>
+  <b> MULTIPOLYGON EMPTY </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </a>
+  <b> MULTIPOINT ((2 2), (3 3)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  POINT EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </a>
+  <b> MULTILINESTRING ((7 7, 8 8), (9 9, 10 10)) </b>
+<test> <op name='intersection'  arg1='A' arg2='B'>  LINESTRING EMPTY   </op> </test>
+</case>
+
+<case>
+  <a> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </a>
+  <b> MULTIPOLYGON (((50 50, 50 60, 60 60, 60 50, 50 50)), ((70 70, 70 80, 80 80, 80 70, 70 70))) </b>
+<test> <op name='difference'    arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+<test> <op name='symDifference' arg1='A' arg2='B'>  POLYGON EMPTY   </op> </test>
+</case>
+
+
+</run>
+
diff --git a/testxml/general/TestRectanglePredicate.xml b/testxml/general/TestRectanglePredicate.xml
index 29071ef..30a7cfb 100644
--- a/testxml/general/TestRectanglePredicate.xml
+++ b/testxml/general/TestRectanglePredicate.xml
@@ -12,7 +12,7 @@
       (100 200, 100 140, 180 140, 180 200, 100 200))
   </b>
 <test>  <op name="intersects" arg1="A" arg2="B">   false   </op> </test>
-<test>  <op name="contains" arg1="A" arg2="B">   false   </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B">   false   </op> </test>
 </case>
 
 <case>
@@ -24,7 +24,7 @@
     POLYGON((10 10, 10 90, 90 90, 90 10, 10 10))
   </b>
 <test>  <op name="intersects" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="contains" arg1="A" arg2="B">   true   </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B">   true   </op> </test>
 </case>
 
 <case>
@@ -36,7 +36,7 @@
     POLYGON ((60 180, -100 120, -140 60, -40 20, -100 -80, 40 -20, 140 -100, 140 40, 260 160, 80 120, 60 180))
   </b>
 <test>  <op name="intersects" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="contains" arg1="A" arg2="B">   false   </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B">   false  </op> </test>
 </case>
 
 <case>
@@ -49,10 +49,10 @@
   	((20 280, 0 180, 180 160, 200 280, 20 280)))
   </b>
 <test>  <op name="intersects" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="contains" arg1="A" arg2="B">   false   </op> </test>
-<test>  <op name="within" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="covers" arg1="A" arg2="B">   false   </op> </test>
-<test>  <op name="coveredBy" arg1="A" arg2="B">   true   </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B">   false  </op> </test>
+<test>  <op name="within"     arg1="A" arg2="B">   true   </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B">   false  </op> </test>
+<test>  <op name="coveredBy"  arg1="A" arg2="B">   true   </op> </test>
 </case>
 
 <case>
@@ -74,9 +74,74 @@
   <b>
     LINESTRING(10 10, 10 2000)
   </b>
-<test>  <op name="intersects" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="contains" arg1="A" arg2="B">   false   </op> </test>
-<test>  <op name="covers" arg1="A" arg2="B">   false   </op> </test>
+<test>  <op name="intersects" arg1="A" arg2="B"> true  </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B"> false </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B"> false </op> </test>
+</case>
+
+<case>
+  <desc>L on upward diagonal crosses</desc>
+  <a>
+    POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))
+  </a>
+  <b>
+    LINESTRING (60 120, -20 20)
+  </b>
+<test>  <op name="intersects" arg1="A" arg2="B"> true  </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B"> false </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B"> false </op> </test>
+</case>
+
+<case>
+  <desc>L on downward diagonal crosses</desc>
+  <a>
+    POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))
+  </a>
+  <b>
+    LINESTRING (50 120, 120 50)
+  </b>
+<test>  <op name="intersects" arg1="A" arg2="B"> true  </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B"> false </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B"> false </op> </test>
+</case>
+
+<case>
+  <desc>L on downward diagonal does not intersect</desc>
+  <a>
+    POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))
+  </a>
+  <b>
+    LINESTRING (70 140, 150 50)
+  </b>
+<test>  <op name="intersects" arg1="A" arg2="B"> false </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B"> false </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B"> false </op> </test>
+</case>
+
+<case>
+  <desc>L with many segments crosses</desc>
+  <a>
+    POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))
+  </a>
+  <b>
+    LINESTRING (110 160, 150 70, 110 -20, 130 80, 90 150, 60 -20, 38 128)
+  </b>
+<test>  <op name="intersects" arg1="A" arg2="B"> true  </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B"> false </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B"> false </op> </test>
+</case>
+
+<case>
+  <desc>L with many segments does not intersect</desc>
+  <a>
+    POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))
+  </a>
+  <b>
+    LINESTRING (110 160, 150 70, 110 -20, 130 80, 90 150, 90 110, 38 128)
+  </b>
+<test>  <op name="intersects" arg1="A" arg2="B"> false </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B"> false </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B"> false </op> </test>
 </case>
 
 <case>
@@ -87,8 +152,8 @@
   <b>
     LINESTRING( 10 10, -10 -20 )
   </b>
-<test>  <op name="intersects" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="covers" arg1="A" arg2="B">   false   </op> </test>
+<test>  <op name="intersects" arg1="A" arg2="B"> true  </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B"> false </op> </test>
 </case>
 
 <case>
@@ -100,9 +165,9 @@
     LINESTRING( 10 0, 90 0 )
   </b>
 <test>  <op name="intersects" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="contains" arg1="A" arg2="B">   false   </op> </test>
-<test>  <op name="covers" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="coveredBy" arg1="B" arg2="A">   true   </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B">   false  </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B">   true   </op> </test>
+<test>  <op name="coveredBy"  arg1="B" arg2="A">   true   </op> </test>
 </case>
 
 <case>
@@ -114,9 +179,9 @@
     LINESTRING( 10 0, 100 0, 100 50 )
   </b>
 <test>  <op name="intersects" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="contains" arg1="A" arg2="B">   false   </op> </test>
-<test>  <op name="covers" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="coveredBy" arg1="B" arg2="A">   true   </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B">   false  </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B">   true   </op> </test>
+<test>  <op name="coveredBy"  arg1="B" arg2="A">   true   </op> </test>
 </case>
 
 <case>
@@ -128,9 +193,9 @@
     LINESTRING( 10 0, 100 0, 100 100, 50 100 )
   </b>
 <test>  <op name="intersects" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="contains" arg1="A" arg2="B">   false   </op> </test>
-<test>  <op name="covers" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="coveredBy" arg1="B" arg2="A">   true   </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B">   false  </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B">   true   </op> </test>
+<test>  <op name="coveredBy"  arg1="B" arg2="A">   true   </op> </test>
 </case>
 
 <case>
@@ -142,9 +207,9 @@
     MULTILINESTRING( (10 0, 20 0), (10 10, 20 20) )
   </b>
 <test>  <op name="intersects" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="contains" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="covers" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="coveredBy" arg1="B" arg2="A">   true   </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B">   true   </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B">   true   </op> </test>
+<test>  <op name="coveredBy"  arg1="B" arg2="A">   true   </op> </test>
 </case>
 
 <case>
@@ -156,7 +221,7 @@
     MULTILINESTRING( (10 10, 10 20), (200 10, 200 20) )
   </b>
 <test>  <op name="intersects" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="contains" arg1="A" arg2="B">   false   </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B">   false   </op> </test>
 </case>
 
 <case>
@@ -168,9 +233,9 @@
     POINT(100 50) 
   </b>
 <test>  <op name="intersects" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="contains" arg1="A" arg2="B">   false   </op> </test>
-<test>  <op name="covers" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="coveredBy" arg1="B" arg2="A">   true   </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B">   false  </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B">   true   </op> </test>
+<test>  <op name="coveredBy"  arg1="B" arg2="A">   true   </op> </test>
 </case>
 
 <case>
@@ -182,9 +247,9 @@
     POINT(50 100) 
   </b>
 <test>  <op name="intersects" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="contains" arg1="A" arg2="B">   false   </op> </test>
-<test>  <op name="covers" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="coveredBy" arg1="B" arg2="A">   true   </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B">   false  </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B">   true   </op> </test>
+<test>  <op name="coveredBy"  arg1="B" arg2="A">   true   </op> </test>
 </case>
 
 <case>
@@ -196,9 +261,9 @@
     POINT(60 60) 
   </b>
 <test>  <op name="intersects" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="contains" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="covers" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="coveredBy" arg1="B" arg2="A">   true   </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B">   true   </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B">   true   </op> </test>
+<test>  <op name="coveredBy"  arg1="B" arg2="A">   true   </op> </test>
 </case>
 
 <case>
@@ -210,9 +275,9 @@
     MULTIPOINT((50 100), (60 60)) 
   </b>
 <test>  <op name="intersects" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="contains" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="covers" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="coveredBy" arg1="B" arg2="A">   true   </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B">   true   </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B">   true   </op> </test>
+<test>  <op name="coveredBy"  arg1="B" arg2="A">   true   </op> </test>
 </case>
 
 <case>
@@ -228,9 +293,9 @@
   )
   </b>
 <test>  <op name="intersects" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="contains" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="covers" arg1="A" arg2="B">   true   </op> </test>
-<test>  <op name="coveredBy" arg1="B" arg2="A">   true   </op> </test>
+<test>  <op name="contains"   arg1="A" arg2="B">   true   </op> </test>
+<test>  <op name="covers"     arg1="A" arg2="B">   true   </op> </test>
+<test>  <op name="coveredBy"  arg1="B" arg2="A">   true   </op> </test>
 </case>
 
 
diff --git a/testxml/general/TestSimple.xml b/testxml/general/TestSimple.xml
index 059ebcc..42cf67a 100644
--- a/testxml/general/TestSimple.xml
+++ b/testxml/general/TestSimple.xml
@@ -242,9 +242,9 @@
 </case>
 
 <case>
-  <desc>A</desc>
+  <desc>LR - valid ring</desc>
   <a>
-    POLYGON ((180 260, 80 300, 40 180, 160 120, 180 260))
+    LINEARRING (100 300, 200 300, 200 200, 100 200, 100 300)
   </a>
 <test>
   <op name="isSimple" arg1="A">
@@ -254,28 +254,57 @@
 </case>
 
 <case>
-  <desc>A - empty</desc>
+  <desc>LR - ring with self-intersection</desc>
   <a>
-    POLYGON EMPTY
+    LINEARRING (100 300, 200 300, 100 200, 200 200, 100 300)
   </a>
 <test>
   <op name="isSimple" arg1="A">
-    true
+    false
   </op>
 </test>
 </case>
 
 <case>
-  <desc>mA</desc>
+  <desc>A - valid polygon</desc>
+  <a>
+    POLYGON ((180 260, 80 300, 40 180, 160 120, 180 260))
+  </a>
+<test>
+  <op name="isSimple" arg1="A"> true </op>
+</test>
+</case>
+
+<case>
+  <desc>A - invalid bowtie polygon</desc>
+  <a>
+    POLYGON ((100 100, 100 200, 200 100, 200 200, 100 100))
+  </a>
+<test>
+  <op name="isSimple" arg1="A"> false </op>
+</test>
+</case>
+
+
+<case>
+  <desc>A - empty</desc>
+  <a>
+    POLYGON EMPTY
+  </a>
+<test>
+  <op name="isSimple" arg1="A"> true </op>
+</test>
+</case>
+
+<case>
+  <desc>mA - valid polygon</desc>
   <a>
     MULTIPOLYGON (((240 160, 140 220, 80 60, 220 40, 240 160)), 
   ((160 380, 100 240, 20 380, 160 380), 
     (120 340, 60 360, 80 320, 120 340)))
   </a>
 <test>
-  <op name="isSimple" arg1="A">
-    true
-  </op>
+  <op name="isSimple" arg1="A"> true </op>
 </test>
 </case>
 
@@ -287,9 +316,41 @@
     (120 340, 60 360, 80 320, 120 340)))
   </a>
 <test>
-  <op name="isSimple" arg1="A">
-    true
-  </op>
+  <op name="isSimple" arg1="A"> true </op>
+</test>
+</case>
+
+<case>
+  <desc>mA - with an invalid bowtie element</desc>
+  <a>
+MULTIPOLYGON (((100 100, 100 200, 200 100, 200 200, 100 100)), ((100 400, 200 400, 200 300, 100 300, 100 400)))
+</a>
+<test>
+  <op name="isSimple" arg1="A"> false </op>
+</test>
+</case>
+
+<case>
+  <desc>GC - all components simple</desc>
+  <a>
+GEOMETRYCOLLECTION (POLYGON ((100 200, 200 200, 200 100, 100 100, 100 200)), 
+  LINESTRING (100 300, 200 250), 
+  POINT (250 250), 
+  POINT (250 150))</a>
+<test>
+  <op name="isSimple" arg1="A"> true </op>
+</test>
+</case>
+
+<case>
+  <desc>GC - one non-simple component</desc>
+  <a>
+GEOMETRYCOLLECTION (POLYGON ((100 100, 100 200, 200 100, 200 200, 100 100)), 
+  LINESTRING (100 300, 200 250), 
+  POINT (250 250), 
+  POINT (250 150))</a>
+<test>
+  <op name="isSimple" arg1="A"> false </op>
 </test>
 </case>
 
diff --git a/testxml/general/TestUnaryUnion.xml b/testxml/general/TestUnaryUnion.xml
index f7c67f3..57344a4 100644
--- a/testxml/general/TestUnaryUnion.xml
+++ b/testxml/general/TestUnaryUnion.xml
@@ -27,6 +27,18 @@
 </case>
 
 <case>
+  <desc>L - LineString (showing noding)</desc>
+  <a>
+    LINESTRING (0 0, 10 0, 5 -5, 5 5)
+  </a>
+<test>
+  <op name="union" arg1="A">
+    MULTILINESTRING ((0 0, 5 0), (5 0, 10 0, 5 -5, 5 0), (5 0, 5 5))
+  </op>
+</test>
+</case>
+
+<case>
   <desc>mL - multiLineString (showing noding)</desc>
   <a>
     MULTILINESTRING((0 0, 10 10), (0 10, 10 0))
@@ -139,8 +151,7 @@
   </a>
   <test>
     <op name="union" arg1="A">
-    	GEOMETRYCOLLECTION (LINESTRING (0 0, 20 0), 
-  POLYGON ((150 0, 20 0, 20 100, 180 100, 180 0, 150 0)))
+  POLYGON ((150 0, 20 0, 20 100, 180 100, 180 0, 150 0))
     </op>
   </test>
 </case>
diff --git a/testxml/general/TestUnaryUnionFloating.xml b/testxml/general/TestUnaryUnionFloating.xml
new file mode 100644
index 0000000..3a30c80
--- /dev/null
+++ b/testxml/general/TestUnaryUnionFloating.xml
@@ -0,0 +1,20 @@
+<run>
+  <desc>Tests for Geometry.union() method (unary union) with floating precision</desc>
+
+<case>
+  <desc>mP - showing that non-polygonal components are discarded correctly</desc>
+  <a>
+  GEOMETRYCOLLECTION (
+    POLYGON ((-3 -2, 700 900, -6 900, -3 -2)),
+    POLYGON((700 900, -1.6859349853697 899.55, 0.3 -0.4, 700 900)),
+    POLYGON ((700 860, 700 899.5, -1.68593498537 899.55, 700 860))
+    )
+  </a>
+<test>
+  <op name="union" arg1="A">
+    POLYGON ((0.2942036115049298 2.226702215615205, -3 -2, -6 900, 700 900, 699.6114719806972 899.5000276853219, 700 899.5, 700 860, 670.2204017222961 861.6785046602191, 0.3 -0.4, 0.2942036115049298 2.226702215615205))
+  </op>
+</test>
+</case>
+
+</run>
diff --git a/testxml/robust/ExternalRobustness.xml b/testxml/robust/ExternalRobustness.xml
index b2d6a11..48dc24b 100644
--- a/testxml/robust/ExternalRobustness.xml
+++ b/testxml/robust/ExternalRobustness.xml
@@ -1,4 +1,8 @@
 <run>
+  <desc>
+    Examples of robustness issues from other JTS implementations (mostly GEOS).
+    Some of these execute correctly in JTS.
+  </desc>
   <!-- first occurrence is used -->
   <precisionModel type="FLOATING"/>
   <precisionModel type="FLOATING_SINGLE"/>
@@ -15,7 +19,9 @@
 </b>
 
 <test>
-   <op name="intersection" arg1="A" arg2="B"> GEOMETRYCOLLECTION EMPTY </op>
+   <op name="intersection" arg1="A" arg2="B"> 
+   POLYGON ((129969.21392215387 708504.5707147988, 129933.95535086046 704464.3386246831, 129828.19037708259 700425.3372284006, 129651.95121785585 696388.7968449033, 129405.2915573354 692355.9470434946, 129088.28653044328 688328.0162692912, 128701.03269998157 684306.2314690261, 128243.64802721844 680291.8177173095, 127716.27183595598 676285.9978434584, 127119.06477009084 672289.9920590118, 126452.20874468057 668305.0175860417, 125715.90689053046 664332.2882863756, 124910.383492318 660373. [...]
+   </op>
 </test>
 
 </case>
@@ -44,7 +50,7 @@ POLYGON((742601.541294537 5087772.18101068,742592.428792606
 </b>
 
 <test>
-<op name="intersection" arg1="A" arg2="B"> GEOMETRYCOLLECTION EMPTY </op>
+<op name="intersection" arg1="A" arg2="B"> MULTIPOLYGON (((742591.4178018438 5087769.04526206, 742591.417801844 5087769.04526206, 742592.428792606 5087767.35034731, 742591.4178018438 5087769.04526206)), ((742592.428792606 5087767.35034731, 742601.541294342 5087772.18101105, 742601.5412945366 5087772.18101068, 742592.428792606 5087767.35034731))) </op>
 </test>
 
 </case>
@@ -61,7 +67,9 @@ POLYGON ((607216.0000000019790605 2370623.9999982002191246, 608128.0000000019790
 </b>
 
 <test>
-<op name="intersection" arg1="A" arg2="B"> GEOMETRYCOLLECTION EMPTY </op>
+<op name="intersection" arg1="A" arg2="B"> 
+POLYGON ((609151.0000000028 2368684.9999981993, 608919.0000000028 2368811.9999982, 608801.0000000027 2369192.9999982, 608801.000000003 2369192.9999982, 608919.000000003 2368811.9999982, 609151.000000003 2368684.9999982, 609151.0000000028 2368684.9999981993))
+</op>
 </test>
 
 </case>
@@ -78,7 +86,9 @@ POLYGON ((607216.0000000019790605 2370623.9999982002191246, 608128.0000000019790
 </b>
 
 <test>
-<op name="intersection" arg1="A" arg2="B"> GEOMETRYCOLLECTION EMPTY </op>
+<op name="intersection" arg1="A" arg2="B"> 
+MULTIPOLYGON (((434608.9999999999 2012571.9999999907, 434608.99999999977 2012571.9999999907, 434505.9999999997 2013031.9999999907, 434889.4374999999 2013081.8073453507, 434506 2013031.99999999, 434608.9999999999 2012571.9999999907)), ((434990.9999999999 2013094.99999999, 435264.9999999997 2013496.9999999898, 435311.2499999999 2013535.9783236892, 435265 2013496.99999999, 434991 2013094.99999999, 434990.9999999999 2013094.99999999)), ((436813.9999999997 2014014.99999999, 436802.9999999997  [...]
+</op>
 </test>
 
 </case>
diff --git a/testxml/robust/TestRobustBuffer.xml b/testxml/robust/TestRobustBuffer.xml
new file mode 100644
index 0000000..b98866b
--- /dev/null
+++ b/testxml/robust/TestRobustBuffer.xml
@@ -0,0 +1,20 @@
+<run>
+  <desc>
+    Buffer test cases which stres the JTS robust buffer algorithms
+  </desc>
+  <precisionModel type="FLOATING" />
+  <resultMatcher>com.vividsolutions.jtstest.testrunner.BufferResultMatcher</resultMatcher>
+
+<case>
+  <desc>GEOS #605 - smallest case.  Works in JTS, but triggers fixed-precision fallback.</desc>
+  <a>
+    LINESTRING (365851.1186 6133776.04159, 366074.9243 6134077.56523, 375141.3101 6138794.83236, 373718.87248 6137668.4963, 373346.64754 6137433.71166638, 366752.527 6134568.1015, 360775.41757 6127074.35479, 360762.97098 6127054.06482, 365851.11862 6133776.04159, 366074.92434 6134077.56523, 366360.99154 6134339.22803, 366752.52702 6134568.1015, 373346.64754 6137433.71166638, 373718.87248 6137668.4963, 375295.49858 6138886.9262, 373718.87248 6137668.4963, 373346.64754 6137433.71166, 36682 [...]
+  </a>
+<test>
+  <op name="buffer" arg1="A" arg2="1000.0">
+    POLYGON ((355917.67656 6124381.22758, 355939.27747 6124576.05034, 355998.46805 6124762.91656, 356092.97404 6124934.64636, 356219.16428 6125084.64146, 356372.19022 6125207.13868, 359638.80782 6127332.78479, 360038.85848 6127754.60444, 360042.83714 6127759.59265, 365050.94349 6134375.82647, 365271.94686 6134673.57465, 365271.94782 6134673.57567, 365399.99268 6134815.44547, 365686.05988 6135077.10827, 365731.38144 6135110.49622, 365766.07316 6135142.63065, 365855.41384 6135201.86967, 36 [...]
+  </op>
+</test>
+</case>
+
+</run>
diff --git a/testxml/validate/TestRelateAA.xml b/testxml/validate/TestRelateAA.xml
index 82c5999..2ee46cc 100644
--- a/testxml/validate/TestRelateAA.xml
+++ b/testxml/validate/TestRelateAA.xml
@@ -14,6 +14,16 @@
   <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>
@@ -29,6 +39,16 @@
   <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>
@@ -44,6 +64,16 @@
   <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>
@@ -59,6 +89,16 @@
   <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>
@@ -74,6 +114,16 @@
   <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>
@@ -89,6 +139,16 @@
   <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>
@@ -104,6 +164,16 @@
   <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>
@@ -119,6 +189,16 @@
   <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>
@@ -134,6 +214,16 @@
   <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>
@@ -149,6 +239,16 @@
   <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>
@@ -164,6 +264,16 @@
   <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>
@@ -179,6 +289,16 @@
   <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>
@@ -194,6 +314,16 @@
   <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>
@@ -209,6 +339,16 @@
   <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>
@@ -225,6 +365,16 @@
   <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>
@@ -241,6 +391,16 @@
   <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>
@@ -256,6 +416,16 @@
   <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>
@@ -271,6 +441,16 @@
   <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>
@@ -286,6 +466,16 @@
   <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>
@@ -301,6 +491,16 @@
   <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>
@@ -316,6 +516,16 @@
   <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>
@@ -331,6 +541,16 @@
   <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>
@@ -346,6 +566,16 @@
   <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>
@@ -361,6 +591,16 @@
   <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>
@@ -376,6 +616,16 @@
   <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>
@@ -391,6 +641,16 @@
   <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>
@@ -406,6 +666,16 @@
   <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>
@@ -421,6 +691,16 @@
   <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>
@@ -436,6 +716,16 @@
   <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>
@@ -451,6 +741,16 @@
   <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>
@@ -466,6 +766,16 @@
   <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>
@@ -481,6 +791,16 @@
   <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>
@@ -496,6 +816,16 @@
   <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>
@@ -511,6 +841,16 @@
   <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>
@@ -526,6 +866,16 @@
   <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>
@@ -541,6 +891,16 @@
   <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>
@@ -556,6 +916,16 @@
   <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>
@@ -571,6 +941,16 @@
   <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>
@@ -586,6 +966,16 @@
   <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>
@@ -601,6 +991,16 @@
   <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>
@@ -616,6 +1016,16 @@
   <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>
@@ -631,6 +1041,16 @@
   <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>
@@ -646,6 +1066,16 @@
   <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>
@@ -661,6 +1091,16 @@
   <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>
@@ -676,6 +1116,16 @@
   <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>
@@ -691,6 +1141,16 @@
   <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>
@@ -706,6 +1166,16 @@
   <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>
@@ -721,6 +1191,16 @@
   <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>
@@ -736,6 +1216,16 @@
   <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>
@@ -751,6 +1241,16 @@
   <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>
@@ -766,6 +1266,16 @@
   <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>
@@ -781,6 +1291,16 @@
   <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>
@@ -796,6 +1316,16 @@
   <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>
@@ -832,6 +1362,16 @@
   <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>
@@ -874,6 +1414,16 @@
   <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>
@@ -889,6 +1439,16 @@
   <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>
@@ -904,6 +1464,16 @@
   <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>
@@ -919,6 +1489,16 @@
   <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>
@@ -934,6 +1514,16 @@
   <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>
@@ -949,6 +1539,16 @@
   <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>
@@ -964,6 +1564,16 @@
   <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>
@@ -979,6 +1589,16 @@
   <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>
@@ -994,6 +1614,16 @@
   <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>
@@ -1009,6 +1639,16 @@
   <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>
@@ -1024,6 +1664,16 @@
   <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>
@@ -1039,6 +1689,16 @@
   <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>
@@ -1054,6 +1714,16 @@
   <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>
@@ -1069,6 +1739,16 @@
   <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>
@@ -1084,6 +1764,16 @@
   <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>
@@ -1099,6 +1789,16 @@
   <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>
@@ -1114,6 +1814,16 @@
   <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>
@@ -1129,6 +1839,16 @@
   <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>
@@ -1144,6 +1864,16 @@
   <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>
@@ -1159,6 +1889,16 @@
   <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>
@@ -1174,6 +1914,16 @@
   <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>
@@ -1189,6 +1939,16 @@
   <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>
@@ -1205,6 +1965,16 @@
   <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>
@@ -1221,6 +1991,16 @@
   <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>
@@ -1237,6 +2017,16 @@
   <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>
@@ -1253,6 +2043,16 @@
   <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>
@@ -1269,6 +2069,16 @@
   <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>
@@ -1285,6 +2095,16 @@
   <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>
@@ -1301,6 +2121,16 @@
   <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>
@@ -1317,6 +2147,16 @@
   <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>
@@ -1333,6 +2173,16 @@
   <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>
@@ -1349,6 +2199,16 @@
   <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>
@@ -1365,6 +2225,16 @@
   <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>
@@ -1381,6 +2251,16 @@
   <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>
@@ -1398,6 +2278,16 @@
   <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>
@@ -1414,6 +2304,16 @@
   <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>
@@ -1430,6 +2330,16 @@
   <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>
@@ -1446,6 +2356,16 @@
   <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>
@@ -1463,6 +2383,16 @@
   <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>
@@ -1482,6 +2412,16 @@
   <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>
@@ -1500,6 +2440,16 @@
   <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>
@@ -1518,6 +2468,16 @@
   <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>
@@ -1536,6 +2496,16 @@
   <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>
@@ -1554,6 +2524,16 @@
   <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>
@@ -1572,6 +2552,16 @@
   <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>
@@ -1590,6 +2580,16 @@
   <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>
@@ -1612,6 +2612,16 @@
   <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>
@@ -1633,6 +2643,16 @@
   <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>
@@ -1658,6 +2678,16 @@
   <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>
@@ -1683,6 +2713,16 @@
   <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>
@@ -1708,6 +2748,16 @@
   <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>
@@ -1733,6 +2783,16 @@
   <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>
@@ -1758,6 +2818,16 @@
   <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/testxml/validate/TestRelateAC.xml b/testxml/validate/TestRelateAC.xml
index 4bbafcb..8d481fd 100644
--- a/testxml/validate/TestRelateAC.xml
+++ b/testxml/validate/TestRelateAC.xml
@@ -21,6 +21,16 @@
   <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/testxml/validate/TestRelateLA.xml b/testxml/validate/TestRelateLA.xml
index ca1e2b1..7bbc50a 100644
--- a/testxml/validate/TestRelateLA.xml
+++ b/testxml/validate/TestRelateLA.xml
@@ -13,6 +13,16 @@
   <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>
@@ -27,6 +37,16 @@
   <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>
@@ -41,6 +61,16 @@
   <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>
@@ -55,6 +85,16 @@
   <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>
@@ -69,6 +109,16 @@
   <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>
@@ -83,6 +133,16 @@
   <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>
@@ -97,6 +157,16 @@
   <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>
@@ -111,6 +181,16 @@
   <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>
@@ -125,6 +205,16 @@
   <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>
@@ -139,6 +229,16 @@
   <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>
@@ -153,6 +253,16 @@
   <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>
@@ -167,6 +277,16 @@
   <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>
@@ -181,6 +301,16 @@
   <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>
@@ -195,6 +325,16 @@
   <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>
@@ -209,6 +349,16 @@
   <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>
@@ -223,6 +373,16 @@
   <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>
@@ -237,6 +397,16 @@
   <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>
@@ -251,6 +421,16 @@
   <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>
@@ -265,6 +445,16 @@
   <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>
@@ -280,6 +470,16 @@
   <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>
@@ -295,6 +495,16 @@
   <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>
@@ -310,6 +520,16 @@
   <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>
@@ -325,6 +545,16 @@
   <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>
@@ -340,6 +570,16 @@
   <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>
@@ -355,6 +595,16 @@
   <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>
@@ -370,6 +620,16 @@
   <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>
@@ -385,6 +645,16 @@
   <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>
@@ -400,6 +670,16 @@
   <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>
@@ -415,6 +695,16 @@
   <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>
@@ -430,6 +720,16 @@
   <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>
@@ -445,6 +745,16 @@
   <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>
@@ -461,6 +771,16 @@
   <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>
@@ -477,6 +797,16 @@
   <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>
@@ -493,6 +823,16 @@
   <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>
@@ -509,6 +849,16 @@
   <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>
@@ -525,6 +875,16 @@
   <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>
@@ -541,6 +901,16 @@
   <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>
@@ -557,6 +927,16 @@
   <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>
@@ -573,6 +953,16 @@
   <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>
@@ -590,6 +980,16 @@
   <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>
@@ -607,6 +1007,16 @@
   <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>
@@ -624,6 +1034,16 @@
   <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>
@@ -638,6 +1058,16 @@
   <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>
@@ -652,6 +1082,16 @@
   <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>
@@ -667,6 +1107,16 @@
   <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>
@@ -681,6 +1131,16 @@
   <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>
@@ -696,6 +1156,16 @@
   <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>
@@ -711,6 +1181,16 @@
   <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>
@@ -726,6 +1206,16 @@
   <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>
@@ -740,6 +1230,16 @@
   <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>
@@ -755,6 +1255,16 @@
   <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>
@@ -769,6 +1279,16 @@
   <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>
@@ -784,6 +1304,16 @@
   <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>
@@ -799,6 +1329,16 @@
   <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>
@@ -814,6 +1354,16 @@
   <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>
@@ -829,6 +1379,16 @@
   <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>
@@ -843,6 +1403,16 @@
   <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>
@@ -857,6 +1427,16 @@
   <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>
@@ -871,6 +1451,16 @@
   <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>
@@ -885,6 +1475,16 @@
   <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>
@@ -899,6 +1499,16 @@
   <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>
@@ -913,6 +1523,16 @@
   <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>
@@ -927,6 +1547,16 @@
   <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>
@@ -941,6 +1571,16 @@
   <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>
@@ -956,6 +1596,16 @@
   <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>
@@ -972,6 +1622,16 @@
   <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>
@@ -988,6 +1648,16 @@
   <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>
@@ -1004,6 +1674,16 @@
   <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>
@@ -1020,6 +1700,16 @@
   <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>
@@ -1036,6 +1726,16 @@
   <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>
@@ -1052,6 +1752,16 @@
   <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>
@@ -1068,6 +1778,16 @@
   <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>
@@ -1084,6 +1804,16 @@
   <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>
@@ -1100,6 +1830,16 @@
   <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>
@@ -1119,6 +1859,16 @@
   <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>
@@ -1138,6 +1888,16 @@
   <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>
@@ -1157,6 +1917,16 @@
   <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/testxml/validate/TestRelateLC.xml b/testxml/validate/TestRelateLC.xml
index 73f3d5d..b5119d8 100644
--- a/testxml/validate/TestRelateLC.xml
+++ b/testxml/validate/TestRelateLC.xml
@@ -16,6 +16,16 @@
   <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>
@@ -32,6 +42,16 @@
   <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/testxml/validate/TestRelateLL.xml b/testxml/validate/TestRelateLL.xml
index 6d10521..35b5c03 100644
--- a/testxml/validate/TestRelateLL.xml
+++ b/testxml/validate/TestRelateLL.xml
@@ -12,6 +12,16 @@
   <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>
@@ -25,6 +35,16 @@
   <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>
@@ -38,6 +58,16 @@
   <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>
@@ -51,6 +81,16 @@
   <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>
@@ -64,6 +104,16 @@
   <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>
@@ -77,6 +127,16 @@
   <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>
@@ -90,6 +150,16 @@
   <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>
@@ -103,6 +173,16 @@
   <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>
@@ -116,6 +196,16 @@
   <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>
@@ -129,6 +219,16 @@
   <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>
@@ -142,6 +242,16 @@
   <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>
@@ -155,6 +265,16 @@
   <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>
@@ -168,6 +288,16 @@
   <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>
@@ -181,6 +311,16 @@
   <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>
@@ -194,6 +334,16 @@
   <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>
@@ -207,6 +357,16 @@
   <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>
@@ -220,6 +380,16 @@
   <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>
@@ -233,6 +403,16 @@
   <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>
@@ -246,6 +426,16 @@
   <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>
@@ -259,6 +449,16 @@
   <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>
@@ -272,6 +472,16 @@
   <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>
@@ -285,6 +495,16 @@
   <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>
@@ -298,6 +518,16 @@
   <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>
@@ -311,6 +541,16 @@
   <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>
@@ -324,6 +564,16 @@
   <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>
@@ -337,6 +587,16 @@
   <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>
@@ -350,6 +610,16 @@
   <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>
@@ -363,6 +633,16 @@
   <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>
@@ -376,6 +656,16 @@
   <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>
@@ -389,6 +679,16 @@
   <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>
@@ -402,6 +702,16 @@
   <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>
@@ -415,6 +725,16 @@
   <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>
@@ -428,6 +748,16 @@
   <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>
@@ -441,6 +771,16 @@
   <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>
@@ -454,6 +794,16 @@
   <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>
@@ -467,6 +817,16 @@
   <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>
@@ -480,6 +840,16 @@
   <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>
@@ -493,6 +863,16 @@
   <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>
@@ -506,6 +886,16 @@
   <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>
@@ -519,6 +909,16 @@
   <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>
@@ -532,6 +932,16 @@
   <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>
@@ -545,6 +955,16 @@
   <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>
@@ -558,6 +978,16 @@
   <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>
@@ -571,6 +1001,16 @@
   <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>
@@ -584,6 +1024,16 @@
   <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>
@@ -597,6 +1047,16 @@
   <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>
@@ -611,6 +1071,16 @@
   <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>
@@ -632,6 +1102,16 @@
   <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>
@@ -645,6 +1125,16 @@
   <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>
@@ -658,6 +1148,16 @@
   <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>
@@ -671,6 +1171,16 @@
   <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>
@@ -684,6 +1194,16 @@
   <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>
@@ -697,6 +1217,16 @@
   <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>
@@ -710,6 +1240,16 @@
   <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>
@@ -723,6 +1263,16 @@
   <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>
@@ -736,6 +1286,16 @@
   <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>
@@ -749,6 +1309,16 @@
   <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>
@@ -762,6 +1332,16 @@
   <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>
@@ -775,6 +1355,16 @@
   <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>
@@ -788,6 +1378,16 @@
   <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>
@@ -801,6 +1401,16 @@
   <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>
@@ -814,6 +1424,16 @@
   <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>
@@ -827,6 +1447,16 @@
   <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>
@@ -840,6 +1470,16 @@
   <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>
@@ -853,6 +1493,16 @@
   <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>
@@ -866,6 +1516,16 @@
   <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>
@@ -879,6 +1539,16 @@
   <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>
@@ -892,6 +1562,16 @@
   <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>
@@ -905,6 +1585,16 @@
   <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>
@@ -919,6 +1609,16 @@
   <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>
@@ -932,6 +1632,16 @@
   <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>
@@ -945,6 +1655,16 @@
   <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>
@@ -958,6 +1678,16 @@
   <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>
@@ -971,6 +1701,16 @@
   <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>
@@ -984,6 +1724,16 @@
   <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>
@@ -997,6 +1747,16 @@
   <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>
@@ -1010,6 +1770,16 @@
   <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>
@@ -1023,6 +1793,16 @@
   <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>
@@ -1036,6 +1816,16 @@
   <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>
@@ -1049,6 +1839,16 @@
   <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>
@@ -1062,6 +1862,16 @@
   <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>
@@ -1075,6 +1885,16 @@
   <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>
@@ -1088,6 +1908,16 @@
   <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>
@@ -1101,6 +1931,16 @@
   <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>
@@ -1114,6 +1954,16 @@
   <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>
@@ -1127,6 +1977,16 @@
   <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>
@@ -1140,6 +2000,16 @@
   <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>
@@ -1153,6 +2023,16 @@
   <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>
@@ -1166,6 +2046,16 @@
   <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>
@@ -1179,6 +2069,16 @@
   <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>
@@ -1192,6 +2092,16 @@
   <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>
@@ -1205,6 +2115,16 @@
   <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>
@@ -1218,6 +2138,16 @@
   <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>
@@ -1231,6 +2161,16 @@
   <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>
@@ -1244,6 +2184,16 @@
   <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>
@@ -1257,6 +2207,16 @@
   <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>
@@ -1270,6 +2230,16 @@
   <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>
@@ -1283,6 +2253,16 @@
   <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>
@@ -1296,6 +2276,16 @@
   <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>
@@ -1309,6 +2299,16 @@
   <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>
@@ -1322,6 +2322,16 @@
   <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>
@@ -1335,6 +2345,16 @@
   <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>
@@ -1348,6 +2368,16 @@
   <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>
@@ -1361,6 +2391,16 @@
   <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>
@@ -1374,6 +2414,16 @@
   <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>
@@ -1389,6 +2439,16 @@
   <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>
@@ -1402,6 +2462,16 @@
   <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>
@@ -1415,6 +2485,16 @@
   <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>
@@ -1428,6 +2508,16 @@
   <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>
@@ -1441,6 +2531,16 @@
   <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>
@@ -1454,6 +2554,16 @@
   <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>
@@ -1467,6 +2577,16 @@
   <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>
@@ -1480,6 +2600,16 @@
   <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>
@@ -1493,6 +2623,16 @@
   <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>
@@ -1506,6 +2646,16 @@
   <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>
@@ -1519,6 +2669,16 @@
   <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>
@@ -1532,6 +2692,16 @@
   <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>
@@ -1545,6 +2715,16 @@
   <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>
@@ -1558,6 +2738,16 @@
   <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>
@@ -1571,6 +2761,16 @@
   <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>
@@ -1584,6 +2784,16 @@
   <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>
@@ -1597,6 +2807,16 @@
   <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>
@@ -1610,6 +2830,16 @@
   <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>
@@ -1623,6 +2853,16 @@
   <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>
@@ -1636,6 +2876,16 @@
   <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>
@@ -1649,6 +2899,16 @@
   <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>
@@ -1662,6 +2922,16 @@
   <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>
@@ -1675,6 +2945,16 @@
   <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>
@@ -1688,6 +2968,16 @@
   <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>
@@ -1701,6 +2991,16 @@
   <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>
@@ -1718,6 +3018,16 @@
   <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>
@@ -1735,6 +3045,16 @@
   <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>
@@ -1752,6 +3072,16 @@
   <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>
@@ -1770,6 +3100,16 @@
   <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>
@@ -1787,6 +3127,16 @@
   <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>
@@ -1804,6 +3154,16 @@
   <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>
@@ -1822,6 +3182,16 @@
   <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>
@@ -1840,6 +3210,16 @@
   <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>
@@ -1858,6 +3238,16 @@
   <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>
@@ -1875,6 +3265,16 @@
   <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>
@@ -1892,6 +3292,16 @@
   <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>
@@ -1909,6 +3319,16 @@
   <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>
@@ -1926,6 +3346,16 @@
   <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>
@@ -1943,6 +3373,16 @@
   <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>
\ No newline at end of file
+</run>
diff --git a/testxml/validate/TestRelatePA.xml b/testxml/validate/TestRelatePA.xml
index 99482b6..1104099 100644
--- a/testxml/validate/TestRelatePA.xml
+++ b/testxml/validate/TestRelatePA.xml
@@ -13,6 +13,16 @@
   <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>
@@ -27,6 +37,16 @@
   <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>
@@ -41,6 +61,16 @@
   <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>
@@ -55,6 +85,16 @@
   <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>
@@ -69,6 +109,16 @@
   <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>
@@ -83,6 +133,16 @@
   <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>
@@ -97,6 +157,16 @@
   <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>
@@ -111,6 +181,16 @@
   <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>
@@ -125,6 +205,16 @@
   <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>
@@ -140,6 +230,16 @@
   <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>
@@ -155,6 +255,16 @@
   <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>
@@ -170,6 +280,16 @@
   <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>
@@ -185,6 +305,16 @@
   <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>
@@ -200,6 +330,16 @@
   <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>
@@ -215,6 +355,16 @@
   <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>
@@ -230,6 +380,16 @@
   <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>
@@ -245,6 +405,16 @@
   <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>
@@ -260,6 +430,16 @@
   <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>
@@ -276,6 +456,16 @@
   <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>
@@ -292,6 +482,16 @@
   <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>
@@ -306,6 +506,16 @@
   <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>
@@ -320,6 +530,16 @@
   <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>
@@ -334,6 +554,16 @@
   <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>
@@ -348,6 +578,16 @@
   <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>
@@ -362,6 +602,16 @@
   <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>
@@ -376,6 +626,16 @@
   <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>
@@ -390,6 +650,16 @@
   <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>
@@ -404,6 +674,16 @@
   <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>
@@ -418,6 +698,16 @@
   <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>
@@ -432,6 +722,16 @@
   <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>
@@ -446,6 +746,16 @@
   <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>
@@ -460,6 +770,16 @@
   <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>
@@ -474,6 +794,16 @@
   <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>
@@ -488,6 +818,16 @@
   <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>
@@ -503,6 +843,16 @@
   <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>
@@ -518,6 +868,16 @@
   <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>
@@ -533,6 +893,16 @@
   <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>
@@ -550,6 +920,16 @@
   <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>
@@ -567,6 +947,16 @@
   <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>
@@ -584,6 +974,16 @@
   <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>
@@ -603,6 +1003,16 @@
   <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>
\ No newline at end of file
+</run>
diff --git a/testxml/validate/TestRelatePL.xml b/testxml/validate/TestRelatePL.xml
index 66dc6ae..5388cfe 100644
--- a/testxml/validate/TestRelatePL.xml
+++ b/testxml/validate/TestRelatePL.xml
@@ -12,6 +12,16 @@
   <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>
@@ -25,6 +35,16 @@
   <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>
@@ -38,6 +58,16 @@
   <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>
@@ -51,6 +81,16 @@
   <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>
@@ -64,6 +104,16 @@
   <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>
@@ -77,6 +127,16 @@
   <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>
@@ -90,6 +150,16 @@
   <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>
@@ -103,6 +173,16 @@
   <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>
@@ -116,6 +196,16 @@
   <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>
@@ -129,6 +219,16 @@
   <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>
@@ -142,6 +242,16 @@
   <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>
@@ -155,6 +265,16 @@
   <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>
@@ -168,6 +288,16 @@
   <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>
@@ -181,6 +311,16 @@
   <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>
@@ -194,6 +334,16 @@
   <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>
@@ -207,6 +357,16 @@
   <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>
@@ -220,6 +380,16 @@
   <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>
@@ -233,6 +403,16 @@
   <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>
@@ -246,6 +426,16 @@
   <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>
@@ -259,6 +449,16 @@
   <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>
@@ -272,6 +472,16 @@
   <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>
@@ -285,6 +495,16 @@
   <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>
@@ -298,6 +518,16 @@
   <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>
@@ -311,6 +541,16 @@
   <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>
@@ -324,6 +564,16 @@
   <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>
@@ -337,6 +587,16 @@
   <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>
@@ -350,6 +610,16 @@
   <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>
@@ -364,6 +634,16 @@
   <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>
@@ -377,6 +657,16 @@
   <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>
@@ -390,6 +680,16 @@
   <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>
@@ -403,6 +703,16 @@
   <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>
@@ -416,6 +726,16 @@
   <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>
@@ -429,6 +749,16 @@
   <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>
@@ -442,6 +772,16 @@
   <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>
@@ -455,6 +795,16 @@
   <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>
@@ -468,6 +818,16 @@
   <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>
@@ -481,6 +841,16 @@
   <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>
@@ -494,6 +864,16 @@
   <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>
@@ -507,6 +887,16 @@
   <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>
@@ -520,6 +910,16 @@
   <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>
@@ -533,6 +933,16 @@
   <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>
@@ -546,6 +956,16 @@
   <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>
@@ -559,6 +979,16 @@
   <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>
@@ -572,6 +1002,16 @@
   <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>
@@ -585,6 +1025,16 @@
   <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>
@@ -598,6 +1048,16 @@
   <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>
@@ -611,6 +1071,16 @@
   <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>
@@ -624,6 +1094,16 @@
   <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>
@@ -637,6 +1117,16 @@
   <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>
@@ -650,6 +1140,16 @@
   <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>
@@ -663,6 +1163,16 @@
   <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>
@@ -676,6 +1186,16 @@
   <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>
@@ -689,6 +1209,16 @@
   <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>
@@ -702,6 +1232,16 @@
   <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>
@@ -715,6 +1255,16 @@
   <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>
@@ -728,6 +1278,16 @@
   <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>
@@ -741,6 +1301,16 @@
   <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>
@@ -754,6 +1324,16 @@
   <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>
@@ -767,6 +1347,16 @@
   <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>
@@ -781,6 +1371,16 @@
   <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>
@@ -794,6 +1394,16 @@
   <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>
@@ -808,6 +1418,16 @@
   <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>
@@ -821,6 +1441,16 @@
   <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>
@@ -834,6 +1464,16 @@
   <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>
@@ -847,6 +1487,16 @@
   <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>
@@ -860,6 +1510,16 @@
   <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>
@@ -874,6 +1534,16 @@
   <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>
@@ -887,6 +1557,16 @@
   <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>
@@ -901,6 +1581,16 @@
   <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>
@@ -914,6 +1604,16 @@
   <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>
@@ -927,6 +1627,16 @@
   <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>
@@ -940,6 +1650,16 @@
   <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>
@@ -953,6 +1673,16 @@
   <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>
@@ -966,6 +1696,16 @@
   <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>
@@ -979,6 +1719,16 @@
   <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>
@@ -992,6 +1742,16 @@
   <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>
@@ -1005,6 +1765,16 @@
   <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>
@@ -1018,6 +1788,16 @@
   <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>
@@ -1031,6 +1811,16 @@
   <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>
@@ -1044,6 +1834,16 @@
   <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>
@@ -1057,6 +1857,16 @@
   <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>
@@ -1070,6 +1880,16 @@
   <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>
@@ -1083,6 +1903,16 @@
   <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>
@@ -1096,6 +1926,16 @@
   <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>
@@ -1109,6 +1949,16 @@
   <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>
@@ -1122,6 +1972,16 @@
   <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>
@@ -1135,6 +1995,16 @@
   <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>
@@ -1148,6 +2018,16 @@
   <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>
@@ -1161,6 +2041,16 @@
   <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>
@@ -1174,6 +2064,16 @@
   <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>
@@ -1187,6 +2087,16 @@
   <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>
@@ -1200,6 +2110,16 @@
   <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>
@@ -1213,6 +2133,16 @@
   <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>
@@ -1226,6 +2156,16 @@
   <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>
@@ -1239,6 +2179,16 @@
   <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>
@@ -1252,6 +2202,16 @@
   <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>
@@ -1265,6 +2225,16 @@
   <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>
@@ -1278,6 +2248,16 @@
   <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>
\ No newline at end of file
+</run>
diff --git a/testxml/validate/TestRelatePP.xml b/testxml/validate/TestRelatePP.xml
index 59fb9d3..1fd4050 100644
--- a/testxml/validate/TestRelatePP.xml
+++ b/testxml/validate/TestRelatePP.xml
@@ -12,6 +12,16 @@
   <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>
@@ -25,6 +35,16 @@
   <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>
@@ -38,6 +58,16 @@
   <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>
@@ -51,6 +81,16 @@
   <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>
@@ -64,6 +104,16 @@
   <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>
@@ -77,6 +127,16 @@
   <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>
@@ -90,6 +150,16 @@
   <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>
@@ -103,6 +173,16 @@
   <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>
@@ -116,6 +196,16 @@
   <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>
@@ -129,6 +219,16 @@
   <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>
@@ -142,6 +242,16 @@
   <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>
@@ -155,6 +265,16 @@
   <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>
@@ -168,6 +288,16 @@
   <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>
\ No newline at end of file
+</run>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/jts.git



More information about the Pkg-grass-devel mailing list