/// <summary>
        /// Checks if the path contains the specified segment.
        /// </summary>
        /// <param name="item">Segment to search for.</param>
        /// <returns><c>true</c> if the item is found in the path, <c>false</c> otherwise.</returns>
        public bool Contains(IPathSegment item)
        {
            PartitionPathSegment laneSegment = item as PartitionPathSegment;

            if (laneSegment == null)
            {
                return(false);
            }

            LanePartition lanePartition = laneSegment.UserPartition.ParentPartition as LanePartition;

            if (lanePartition == null)
            {
                return(false);
            }

            return(lanePartition.Lane.Equals(lane));
        }
        /// <summary>
        /// Returns the <see cref="PointOnPath"/> associated with the supplied <see cref="RndfWayPoint"/>.
        /// </summary>
        /// <param name="waypoint"><see cref="RndfWayPoint"/> to find on the path.</param>
        /// <returns><see cref="PointOnPath"/> instance of <paramref name="waypoint"/>.</returns>
        /// <remarks>
        /// The methods does not do any searching but returns the <see cref="PointOnPath"/> object directly. It will put
        /// the point at the end of a <see cref="PartitionPathSegment"/> if possible or at the beginning if the waypoint
        /// is the first in the lane.
        /// </remarks>
        /// <exception cref="ArgumentException">
        /// Throw when the waypoint does not belong to the <see cref="Lane"/> associated with the <see cref="LanePath"/>.
        /// </exception>
        public PointOnPath GetWaypointPoint(RndfWayPoint waypoint)
        {
            if (!lane.Equals(waypoint.Lane))
            {
                throw new ArgumentException("Waypoint does not belong to the current lane");
            }

            // get the user partition for that stuff
            if (waypoint.PreviousLanePartition != null)
            {
                LanePartition        laneParition = waypoint.PreviousLanePartition;
                PartitionPathSegment pathSeg      = GetPathSegment(laneParition.UserPartitions[laneParition.UserPartitions.Count - 1]);
                return(pathSeg.EndPoint);
            }
            else
            {
                LanePartition        laneParition = waypoint.NextLanePartition;
                PartitionPathSegment pathSeg      = GetPathSegment(laneParition.UserPartitions[0]);
                return(pathSeg.StartPoint);
            }
        }
        /// <summary>
        /// Returns the index of the specified segment.
        /// </summary>
        /// <param name="item">Segment to look for.</param>
        /// <returns>
        /// Zero-based index of segment if found, -1 if not found.
        /// </returns>
        public int IndexOf(IPathSegment item)
        {
            PartitionPathSegment laneSeg = item as PartitionPathSegment;

            if (laneSeg == null)
            {
                return(-1);
            }

            UserPartition partition     = laneSeg.UserPartition;
            LanePartition lanePartition = partition.ParentPartition as LanePartition;

            Debug.Assert(lanePartition.Lane.Equals(lane));

            int index     = partition.ParentPartition.UserPartitions.IndexOf(partition);
            int laneIndex = lanePartition.Lane.LanePartitions.IndexOf(lanePartition);

            while (--laneIndex > 0)
            {
                index += lane.LanePartitions[laneIndex].UserPartitions.Count;
            }
            return(index);
        }
        /// <summary>
        /// Returns a path segment enumerator starting with the specified <see cref="UserPartition"/>.
        /// </summary>
        /// <param name="partition">Starting <see cref="UserPartition"/> of the enumerator</param>
        /// <returns>An <see cref="IEnumerable{IPathSegment}"/> instance.</returns>
        /// <remarks>
        /// <para>Each <see cref="IPathSegment"/> of the enumerator will be a <see cref="PartitionPathSegment"/>
        /// instance wrapping a <see cref="UserPartition"/>.
        /// </para>
        /// <para>
        /// The enumerator will start at the user partition specified by <paramref name="partition"/>.
        /// </para>
        /// </remarks>
        /// <example>
        /// This code example enumerates over all the user partition starting with a given starting partition.
        /// <code>
        /// foreach (IPathSegment seg in path.GetEnumeratorFrom(startingPartition) {
        ///		PartitionPathSegment partitionSeg = (PartitionPathSegment)seg;
        ///		Debug.WriteLine("user parition id: + " + partitionSeg.UserPartition.PartitionID.ToString());
        ///		Debug.WriteLine("start: " + seg.Start.ToString() + ", end: " + seg.End.ToString());
        /// }
        /// </code>
        /// </example>
        public IEnumerable <IPathSegment> GetEnumeratorFrom(UserPartition partition)
        {
            // enumerate over the first segment
            LanePartition lanePartition = partition.ParentPartition as LanePartition;

            if (lanePartition == null)
            {
                throw new InvalidOperationException();
            }

            for (int i = lanePartition.UserPartitions.IndexOf(partition); i < lanePartition.UserPartitions.Count; i++)
            {
                yield return(GetPathSegment(lanePartition.UserPartitions[i]));
            }

            // enumerate over the later lane partitions
            for (int i = lane.LanePartitions.IndexOf(lanePartition) + 1; i < lane.LanePartitions.Count; i++)
            {
                foreach (UserPartition userPartition in lane.LanePartitions[i].UserPartitions)
                {
                    yield return(GetPathSegment(userPartition));
                }
            }
        }