/// <summary>
        /// Method to execute the task which is to create adaptive card attachements for every single reservation and display them.
        /// </summary>
        /// <param name="stepContext"></param>
        /// <param name="cancellationToken"></param>
        /// <returns>EndDialogAsync</returns>
        private async Task <DialogTurnResult> DisplayReservationsAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            ReservationStorage rstorage = await _accessor.ReservationStorageAccessor.GetAsync(stepContext.Context, () => new ReservationStorage());

            //This block decides if rstorage is not empty and there is any reservation to display.
            if (rstorage.Reservations != null)
            {
                if (rstorage.Reservations.Count > 0)
                {
                    //Initialize reservation list and assign list of reservations stored in rstorage.
                    IList <FlightInfo> reservations = rstorage.Reservations;
                    //Initialize reply Activity.
                    Activity reply = stepContext.Context.Activity.CreateReply();
                    reply.Attachments = new List <Attachment>();

                    //Create attachement for every element of the reservations list.
                    foreach (FlightInfo reservationInfo in reservations)
                    {
                        Attachment attachment = new Attachment();

                        //This block decides which adaptive card template should be used based on reservation details.
                        if (reservationInfo.OneWayFlight && reservationInfo.Rental == null)
                        {
                            attachment = CreateReservationAttachement(@".\Resources\FlightDetailsOneWay.txt", reservationInfo.PassengerName, reservationInfo.FromAirport, reservationInfo.ToAirport, reservationInfo.StartDate, reservationInfo.TripClass, (reservationInfo.FlightCost.ToString() + " $"), reservationInfo.ReservationId.ToString());
                        }
                        else if (!reservationInfo.OneWayFlight && reservationInfo.Rental == null)
                        {
                            attachment = CreateReservationAttachement(@".\Resources\FlightDetailsTwoWays.txt", reservationInfo.PassengerName, reservationInfo.FromAirport, reservationInfo.ToAirport, reservationInfo.StartDate, reservationInfo.TripClass, (reservationInfo.FlightCost.ToString() + " $"), reservationInfo.ReservationId.ToString(), reservationInfo.EndDate);
                        }
                        else if (reservationInfo.OneWayFlight && reservationInfo.Rental != null)
                        {
                            attachment = CreateCombinedAttachement(@".\Resources\FlightDetailsOneWayRental.txt", reservationInfo.PassengerName, reservationInfo.FromAirport, reservationInfo.ToAirport, reservationInfo.StartDate, reservationInfo.TripClass, (reservationInfo.FlightCost.ToString() + " $"), reservationInfo.ReservationId.ToString(), reservationInfo.Rental.RentalLength, reservationInfo.Rental.PassengersNumber, reservationInfo.Rental.ChildSeats, reservationInfo.Rental.CarClass, reservationInfo.Rental.RentalCost);
                        }
                        else if (!reservationInfo.OneWayFlight && reservationInfo.Rental != null)
                        {
                            attachment = CreateCombinedAttachement(@".\Resources\FlightDetailsTwoWaysRental.txt", reservationInfo.PassengerName, reservationInfo.FromAirport, reservationInfo.ToAirport, reservationInfo.StartDate, reservationInfo.TripClass, (reservationInfo.FlightCost.ToString() + " $"), reservationInfo.ReservationId.ToString(), reservationInfo.Rental.RentalLength, reservationInfo.Rental.PassengersNumber, reservationInfo.Rental.ChildSeats, reservationInfo.Rental.CarClass, reservationInfo.Rental.RentalCost, reservationInfo.EndDate);
                        }
                        ;

                        //Add created attachment to list of attachments.
                        reply.Attachments.Add(attachment);
                    }
                    await stepContext.Context.SendActivityAsync(reply, cancellationToken);

                    return(await stepContext.EndDialogAsync());
                }
            }
            //Inform user that there is not any reservation to dispaly.
            await stepContext.Context.SendActivityAsync("There is no reservation to display.");

            return(await stepContext.EndDialogAsync());
        }
        /// <summary>
        /// Method to execute the task which is to add the object of FlithInfo class to the object of ReservatonStorage class (list of FlightInfo objects) and end the GetFlightDetailsDialog.
        /// </summary>
        /// <param name="stepContext"></param>
        /// <param name="cancellationToken"></param>
        /// <returns>Ends the GetFlightDetailsDialog</returns>
        private async Task <DialogTurnResult> EndDialogAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            FlightInfo flightInfo = await _accessor.FlightInfoAccessor.GetAsync(stepContext.Context, () => new FlightInfo());

            ReservationStorage rstorage = await _accessor.ReservationStorageAccessor.GetAsync(stepContext.Context, () => new ReservationStorage());

            if (rstorage.Reservations == null)
            {
                List <FlightInfo> newReservation = new List <FlightInfo> {
                    flightInfo
                };
                rstorage.Reservations = newReservation;
            }
            else
            {
                rstorage.Reservations.Add(flightInfo);
            }
            await _accessor.ReservationStorageAccessor.SetAsync(stepContext.Context, rstorage);

            return(await stepContext.EndDialogAsync());
        }
        /// <summary>
        /// Method to execute the task which is to collect ID of the reservation to be displayed.
        /// </summary>
        /// <param name="stepContext"></param>
        /// <param name="cancellationToken"></param>
        /// <returns>ReservationId TextPrompt</returns>
        private async Task <DialogTurnResult> AskForReservationIdAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            ReservationStorage rstorage = await _accessor.ReservationStorageAccessor.GetAsync(stepContext.Context, () => new ReservationStorage());

            //This block decides if rstorage is not empty and asks for reservation ID.
            if (rstorage.Reservations != null)
            {
                if (rstorage.Reservations.Count > 0)
                {
                    return(await stepContext.PromptAsync("ReservationId", new PromptOptions
                    {
                        Prompt = MessageFactory.Text("Please enter reservation ID.")
                    },
                                                         cancellationToken));
                }
            }
            //Inform user that there is not any reservation to dispaly and end subdialog.
            await stepContext.Context.SendActivityAsync("There is no reservation to display.");

            return(await stepContext.EndDialogAsync());
        }
        /// <summary>
        /// Method to execute the task which is to confirm cancellation action or end dialog.
        /// </summary>
        /// <param name="stepContext"></param>
        /// <param name="cancellationToken"></param>
        /// <returns>End dialog async</returns>
        private async Task <DialogTurnResult> EndShowOneReservationAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            FoundChoice foundChoice = stepContext.Result as FoundChoice;

            //This block decides if dialog should start over, reservation should be cancelled or end.
            if (foundChoice.Value.Equals("Dispaly other reservation", StringComparison.InvariantCultureIgnoreCase))
            {
                return(await stepContext.ReplaceDialogAsync(ShowOneReservationId, null, cancellationToken));
            }
            else if (foundChoice.Value.Contains("Cancel reservation"))
            {
                int flightId = int.Parse(stepContext.Values["RequestID"].ToString());
                //Get ReservationStorage object.
                ReservationStorage rstorage = await _accessor.ReservationStorageAccessor.GetAsync(stepContext.Context, () => new ReservationStorage());

                //Initialize reservation list and assign list of reservations stored in rstorage.
                IList <FlightInfo> reservations = rstorage.Reservations;
                //Initialize reservationInfo variable.
                FlightInfo reservationInfo = new FlightInfo();
                //This block searches suitable reservation ID in the list of reservations using Linq expression.
                var result = from r in reservations
                             where r.ReservationId == flightId
                             select r;
                reservationInfo = result.First();
                //Remove reservation from ResercationStorage object.
                rstorage.Reservations.Remove(reservationInfo);
                await _accessor.ReservationStorageAccessor.SetAsync(stepContext.Context, rstorage);

                //Inform user that reservation has been cancelled.
                await stepContext.Context.SendActivityAsync("Your reservaton has been successfully cancelled.");

                return(await stepContext.EndDialogAsync());
            }
            else
            {
                return(await stepContext.EndDialogAsync());
            }
        }
        /// <summary>
        /// Method to execute the task which is to create adaptive card attachment of the reservation indicated by the user and display it.
        /// </summary>
        /// <param name="stepContext"></param>
        /// <param name="cancellationToken"></param>
        /// <returns>NextAsync</returns>
        private async Task <DialogTurnResult> DisplayReservationAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            //Get ReservationStorage object.
            ReservationStorage rstorage = await _accessor.ReservationStorageAccessor.GetAsync(stepContext.Context, () => new ReservationStorage());

            //Initialize reservation list and assign list of reservations stored in rstorage.
            IList <FlightInfo> reservations = rstorage.Reservations;
            //Get flight ID provided by the user and convert it to integer.
            int flightId = int.Parse(stepContext.Result as string);
            //Initialize reservationInfo variable.
            FlightInfo reservationInfo = new FlightInfo();

            //This block tries to find suitable reservation ID in the list of reservations using Linq expression, if there is not any suitable reservation ID it caches the exception and assigns reservationInfo variable as null.
            try
            {
                var result = from r in reservations
                             where r.ReservationId == flightId
                             select r;
                reservationInfo = result.First();
            }
            catch (Exception e) when(e.Message == "Sequence contains no elements")
            {
                reservationInfo = null;
            };
            //This block decides if reservationInfo is not empty and there is any reservation to display.
            if (reservationInfo != null)
            {
                Attachment attachment = new Attachment();

                // This block decides which adaptive card template should be used based on reservation details.
                if (reservationInfo.OneWayFlight && reservationInfo.Rental == null)
                {
                    attachment = CreateReservationAttachement(@".\Resources\FlightDetailsOneWay.txt", reservationInfo.PassengerName, reservationInfo.FromAirport, reservationInfo.ToAirport, reservationInfo.StartDate, reservationInfo.TripClass, (reservationInfo.FlightCost.ToString() + " $"), reservationInfo.ReservationId.ToString());
                }
                else if (!reservationInfo.OneWayFlight && reservationInfo.Rental == null)
                {
                    attachment = CreateReservationAttachement(@".\Resources\FlightDetailsTwoWays.txt", reservationInfo.PassengerName, reservationInfo.FromAirport, reservationInfo.ToAirport, reservationInfo.StartDate, reservationInfo.TripClass, (reservationInfo.FlightCost.ToString() + " $"), reservationInfo.ReservationId.ToString(), reservationInfo.EndDate);
                }
                else if (reservationInfo.OneWayFlight && reservationInfo.Rental != null)
                {
                    attachment = CreateCombinedAttachement(@".\Resources\FlightDetailsOneWayRental.txt", reservationInfo.PassengerName, reservationInfo.FromAirport, reservationInfo.ToAirport, reservationInfo.StartDate, reservationInfo.TripClass, (reservationInfo.FlightCost.ToString() + " $"), reservationInfo.ReservationId.ToString(), reservationInfo.Rental.RentalLength, reservationInfo.Rental.PassengersNumber, reservationInfo.Rental.ChildSeats, reservationInfo.Rental.CarClass, reservationInfo.Rental.RentalCost);
                }
                else if (!reservationInfo.OneWayFlight && reservationInfo.Rental != null)
                {
                    attachment = CreateCombinedAttachement(@".\Resources\FlightDetailsTwoWaysRental.txt", reservationInfo.PassengerName, reservationInfo.FromAirport, reservationInfo.ToAirport, reservationInfo.StartDate, reservationInfo.TripClass, (reservationInfo.FlightCost.ToString() + " $"), reservationInfo.ReservationId.ToString(), reservationInfo.Rental.RentalLength, reservationInfo.Rental.PassengersNumber, reservationInfo.Rental.ChildSeats, reservationInfo.Rental.CarClass, reservationInfo.Rental.RentalCost, reservationInfo.EndDate);
                }
                ;
                //Initialize reply Activity.
                Activity reply = stepContext.Context.Activity.CreateReply();
                //Add created attachment to the lift of attachments.
                reply.Attachments = new List <Attachment>()
                {
                    attachment
                };
                await stepContext.Context.SendActivityAsync(reply, cancellationToken : cancellationToken);

                //Add flight id provided by user to the stepContext.Values distionary.
                stepContext.Values["RequestID"] = flightId;
            }
            //Inform user that there is not any reservation to dispaly.
            else
            {
                await stepContext.Context.SendActivityAsync("There is not any reservation matching provided ID.");

                //Add default value of request id = 0 to the stepContext.Values distionary.
                stepContext.Values["RequestID"] = 0;
            }

            return(await stepContext.NextAsync());
        }