/// <summary>
        /// 
        /// </summary>
        /// <param name="wkt"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        public void RunExtractedLine(string wkt, double start, double end)    
        {
            Console.WriteLine("=========================");
            IGeometry g1 = rdr.Read(wkt);
            Console.WriteLine("Input Geometry: " + g1);
            Console.WriteLine("Indices to extract: " + start + " " + end);
            
            LengthIndexedLine indexedLine = new LengthIndexedLine(g1);

            IGeometry subLine = indexedLine.ExtractLine(start, end);
            Console.WriteLine("Extracted Line: " + subLine);

            double[] index = indexedLine.IndicesOf(subLine);
            Console.WriteLine("Indices of extracted line: " + index[0] + " " + index[1]);

            ICoordinate midpt = indexedLine.ExtractPoint((index[0] + index[1]) / 2);
            Console.WriteLine("Midpoint of extracted line: " + midpt);
        }
        //INetworkCoverage coverage, 
        private static IList<INetworkSegment> UpdateSegmentsBranchSegmentBetweenLocations(bool fullyCover,
                                                                                          IBranch branch,
                                                                                          IEnumerable<INetworkLocation>
                                                                                              branchLocations)
        {
            var segments = new List<INetworkSegment>();

            var length = branch.Length;

            // select all locations that have an offset within the branch
            var factor = 1.0; // branch.IsLengthCustom ? (branch.Geometry.Length / branch.Length) : 1.0;
            IList<double> offsets =
                branchLocations.Where(l => l.Chainage <= length).Select(l => factor*l.Chainage).ToList();

            if (0 == offsets.Count)
            {
                if (fullyCover)
                {
                    offsets.Add(0);
                    offsets.Add(length);
                }
                else
                {
                    return segments;
                }
            }
            else
            {
                if (fullyCover)
                {
                    if (Math.Abs(offsets[0]) > BranchFeature.Epsilon)
                    {
                        offsets.Insert(0, 0.0);
                    }
                    if (Math.Abs(offsets[offsets.Count - 1] - length) > BranchFeature.Epsilon)
                    {
                        offsets.Add(length);
                    }
                }
            }

            var lengthIndexedLine = new LengthIndexedLine(branch.Geometry);

            for (int i = 1; i < offsets.Count; i++)
            {
                var segment = new NetworkSegment
                    {
                        Branch = branch,
                        Chainage = offsets[i - 1],
                        Length = Math.Abs(offsets[i] - offsets[i - 1]),
                        DirectionIsPositive = offsets[i] >= offsets[i - 1],
                        // thousand bombs and grenades: ExtractLine will give either a new coordinate or 
                        // a reference to an existing object
                        Geometry = (IGeometry) lengthIndexedLine.ExtractLine(offsets[i - 1], offsets[i]).Clone()
                    };
                segments.Add(segment);
            }
            return segments;
        }
        //INetworkCoverage coverage, 
        private static IEnumerable<INetworkSegment> UpdateSegmentsBranchSegmentBetweenLocations(bool fullyCover, 
            IBranch branch, IEnumerable<INetworkLocation> branchLocations)
        {
            var segments = new List<INetworkSegment>();

            var length = branch.Length;
            //note do we really want this?? should this not be handled in branch!
            /*if (branch.Geometry != null)
            {
                length = branch.Geometry.Length; // TODO: check if it is geometry-based, length can be in local units
            }*/

            // select all locations that have an offset within the branch
            IList<double> offsets = branchLocations.Where(l => l.Offset <= length).Select(l => l.Offset).ToList();

            if (0 == offsets.Count)
            {
                if (fullyCover)
                {
                    offsets.Add(0);
                    offsets.Add(length);
                }
                else
                {
                    return segments;
                }
            }
            else
            {
                if (fullyCover)
                {
                    if (Math.Abs(offsets[0]) > 1.0e-6)
                    {
                        offsets.Add(0.0);
                    }
                    if (Math.Abs(offsets[offsets.Count - 1] - length) > 1.0e-6)
                    {
                        offsets.Add(length);
                    }
                }
            }

            var lengthIndexedLine = new LengthIndexedLine(branch.Geometry);

            for (int i=1; i< offsets.Count; i++)
            {
                var segment = new NetworkSegment
                                  {
                                      Branch = branch,
                                      Offset = offsets[i - 1],
                                      Length = Math.Abs(offsets[i] - offsets[i - 1]),
                                      DirectionIsPositive = offsets[i] >= offsets[i - 1],
                                      // thousand bombs and granates: ExtractLine will give either a new coordinate or 
                                      // a reference to an existing object
                                      Geometry = (IGeometry)lengthIndexedLine.ExtractLine(offsets[i - 1], offsets[i]).Clone()
                };
                segments.Add(segment);
                //coverage.Segments.Values.Add(segment);
            }
            return segments;
        }