public Session(Navigraph graph,
                       Guid startWaypointID,
                       Guid finalWaypointID,
                       int[] avoid)
        {
            Event = new Event();

            //Read the xml file to get regions and edges information
            _regionGraph = graph.GetRegiongraph();
            //We only consider to one region situation,
            //therefore, we add different floors' waypoints in same regions
            _subgraph = graph.Regions[0].GetNavigationSubgraph(avoid);

            //Use the ID we get to search where the waypoints are
            Waypoint startWaypoint = _subgraph.Where(node =>
                                                     node.Item.ID.Equals(startWaypointID)).Select(w => w.Item).First();

            _finalWaypoint = _subgraph.Where(node =>
                                             node.Item.ID.Equals(finalWaypointID)).Select(w => w.Item).First();

            //Get the best route through dijkstra
            _allCorrectWaypoint = GetPath(startWaypoint,
                                          _finalWaypoint, _subgraph);
        }
        //In this function we get the currentwaypoint and determine whether
        //the users are in the right path or not.
        //And we return a structure called navigationInstruction that
        //contains four elements that Navigation main and UI need.
        //Moreover, if the users are not on the right path, we reroute and
        //tell users the new path.
        public void DetectRoute(object sender, EventArgs args)
        {
            Waypoint currentWaypoint = _subgraph.Where(node =>
                                                       node.Item.ID.Equals((args as WaypointScanEventArgs).WaypointID)).
                                       Select(w => w.Item).First();

            //NavigationInstruction is a structure that contains five
            //elements that need to be passed to the main and UI
            NavigationInstruction navigationInstruction =
                new NavigationInstruction();
            //getWaypoint is used to check where the current way point is in
            //which place of the Allcorrectwaypoint
            int getWaypoint = 0;

            if (currentWaypoint == _finalWaypoint)
            {
                Event.OnEventCall(new NavigationEventArgs
                {
                    Result = NavigationResult.Arrival
                });
            }
            else if (_allCorrectWaypoint.Contains(currentWaypoint))
            {
                //Check where the current point is in the AllcorrectWaypoint,
                //we need this informationto get the direction, the progress
                //and the next way point
                for (int i = 0; i < _allCorrectWaypoint.Count; i++)
                {
                    if (_allCorrectWaypoint[i].ID == currentWaypoint.ID)
                    {
                        getWaypoint = i;
                        break;
                    }
                }
                //Get nextwaypoint
                navigationInstruction.NextWaypoint =
                    _allCorrectWaypoint[getWaypoint + 1];

                //If the floor information between the current waypoint and
                //next are different, it means that the users need to change
                //the floor, therefore, we can determine the users need to
                //go up or down by compare which floor is higher
                if (currentWaypoint.Floor !=
                    _allCorrectWaypoint[getWaypoint + 1].Floor)
                {
                    if (currentWaypoint.Floor >
                        _allCorrectWaypoint[getWaypoint + 1].Floor)
                    {
                        navigationInstruction.Direction = TurnDirection.Down;
                    }
                    else
                    {
                        navigationInstruction.Direction = TurnDirection.Up;
                    }
                    navigationInstruction.Distance = 0;
                }
                //If the fllor information between current way point and next
                // way point are the same, we need to tell the user go
                //straight or turn direction, therefore, we need to have
                //three informations, previous, current and next waypoints
                else
                {
                    navigationInstruction.Distance =
                        Navigraph.GetDistance(_subgraph,
                                              currentWaypoint,
                                              _allCorrectWaypoint[getWaypoint + 1]);
                    //getwaypoint=0 means that we are now in the starting
                    // point, we do not have the previous waypoint
                    //therefore, we give the first point a direction called
                    // FirstDirection
                    if (getWaypoint == 0)
                    {
                        navigationInstruction.Direction =
                            TurnDirection.FirstDirection;
                    }
                    else
                    {
                        navigationInstruction.Direction =
                            Navigraph.GetTurnDirection(
                                _allCorrectWaypoint[getWaypoint - 1],
                                currentWaypoint,
                                _allCorrectWaypoint[getWaypoint + 1]);
                    }
                }

                //Get the progress
                navigationInstruction.Progress =
                    (double)Math.Round(
                        (decimal)getWaypoint / _allCorrectWaypoint.Count, 3);

                // Raise event to notify the UI/main thread with the result
                Event.OnEventCall(new NavigationEventArgs
                {
                    Result          = NavigationResult.Run,
                    NextInstruction = navigationInstruction
                });
            }
            else if (_allNoneWrongWaypoint
                     .Contains(currentWaypoint.ID) == false)
            {
                Event.OnEventCall(new NavigationEventArgs
                {
                    Result = NavigationResult.AdjustRoute
                });

                //If the waypoint is wrong, we initial the correct waypoint
                // and its neighbors and rerun the GetPath function and reget
                //the navigationInstruction
                _allCorrectWaypoint   = new List <Waypoint>();
                _allNoneWrongWaypoint = new List <Guid>();
                _allCorrectWaypoint   = GetPath(currentWaypoint,
                                                _finalWaypoint,
                                                _subgraph);

                Event.OnEventCall(new NavigationEventArgs
                {
                    Result          = NavigationResult.Run,
                    NextInstruction = new NavigationInstruction
                    {
                        NextWaypoint = _allCorrectWaypoint[1],
                        Distance     = Navigraph.
                                       GetDistance(_subgraph,
                                                   currentWaypoint,
                                                   _allCorrectWaypoint[1]),
                        Progress  = 0,
                        Direction = TurnDirection.FirstDirection
                    }
                });
            }
        }