public void ChangeFields(string newPreviousBusStopNameForDepartureOrNextBusStopForArrival, string newLineNumberWhichLeadToThisBusStop,
     TimeOfArrival newTotalTimeFromStartBus, DateTime newArrivalDateTimeAtThisBusStopForDepartureOrAtTheNextBusStopForArrival, DateTime newDepartureDateTimeFromPreviousBusStopForDepartureOrFromCurrentBusStopForArrival)
 {
     this.PreviousBusStopNameForDepartureOrNextBusStopForArrival = newPreviousBusStopNameForDepartureOrNextBusStopForArrival;
     this.LineNumberWhichLeadToThisBusStop = newLineNumberWhichLeadToThisBusStop;
     this.TotalTimeFromStartBus = newTotalTimeFromStartBus;
     this.ArrivalDateTimeAtThisBusStopForDepartureOrAtTheNextBusStopForArrival = newArrivalDateTimeAtThisBusStopForDepartureOrAtTheNextBusStopForArrival;
     this.DepartureDateTimeFromPreviousBusStopForDepartureOrFromCurrentBusStopForArrival = newDepartureDateTimeFromPreviousBusStopForDepartureOrFromCurrentBusStopForArrival;
 }
        public void ChangeFieldsForDepartureOption(DateTime newDepartureDateTime, string newStartBusStopName)
        {
            DepartureDateTime = newDepartureDateTime;
            StartBusStopName = newStartBusStopName;

            TimeOfArrival departureTime = new TimeOfArrival(DepartureDateTime.Hour, DepartureDateTime.Minute);
            TimeOfArrival arrivalTime = new TimeOfArrival(ArrivalDateTime.Hour, ArrivalDateTime.Minute);
            TimeDistanceBetweenBusStops = arrivalTime - departureTime;
        }
 public SingleBusStopForIndirectConnection(string busStopName, string previousBusStopNameForDepartureOrNextBusStopForArrival, string lineNumberWhichLeadToThisBusStop, TimeOfArrival totalTimeFromStartBus,
     DateTime arrivalDateTimeAtThisBusStopForDepartureOrAtTheNextBusStopForArrival, DateTime departureDateTimeFromPreviousBusStopForDepartureOrFromCurrentBusStopForArrival)
 {
     BusStopName = busStopName;
     PreviousBusStopNameForDepartureOrNextBusStopForArrival = previousBusStopNameForDepartureOrNextBusStopForArrival;
     LineNumberWhichLeadToThisBusStop = lineNumberWhichLeadToThisBusStop;
     TotalTimeFromStartBus = totalTimeFromStartBus;
     ArrivalDateTimeAtThisBusStopForDepartureOrAtTheNextBusStopForArrival = arrivalDateTimeAtThisBusStopForDepartureOrAtTheNextBusStopForArrival;
     DepartureDateTimeFromPreviousBusStopForDepartureOrFromCurrentBusStopForArrival = departureDateTimeFromPreviousBusStopForDepartureOrFromCurrentBusStopForArrival;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="TemporaryTrackNode"/> class.
 /// </summary>
 /// <param name="hour">The hour of arrival.</param>
 /// <param name="busLineNumber">The bus line number.</param>
 /// <param name="busStopName">Name of the bus stop.</param>
 /// <param name="nextBusStopName">Name of the next bus stop.</param>
 /// <param name="letter">The letter next to arrival time.</param>
 /// <param name="dayType">Type of the day.</param>
 public TemporaryTrackNode(TimeOfArrival hour, string busLineNumber, string busStopName,
     string nextBusStopName, string letter, string dayType)
 {
     BusLineNumber = busLineNumber;
     BusStopName = busStopName;
     Hour = hour;
     NextBusStopName = nextBusStopName;
     Letter = letter;
     DayType = dayType;
 }
 public SearchResultConnection(bool isDirectConnection, string lineNumber, DateTime departureDateTime, DateTime arrivalDateTime, 
     TimeOfArrival timeDistanceBetweenBusStops, string startBusStopName, string endBusStopName)
 {
     IsDirectConnection = isDirectConnection;
     LineNumber = lineNumber;
     DepartureDateTime = departureDateTime;
     ArrivalDateTime = arrivalDateTime;
     TimeDistanceBetweenBusStops = timeDistanceBetweenBusStops;
     StartBusStopName = startBusStopName;
     EndBusStopName = endBusStopName;
 }
        public SearchResultConnection FindDirectConnectionWitMaxWaitingTime(Repository repository, SoughtConnection soughtConnection, TimeOfArrival maxWaitingTime)
        {
            List<BusStop> busStops = repository.BusStops;
            if (busStops == null)
            {
                return null;
            }

            TypeOfDayRecognizer dayRecognizer = new TypeOfDayRecognizer();
            List<string> dayTypes = dayRecognizer.RecognizeTypeOfDay(soughtConnection.DateAndTime);
            TracksGiverForSpecifiedDayType tracksGiverForSpecfiedDayType = new TracksGiverForSpecifiedDayType();

            BusStop startBusStop = null;
            BusStop endBusStop = null;
            FindStartAndEndBusStop(ref startBusStop, ref endBusStop, soughtConnection.StartBusStop, soughtConnection.EndBusStop, busStops);

            List<Line> linesPlyingThroughBothBusStops = GiveLinesPlyingThroughTwoBusStops(startBusStop, endBusStop);

            List<LineForSpecifiedDayType> allTracksFromStartToEndBusStopInSpecifiedDayType =
                tracksGiverForSpecfiedDayType.GiveLinesForSpecifiedDayType(linesPlyingThroughBothBusStops, dayTypes);

            SearchResultConnection result = GiveDirectConnectionWitMaxWaitingTime(allTracksFromStartToEndBusStopInSpecifiedDayType,
                soughtConnection, maxWaitingTime);
            if (result != null)
            {
                return result;
            }

            DateTime newDateForSoughtConnection = new DateTime();
            if (soughtConnection.IsDeparture)
            {
                DateTime dayAfterDaySpecifiedByUser = soughtConnection.DateAndTime.AddDays(1);
                newDateForSoughtConnection = new DateTime(dayAfterDaySpecifiedByUser.Year, dayAfterDaySpecifiedByUser.Month, dayAfterDaySpecifiedByUser.Day, 0, 0, 0);
            }
            else
            {
                DateTime dayBeforeDaySpecifiedByUser = soughtConnection.DateAndTime.AddDays(-1);
                newDateForSoughtConnection = new DateTime(dayBeforeDaySpecifiedByUser.Year, dayBeforeDaySpecifiedByUser.Month, dayBeforeDaySpecifiedByUser.Day, 23, 59, 0);
            }

            soughtConnection = new SoughtConnection(startBusStop.BusStopName, endBusStop.BusStopName, newDateForSoughtConnection, soughtConnection.IsDeparture);
            dayTypes = dayRecognizer.RecognizeTypeOfDay(newDateForSoughtConnection);
            allTracksFromStartToEndBusStopInSpecifiedDayType =
                tracksGiverForSpecfiedDayType.GiveLinesForSpecifiedDayType(linesPlyingThroughBothBusStops, dayTypes);
            result = GiveDirectConnectionWitMaxWaitingTime(allTracksFromStartToEndBusStopInSpecifiedDayType,
                soughtConnection, maxWaitingTime);
            return result;
        }
        private SearchResultConnection GiveDirectConnectionWitMaxWaitingTime(List<LineForSpecifiedDayType> allSpecifiedLines, SoughtConnection soughtConnection, TimeOfArrival maxWaitingTime)
        {
            SearchResultConnection foundConnection = null;
            TimeOfArrival soughConnectionTimeOfArrival = new TimeOfArrival(soughtConnection.DateAndTime.Hour, soughtConnection.DateAndTime.Minute);
            foreach (LineForSpecifiedDayType line in allSpecifiedLines)
            {
                foreach (Track track in line.TracksForSpecifiedDayType)
                {
                    try
                    {
                        if (track.TimeOfArrivalOnBusStops.Count < 2)
                        {
                            continue;
                        }
                        if (soughtConnection.IsDeparture)
                        {
                            if (track.TimeOfArrivalOnBusStops.Last().Value - soughConnectionTimeOfArrival > MAX_LENGTH_OF_TRACK
                                || (track.TimeOfArrivalOnBusStops.First().Value - soughConnectionTimeOfArrival > MAX_WAITING_TIME_FOR_START_BUS_FOR_DEPARTUE_OR_FOR_END_BUS_FOR_ARRIVAL
                                    && soughConnectionTimeOfArrival - track.TimeOfArrivalOnBusStops.First().Value > MAX_LENGTH_OF_TRACK))
                            {
                                continue;
                            }
                        }
                        else
                        {
                            if (soughConnectionTimeOfArrival - track.TimeOfArrivalOnBusStops.First().Value > MAX_LENGTH_OF_TRACK
                                || (soughConnectionTimeOfArrival - track.TimeOfArrivalOnBusStops.Last().Value > MAX_WAITING_TIME_FOR_START_BUS_FOR_DEPARTUE_OR_FOR_END_BUS_FOR_ARRIVAL
                                    && track.TimeOfArrivalOnBusStops.Last().Value - soughConnectionTimeOfArrival > MAX_LENGTH_OF_TRACK))

                            {
                                continue;
                            }
                        }

                        TimeOfArrival startBusStopTimeOfArrival = track.TimeOfArrivalOnBusStops[soughtConnection.StartBusStop];
                        TimeOfArrival endBusStopTimeOfArrival = track.TimeOfArrivalOnBusStops[soughtConnection.EndBusStop];

                        if (soughtConnection.IsDeparture)
                        {
                            if (startBusStopTimeOfArrival - soughConnectionTimeOfArrival > maxWaitingTime)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            if (soughConnectionTimeOfArrival - endBusStopTimeOfArrival > maxWaitingTime)
                            {
                                continue;
                            }
                        }

                        TimeOfArrival timeDistanceBetweenStartAndEndBusStop = endBusStopTimeOfArrival - startBusStopTimeOfArrival;
                        if (timeDistanceBetweenStartAndEndBusStop > new TimeOfArrival(4, 0))
                        {
                            continue;
                        }

                        DateTime startBusStopDateTime = new DateTime();
                        DateTime endBusStopDateTime = new DateTime();
                        if (endBusStopTimeOfArrival >= startBusStopTimeOfArrival)
                        {
                            // the same dates
                            startBusStopDateTime = new DateTime(soughtConnection.DateAndTime.Year, soughtConnection.DateAndTime.Month, soughtConnection.DateAndTime.Day,
                                startBusStopTimeOfArrival.Hour, startBusStopTimeOfArrival.Minutes, 0);
                            endBusStopDateTime = new DateTime(soughtConnection.DateAndTime.Year, soughtConnection.DateAndTime.Month, soughtConnection.DateAndTime.Day,
                                endBusStopTimeOfArrival.Hour, endBusStopTimeOfArrival.Minutes, 0);
                        }
                        else
                        {
                            // end date is one day after start date
                            startBusStopDateTime = new DateTime(soughtConnection.DateAndTime.Year, soughtConnection.DateAndTime.Month, soughtConnection.DateAndTime.Day,
                                startBusStopTimeOfArrival.Hour, startBusStopTimeOfArrival.Minutes, 0);
                            DateTime dayAfterDayInSoughtConnection = soughtConnection.DateAndTime.AddDays(1);
                            endBusStopDateTime = new DateTime(dayAfterDayInSoughtConnection.Year, dayAfterDayInSoughtConnection.Month, dayAfterDayInSoughtConnection.Day,
                                endBusStopTimeOfArrival.Hour, endBusStopTimeOfArrival.Minutes, 0);
                        }

                        TimeOfArrival timeSpecifiedByUser = new TimeOfArrival(soughtConnection.DateAndTime.Hour, soughtConnection.DateAndTime.Minute);
                        if (soughtConnection.IsDeparture)
                        {
                            if (startBusStopTimeOfArrival >= timeSpecifiedByUser)
                            {
                                if (foundConnection == null)
                                {

                                    foundConnection = new SearchResultConnection(true, line.Number, startBusStopDateTime,
                                        endBusStopDateTime, timeDistanceBetweenStartAndEndBusStop, soughtConnection.StartBusStop, soughtConnection.EndBusStop);
                                }
                                else
                                {
                                    TimeOfArrival foundConnectionArrivalTime = new TimeOfArrival(foundConnection.ArrivalDateTime.Hour, foundConnection.ArrivalDateTime.Minute);
                                    if (foundConnectionArrivalTime > endBusStopTimeOfArrival)
                                    {
                                        foundConnection = new SearchResultConnection(true, line.Number, startBusStopDateTime,
                                            endBusStopDateTime, timeDistanceBetweenStartAndEndBusStop, soughtConnection.StartBusStop, soughtConnection.EndBusStop);
                                    }
                                }
                            }

                        }
                        else
                        {
                            if (endBusStopTimeOfArrival <= timeSpecifiedByUser)
                            {
                                if (foundConnection == null)
                                {
                                    foundConnection = new SearchResultConnection(true, line.Number, startBusStopDateTime,
                                        endBusStopDateTime, timeDistanceBetweenStartAndEndBusStop, soughtConnection.StartBusStop, soughtConnection.EndBusStop);
                                }
                                else
                                {
                                    TimeOfArrival foundConnectionArrivalTime = new TimeOfArrival(foundConnection.ArrivalDateTime.Hour, foundConnection.ArrivalDateTime.Minute);
                                    if (foundConnectionArrivalTime < startBusStopTimeOfArrival)
                                    {
                                        foundConnection = new SearchResultConnection(true, line.Number, startBusStopDateTime,
                                            endBusStopDateTime, timeDistanceBetweenStartAndEndBusStop, soughtConnection.StartBusStop, soughtConnection.EndBusStop);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception)
                    {
                    }
                }
            }

            return foundConnection;
        }
 public SearcherOfDirectRoutes()
 {
     MAX_WAITING_TIME_FOR_START_BUS_FOR_DEPARTUE_OR_FOR_END_BUS_FOR_ARRIVAL = new TimeOfArrival(2, 0);
     MAX_LENGTH_OF_TRACK = new TimeOfArrival(2, 0);
 }
        private SearchResultConnection GiveDirectConnection(List<LineForSpecifiedDayType> allSpecifiedLines, SoughtConnection soughtConnection)
        {
            SearchResultConnection foundConnection = null;
            foreach (LineForSpecifiedDayType line in allSpecifiedLines)
            {
                foreach (Track track in line.TracksForSpecifiedDayType)
                {
                    try
                    {
                        TimeOfArrival startBusStopTimeOfArrival = track.TimeOfArrivalOnBusStops[soughtConnection.StartBusStop];
                        TimeOfArrival endBusStopTimeOfArrival = track.TimeOfArrivalOnBusStops[soughtConnection.EndBusStop];
                        TimeOfArrival timeDistanceBetweenStartAndEndBusStop = endBusStopTimeOfArrival - startBusStopTimeOfArrival;
                        if (timeDistanceBetweenStartAndEndBusStop > new TimeOfArrival(8, 0))
                        {
                            continue;
                        }

                        DateTime startBusStopDateTime = new DateTime();
                        DateTime endBusStopDateTime = new DateTime();
                        if (endBusStopTimeOfArrival >= startBusStopTimeOfArrival)
                        {
                            // the same dates
                            startBusStopDateTime = new DateTime(soughtConnection.DateAndTime.Year, soughtConnection.DateAndTime.Month, soughtConnection.DateAndTime.Day,
                                startBusStopTimeOfArrival.Hour, startBusStopTimeOfArrival.Minutes, 0);
                            endBusStopDateTime = new DateTime(soughtConnection.DateAndTime.Year, soughtConnection.DateAndTime.Month, soughtConnection.DateAndTime.Day,
                                endBusStopTimeOfArrival.Hour, endBusStopTimeOfArrival.Minutes, 0);
                        }
                        else
                        {
                            // end date is one day after start date
                            startBusStopDateTime = new DateTime(soughtConnection.DateAndTime.Year, soughtConnection.DateAndTime.Month, soughtConnection.DateAndTime.Day,
                                startBusStopTimeOfArrival.Hour, startBusStopTimeOfArrival.Minutes, 0);
                            DateTime dayAfterDayInSoughtConnection = soughtConnection.DateAndTime.AddDays(1);
                            endBusStopDateTime = new DateTime(dayAfterDayInSoughtConnection.Year, dayAfterDayInSoughtConnection.Month, dayAfterDayInSoughtConnection.Day,
                                endBusStopTimeOfArrival.Hour, endBusStopTimeOfArrival.Minutes, 0);
                        }

                        TimeOfArrival timeSpecifiedByUser = new TimeOfArrival(soughtConnection.DateAndTime.Hour, soughtConnection.DateAndTime.Minute);
                        if (soughtConnection.IsDeparture)
                        {
                            if (startBusStopTimeOfArrival >= timeSpecifiedByUser)
                            {
                                if (foundConnection == null)
                                {

                                    foundConnection = new SearchResultConnection(true, line.Number, startBusStopDateTime,
                                        endBusStopDateTime, timeDistanceBetweenStartAndEndBusStop, soughtConnection.StartBusStop, soughtConnection.EndBusStop);
                                }
                                else
                                {
                                    TimeOfArrival foundConnectionArrivalTime = new TimeOfArrival(foundConnection.ArrivalDateTime.Hour, foundConnection.ArrivalDateTime.Minute);
                                    if (foundConnectionArrivalTime > endBusStopTimeOfArrival)
                                    {
                                        foundConnection = new SearchResultConnection(true, line.Number, startBusStopDateTime,
                                            endBusStopDateTime, timeDistanceBetweenStartAndEndBusStop, soughtConnection.StartBusStop, soughtConnection.EndBusStop);
                                    }
                                }
                            }

                        }
                        else
                        {
                            if (endBusStopTimeOfArrival <= timeSpecifiedByUser)
                            {
                                if (foundConnection == null)
                                {
                                    foundConnection = new SearchResultConnection(true, line.Number, startBusStopDateTime,
                                        endBusStopDateTime, timeDistanceBetweenStartAndEndBusStop, soughtConnection.StartBusStop, soughtConnection.EndBusStop);
                                }
                                else
                                {
                                    TimeOfArrival foundConnectionArrivalTime = new TimeOfArrival(foundConnection.ArrivalDateTime.Hour, foundConnection.ArrivalDateTime.Minute);
                                    if (foundConnectionArrivalTime < startBusStopTimeOfArrival)
                                    {
                                        foundConnection = new SearchResultConnection(true, line.Number, startBusStopDateTime,
                                            endBusStopDateTime, timeDistanceBetweenStartAndEndBusStop, soughtConnection.StartBusStop, soughtConnection.EndBusStop);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception)
                    {
                    }
                }
            }

            return foundConnection;
        }
 /// <summary>
 /// Sorts stored data for correct building process.
 /// </summary>
 private void Sort()
 {
     TimeOfArrival tmp = new TimeOfArrival(0,0);
     List<TemporaryTrackNode> o = new List<TemporaryTrackNode>();
     List<List<TemporaryTrackNode>> _tracksData2 = new List<List<TemporaryTrackNode>>();
     do
     {
         foreach (List<TemporaryTrackNode> t in _tracksData)
         {
             if (t.First().Hour >= tmp)
             {
                 tmp = new TimeOfArrival(t.First().Hour);
                 o = t;
             }
         }
         _tracksData2.Add(o);
         _tracksData.Remove(o);
         tmp = new TimeOfArrival(0, 0);
     } while (_tracksData.Count > 0);
     _tracksData.AddRange(_tracksData2);
 }
        private List<SingleBusStopForIndirectConnection> FindBusStopsWithLinesWhichAreCloseToTheTarget(Repository repository, SoughtConnection soughtConnection, Delegates.UpdateInformationAboutProgresForTheUser updateInformationForUserAboutSearching)
        {
            SearcherOfDirectRoutes searcherOfDirectConnections = new SearcherOfDirectRoutes();
            List<SingleBusStopForIndirectConnection> busStopsToCheckList = InitializeBusStopsToCheckList(soughtConnection, repository.BusStops);
            List<SingleBusStopForIndirectConnection> busStopsCheckedList = new List<SingleBusStopForIndirectConnection>();

            string busStopNameStopCondition = "";
            NeighbourBusStopsRecognizer.Direction direction;
            if (soughtConnection.IsDeparture)
            {
                busStopNameStopCondition = soughtConnection.EndBusStop;
                direction = NeighbourBusStopsRecognizer.Direction.Next;
            }
            else
            {
                busStopNameStopCondition = soughtConnection.StartBusStop;
                direction = NeighbourBusStopsRecognizer.Direction.Previous;
            }

            // lastBusStop is (only in the first step)
            // - start bus stop for departure
            // - end bus stop for arrival
            SingleBusStopForIndirectConnection lastBusStop = busStopsToCheckList.Last();
            busStopsToCheckList.RemoveAt(busStopsToCheckList.Count - 1);
            busStopsCheckedList.Add(lastBusStop);
            int numberOfAllBusStopsToCheck = busStopsToCheckList.Count;
            TimeOfArrival maxWaitingTime = new TimeOfArrival(2, 0);
            do
            {
                double actualProgress = (double)busStopsCheckedList.Count / (double)numberOfAllBusStopsToCheck;
                updateInformationForUserAboutSearching(actualProgress);
                DateTime dateTomeForRecognizerOfNeighbourBusStops = new DateTime();
                if (soughtConnection.IsDeparture)
                {
                    dateTomeForRecognizerOfNeighbourBusStops = lastBusStop.ArrivalDateTimeAtThisBusStopForDepartureOrAtTheNextBusStopForArrival;
                }
                else
                {
                    dateTomeForRecognizerOfNeighbourBusStops = lastBusStop.DepartureDateTimeFromPreviousBusStopForDepartureOrFromCurrentBusStopForArrival;
                }
                List<string> neighbourBusStopsList = new NeighbourBusStopsRecognizer().RecognizeNeighbourBusStopsInSpecifiedDirection(lastBusStop.BusStopName,
                    repository, dateTomeForRecognizerOfNeighbourBusStops, direction);
                foreach (SingleBusStopForIndirectConnection oneBusStop in busStopsToCheckList)
                {
                    bool oneBusStopWasFound = false;

                    foreach (string neighbourBusStop in neighbourBusStopsList)
                    {
                        if (neighbourBusStop.Equals(oneBusStop.BusStopName))
                        {
                            oneBusStopWasFound = true;
                            break;
                        }
                    }

                    if (!oneBusStopWasFound)
                    {
                        continue;
                    }
                    SoughtConnection singleSoughtConnection = null;
                    if (soughtConnection.IsDeparture)
                    {
                        singleSoughtConnection = new SoughtConnection(lastBusStop.BusStopName, oneBusStop.BusStopName,
                            lastBusStop.ArrivalDateTimeAtThisBusStopForDepartureOrAtTheNextBusStopForArrival, soughtConnection.IsDeparture);
                    }
                    else
                    {
                        singleSoughtConnection = new SoughtConnection(oneBusStop.BusStopName, lastBusStop.BusStopName,
                            lastBusStop.DepartureDateTimeFromPreviousBusStopForDepartureOrFromCurrentBusStopForArrival, soughtConnection.IsDeparture);
                    }
                    SearchResultConnection singleResult = searcherOfDirectConnections.FindDirectConnectionWitMaxWaitingTime(repository, singleSoughtConnection, maxWaitingTime);

                    if (singleResult != null)
                    {
                        TimeOfArrival newArrivalTimeOnEndBusStop = new TimeOfArrival(singleResult.ArrivalDateTime.Hour, singleResult.ArrivalDateTime.Minute);
                        if (oneBusStop.TotalTimeFromStartBus == null)
                        {
                            // only save this informations
                            oneBusStop.ChangeFields(lastBusStop.BusStopName, singleResult.LineNumber,
                                lastBusStop.TotalTimeFromStartBus + singleResult.TimeDistanceBetweenBusStops, singleResult.ArrivalDateTime, singleResult.DepartureDateTime);
                        }
                        else
                        {
                            // check if new time is lower and then save this
                            if ((lastBusStop.TotalTimeFromStartBus + singleResult.TimeDistanceBetweenBusStops) < oneBusStop.TotalTimeFromStartBus) // condition
                            {
                                oneBusStop.ChangeFields(lastBusStop.BusStopName, singleResult.LineNumber,
                                    lastBusStop.TotalTimeFromStartBus + singleResult.TimeDistanceBetweenBusStops, singleResult.ArrivalDateTime, singleResult.DepartureDateTime);
                            }
                        }
                    }
                }
                int indexOfTheNearestBusStop = -1;
                TimeOfArrival actualTotalTimeTravel = new TimeOfArrival(23, 59);
                for (int i = 0; i < busStopsToCheckList.Count; i++)
                {
                    if (busStopsToCheckList[i].TotalTimeFromStartBus == null)
                    {
                        continue;
                    }
                    if (busStopsToCheckList[i].TotalTimeFromStartBus < actualTotalTimeTravel)
                    {
                        indexOfTheNearestBusStop = i;
                        actualTotalTimeTravel = busStopsToCheckList[i].TotalTimeFromStartBus;
                    }
                }
                // probably route doesn't exist
                if (indexOfTheNearestBusStop == -1)
                {
                    break;
                }

                lastBusStop = busStopsToCheckList[indexOfTheNearestBusStop];
                busStopsToCheckList.RemoveAt(indexOfTheNearestBusStop);
                busStopsCheckedList.Add(lastBusStop);
                maxWaitingTime = new TimeOfArrival(0, 20);

                // one of the conditions - found end bus stop and route to this bus stop
                if (lastBusStop.BusStopName.Equals(busStopNameStopCondition))
                {
                    break;
                }

            } while (busStopsToCheckList.Count > 0);

            return busStopsCheckedList;
        }
        private List<SearchResultConnection> ProcessBusStopsCheckedList(SoughtConnection soughtConnection, List<SingleBusStopForIndirectConnection> unprocessedBusStopsList)
        {
            List<SearchResultConnection> resultList = new List<SearchResultConnection>();
            if (unprocessedBusStopsList == null || unprocessedBusStopsList.Count < 2)
            {
                return null;
            }

            SingleBusStopForIndirectConnection lastBusStop = unprocessedBusStopsList.Last(); // for departure it's endBusStop, for arrival it's startBusStop
            unprocessedBusStopsList.RemoveAt(unprocessedBusStopsList.Count - 1);
            if (soughtConnection.IsDeparture)
            {
                if (!lastBusStop.BusStopName.Equals(soughtConnection.EndBusStop))
                {
                    return null;
                }
            }
            else
            {
                if (!lastBusStop.BusStopName.Equals(soughtConnection.StartBusStop))
                {
                    return null;
                }
            }

            string busStopNameForStopCondition = "";
            string startBusStopNameInDirectConnection = "";
            string endBusStopNameInDirectConnection = "";
            if (soughtConnection.IsDeparture)
            {
                busStopNameForStopCondition = soughtConnection.StartBusStop;
                startBusStopNameInDirectConnection = lastBusStop.PreviousBusStopNameForDepartureOrNextBusStopForArrival;
                endBusStopNameInDirectConnection = lastBusStop.BusStopName;
            }
            else
            {
                busStopNameForStopCondition = soughtConnection.EndBusStop;
                startBusStopNameInDirectConnection = lastBusStop.BusStopName;
                endBusStopNameInDirectConnection = lastBusStop.PreviousBusStopNameForDepartureOrNextBusStopForArrival;
            }
            bool stopCondition = false;
            TimeOfArrival arrivalTime = new TimeOfArrival(lastBusStop.ArrivalDateTimeAtThisBusStopForDepartureOrAtTheNextBusStopForArrival.Hour, lastBusStop.ArrivalDateTimeAtThisBusStopForDepartureOrAtTheNextBusStopForArrival.Minute);
            TimeOfArrival departureTime = new TimeOfArrival(lastBusStop.DepartureDateTimeFromPreviousBusStopForDepartureOrFromCurrentBusStopForArrival.Hour, lastBusStop.DepartureDateTimeFromPreviousBusStopForDepartureOrFromCurrentBusStopForArrival.Minute);
            TimeOfArrival timeDistanceBetweenBusStops = arrivalTime - departureTime;
            resultList.Add(new SearchResultConnection(false, lastBusStop.LineNumberWhichLeadToThisBusStop, lastBusStop.DepartureDateTimeFromPreviousBusStopForDepartureOrFromCurrentBusStopForArrival,
                lastBusStop.ArrivalDateTimeAtThisBusStopForDepartureOrAtTheNextBusStopForArrival, timeDistanceBetweenBusStops, startBusStopNameInDirectConnection, endBusStopNameInDirectConnection));
            do
            {
                string previousOrNextBusStopName = lastBusStop.PreviousBusStopNameForDepartureOrNextBusStopForArrival;

                int indexOfUnprocessedBusStop = -1;
                for (int i = unprocessedBusStopsList.Count - 1; i >= 0; i--)
                {
                    if (unprocessedBusStopsList[i].BusStopName.Equals(previousOrNextBusStopName))
                    {
                        lastBusStop = unprocessedBusStopsList[i];
                        indexOfUnprocessedBusStop = i;
                        unprocessedBusStopsList.RemoveAt(indexOfUnprocessedBusStop);
                        break;
                    }
                }
                if (indexOfUnprocessedBusStop == -1)
                {
                    return null;
                }

                if (lastBusStop.LineNumberWhichLeadToThisBusStop.Equals(resultList.Last().LineNumber))
                {
                    if (soughtConnection.IsDeparture)
                    {
                        resultList.Last().ChangeFieldsForDepartureOption(lastBusStop.DepartureDateTimeFromPreviousBusStopForDepartureOrFromCurrentBusStopForArrival, lastBusStop.PreviousBusStopNameForDepartureOrNextBusStopForArrival);
                    }
                    else
                    {
                        resultList.Last().ChangeFieldsForArrivalOption(lastBusStop.ArrivalDateTimeAtThisBusStopForDepartureOrAtTheNextBusStopForArrival, lastBusStop.PreviousBusStopNameForDepartureOrNextBusStopForArrival);
                    }
                }
                else
                {
                    if (soughtConnection.IsDeparture)
                    {
                        startBusStopNameInDirectConnection = lastBusStop.PreviousBusStopNameForDepartureOrNextBusStopForArrival;
                        endBusStopNameInDirectConnection = lastBusStop.BusStopName;
                    }
                    else
                    {
                        startBusStopNameInDirectConnection = lastBusStop.BusStopName;
                        endBusStopNameInDirectConnection = lastBusStop.PreviousBusStopNameForDepartureOrNextBusStopForArrival;
                    }

                    arrivalTime = new TimeOfArrival(lastBusStop.ArrivalDateTimeAtThisBusStopForDepartureOrAtTheNextBusStopForArrival.Hour, lastBusStop.ArrivalDateTimeAtThisBusStopForDepartureOrAtTheNextBusStopForArrival.Minute);
                    departureTime = new TimeOfArrival(lastBusStop.DepartureDateTimeFromPreviousBusStopForDepartureOrFromCurrentBusStopForArrival.Hour, lastBusStop.DepartureDateTimeFromPreviousBusStopForDepartureOrFromCurrentBusStopForArrival.Minute);
                    timeDistanceBetweenBusStops = arrivalTime - departureTime;
                    resultList.Add(new SearchResultConnection(false, lastBusStop.LineNumberWhichLeadToThisBusStop, lastBusStop.DepartureDateTimeFromPreviousBusStopForDepartureOrFromCurrentBusStopForArrival,
                        lastBusStop.ArrivalDateTimeAtThisBusStopForDepartureOrAtTheNextBusStopForArrival, timeDistanceBetweenBusStops, startBusStopNameInDirectConnection, endBusStopNameInDirectConnection));
                }

                if (lastBusStop.BusStopName.Equals(busStopNameForStopCondition))
                {
                    stopCondition = true;
                }
            } while (!stopCondition);

            resultList.RemoveAt(resultList.Count - 1);
            if (soughtConnection.IsDeparture)
            {
                resultList.Reverse();
            }

            return resultList;
        }