/// <summary>
        /// Triangulation algorithm of building segments, based on vertices collection
        /// </summary>
        /// <param name="vertices">Collection of all predefined vertices (points)</param>
        /// <returns>Collection of non-intersecting segments which in total form a set of triangles</returns>
        /// <remarks><see cref="ITriangulation.Triangulate(VertexCollection)"/> implementation</remarks>
        public List <Edge> Triangulate(VertexCollection vertices)
        {
            Util.Check.NotNull(vertices, "Can't triangulate null collection");
            var i = 0u;

            foreach (var v in vertices)
            {
                v.Id = i++;
            }
            ;

            var vvertices = vertices.OrderBy(v => v.X).ThenBy(v => v.Y);

            Vertices = vvertices.ToVertexCollection();

            var result = new List <Edge>();

            Debug.WriteLine($"Create Super Triangle:");

            var superTriangle = GetSuperTriangle(vertices);

            Debug.WriteLine($"{superTriangle}");

            var triangulation = new HashSet <Triangle>
            {
                superTriangle
            };

            foreach (var point in vvertices)
            {
                var badTriangles = FindBadTriangles(point, triangulation);
                var polygon      = FindHoleBoundaries(badTriangles);

                foreach (var triangle in badTriangles)
                {
                    foreach (var vertex in triangle.Vertices)
                    {
                        vertex.AdjacentTriangles.Remove(triangle);
                    }
                }

                triangulation.RemoveWhere(triangle => badTriangles.Contains(triangle));

                Debug.WriteLine("Start build new triangles");
                Debug.WriteLine($"Current point: {point}");
                var posibleEdges = polygon.Where(possibleEdge => possibleEdge.Start != point && possibleEdge.End != point).DistinctEdge().ToList();
                foreach (var edge in posibleEdges)
                {
                    Debug.WriteLine($"Edge for new triangle: {edge}");
                    if ((point.X == edge.Start.X && point.X == edge.End.X) ||
                        (point.Y == edge.Start.Y && point.Y == edge.End.Y))
                    {
                        Debug.WriteLine(new string('-', 20));
                        Debug.WriteLine("Something wrong");
                        continue;
                    }

                    var triangle = new Triangle(point, edge.Start, edge.End);
                    triangulation.Add(triangle);
                }
            }

            triangulation.RemoveWhere(t => t.Vertices.Any(v => superTriangle.Vertices.Contains(v)));

            Triangles = triangulation.ToList();

            foreach (var triangle in triangulation)
            {
                triangle.Vertices.
                ForEach(v => v.AdjacentTriangles.RemoveWhere(t => t.Vertices.Intersect(superTriangle.Vertices).Any()));
                result.AddRange(triangle.Edges);
            }

            return(result.DistinctEdge().ToList());
        }