private static void CompareSegmentAngles(
            [NotNull] IList <double> sourceAngles,
            [NotNull] IList <double> transformedAngles,
            double maxSegmentAngleDifferenceRadians,
            double ignoredAngleValue,
            [NotNull] IFeature transformedFeature,
            [NotNull] IPointCollection transformedPoints,
            [NotNull] IIssueReporter issueReporter)
        {
            Assert.AreEqual(sourceAngles.Count, transformedAngles.Count,
                            "Differing number of segment angles. Source: {0} Transformed: {1}",
                            sourceAngles.Count, transformedAngles.Count);

            var ignoredVertices   = new List <int>();
            var isClosedEvaluator = new IsClosedEvaluator(transformedPoints);

            int lastVertexIndex = sourceAngles.Count - 1;

            for (var vertexIndex = 0; vertexIndex <= lastVertexIndex; vertexIndex++)
            {
                double sourceAngle      = sourceAngles[vertexIndex];
                double transformedAngle = transformedAngles[vertexIndex];

                if (Math.Abs(sourceAngle - ignoredAngleValue) < double.Epsilon)
                {
                    ignoredVertices.Add(vertexIndex);
                    continue;
                }

                double difference = Math.Abs(sourceAngle - transformedAngle);

                if (difference > maxSegmentAngleDifferenceRadians)
                {
                    // ignore the angle difference if this is the last vertex, and its angle is
                    // equal to the first vertex, and the points form a closed loop
                    bool ignoreDifference =
                        vertexIndex == lastVertexIndex &&
                        Math.Abs(transformedAngle - transformedAngles[0]) < double.Epsilon &&
                        isClosedEvaluator.IsClosed;

                    if (!ignoreDifference)
                    {
                        IGeometry errorGeometry = GetErrorGeometry(
                            vertexIndex, ignoredVertices, transformedPoints,
                            isClosedEvaluator, sourceAngles, ignoredAngleValue);

                        string description = string.Format(
                            "Segment angle difference exceeds limit: {0}°",
                            MathUtils.ToDegrees(difference));

                        issueReporter.Report(transformedFeature, errorGeometry, description);
                    }
                }

                if (ignoredVertices.Count > 0)
                {
                    ignoredVertices.Clear();
                }
            }
        }
        private static IGeometry GetErrorGeometry(
            int vertexIndex,
            [NotNull] ICollection <int> ignoredVertices,
            [NotNull] IPointCollection transformedPoints,
            [NotNull] IsClosedEvaluator isClosedEvaluator,
            IList <double> sourceAngles,
            double ignoredAngleValue)
        {
            if (ignoredVertices.Count <= 0)
            {
                return(transformedPoints.Point[vertexIndex]);
            }

            List <IPoint> points = ignoredVertices.Select(
                index => transformedPoints.Point[index])
                                   .ToList();

            if (ignoredVertices.Contains(0) && isClosedEvaluator.IsClosed)
            {
                // the first vertex is ignored, and the path is closed
                // --> check if there are ignored vertices at the end of the path which should be added

                int lastVertexIndexBeforeEndpoint = transformedPoints.PointCount - 2;

                if (Math.Abs(sourceAngles[lastVertexIndexBeforeEndpoint] - ignoredAngleValue) <
                    double.Epsilon)
                {
                    // the vertex before the end vertex is also ignored

                    // --> add the ending sequence of ignored vertices to the list
                    for (int vertexIndexFromEnd = lastVertexIndexBeforeEndpoint;
                         vertexIndexFromEnd >= 0;
                         vertexIndexFromEnd--)
                    {
                        if (Math.Abs(sourceAngles[vertexIndexFromEnd] - ignoredAngleValue) >
                            double.Epsilon)
                        {
                            // the vertex is not ignored --> stop here
                            break;
                        }

                        if (ignoredVertices.Contains(vertexIndexFromEnd))
                        {
                            // the end sequence overlaps the start sequence
                            // --> apparently all vertices are ignored
                            break;
                        }

                        // add the ignored vertex from the end sequence
                        points.Add(transformedPoints.Point[vertexIndexFromEnd]);
                    }
                }
            }

            points.Add(transformedPoints.Point[vertexIndex]);

            return(GeometryFactory.CreateMultipoint(points));
        }