private static List <ConnectedSegmentParts> GetClosedConnected(
            [NotNull] List <ConnectedSegmentParts> curves)
        {
            var connected = new List <ConnectedSegmentParts>(curves.Count);

            ConnectedSegmentParts atStart = null;

            foreach (ConnectedSegmentParts curve in curves)
            {
                if (MathUtils.AreEqual(curve.StartFullIndex, 0))
                {
                    if (atStart != null)
                    {
                        connected.Add(atStart);
                    }

                    atStart = curve;
                    continue;
                }

                if (atStart != null &&
                    atStart.PartIndex == curve.PartIndex &&
                    curve.BaseGeometry.IsPartClosed(curve.PartIndex) &&
                    MathUtils.AreEqual(curve.EndFullIndex,
                                       curve.BaseGeometry.GetPartSegmentCount(curve.PartIndex)))
                {
                    connected.Add(new ConnectedSegmentParts(atStart, curve));
                    atStart = null;
                }
                else
                {
                    connected.Add(curve);
                }
            }

            if (atStart != null)
            {
                connected.Add(atStart);
            }

            return(connected);
        }
        protected static void AddSegment(
            [NotNull] IIndexedSegments geom,
            [NotNull] IList <ConnectedSegmentParts> standardConnectedList,
            [NotNull] IList <ConnectedSegmentParts> nearSelfConnectedList,
            [NotNull] SegmentPart segPart,
            double connectedMinLength,
            double nearSquared, bool is3D)
        {
            ConnectedSegmentParts         current       = null;
            IList <ConnectedSegmentParts> connectedList = standardConnectedList;

            SegmentProxy neighbor = segPart.NearSelf;

            if (neighbor != null)
            {
                #region neighbor != null

                // Get the distance between the parts that are near
                double d0        = double.MaxValue;
                int    partIndex = segPart.PartIndex;

                if (geom.IsPartClosed(partIndex) || segPart.SegmentIndex > neighbor.SegmentIndex)
                {
                    if (segPart.PartIndex == neighbor.PartIndex)
                    // TODO revise; workaround to avoid exception (invalid index)
                    {
                        // raw estimate for distance betwenn segPart and neighborPart
                        // this estimate is too small, because not the entire part of neighbor is near segPart
                        var curve = new SubClosedCurve(geom, partIndex,
                                                       neighbor.SegmentIndex + 1,
                                                       segPart.FullMin);
                        d0 = curve.GetLength();
                        if (d0 < connectedMinLength)
                        {
                            double d0Max = d0 + neighbor.Length;
                            if (d0Max > connectedMinLength)
                            {
                                // closer investigation necessary
                                double min;
                                double max;
                                GetClosePart(neighbor, geom, segPart, nearSquared, is3D,
                                             out min, out max);

                                d0 = d0 + (1 - max) * neighbor.Length;
                            }                     // else segPart is definitly near neighbor
                        }                         //else segPart is definitly not near neighbor
                    }
                }

                if (geom.IsPartClosed(partIndex) || segPart.SegmentIndex < neighbor.SegmentIndex)
                {
                    if (segPart.PartIndex == neighbor.PartIndex)
                    // TODO revise; workaround to avoid exception (invalid index)
                    {
                        var curve = new SubClosedCurve(geom, partIndex,
                                                       segPart.FullMax,
                                                       neighbor.SegmentIndex);

                        double d0Min = curve.GetLength();
                        if (d0Min < connectedMinLength)
                        {
                            double d0Max = d0Min + neighbor.Length;
                            if (d0Max > connectedMinLength)
                            {
                                // closer investigation necessary
                                double min;
                                double max;
                                GetClosePart(neighbor, geom, segPart, nearSquared, is3D,
                                             out min, out max);

                                d0Min = d0Min + min * neighbor.Length;
                            }                     //else segPart is definitly near neighbor
                        }                         // else segPart is definitly not near neighbor

                        d0 = Math.Min(d0, d0Min);
                    }
                }

                if (d0 < connectedMinLength)
                {
                    connectedList = nearSelfConnectedList;
                }

                #endregion
            }

            if (connectedList.Count > 0)
            {
                current = connectedList[connectedList.Count - 1];
            }

            if (current != null)
            {
                if (current.PartIndex != segPart.PartIndex)
                {
                    current = null;
                }
                else if (current.EndFullIndex < segPart.FullMin)
                {
                    current = null;
                }
            }

            if (current == null)
            {
                current = new ConnectedSegmentParts(geom, segPart);
                connectedList.Add(current);
            }
            else
            {
                current.AddPart(segPart);
            }
        }