private OffsetDateTime CreateUpdatedOffsetDateTimeFromTokens(OffsetDateTime existingOffsetDateTime, DateToken dateToken, TimeToken timeToken)
        {
            var existingLocalDateTime = existingOffsetDateTime.LocalDateTime;
            var day = existingLocalDateTime.Day;
            var month = existingLocalDateTime.Month;
            var year = existingLocalDateTime.Year;
            if (dateToken != null)
            {
                if (dateToken.Day.HasValue) day = dateToken.Day.Value;
                if (dateToken.Month.HasValue) month = dateToken.Month.Value;
                if (dateToken.Year.HasValue) year = dateToken.Year.Value;
            }
            var hour = 12;
            var minute = 0;
            if (timeToken != null)
            {
                hour = timeToken.Hour;
                if (timeToken.Meridiem == Meridiem.AM && hour == 12) hour = 0;
                if (timeToken.Meridiem == Meridiem.PM && hour < 12) hour += 12;
                minute = timeToken.Minute ?? 0;
            }

            try
            {
                return new LocalDateTime(year, month, day, hour, minute).WithOffset(existingOffsetDateTime.Offset);
            }
            catch (ArgumentOutOfRangeException)
            {
                throw new InvalidTokenValueException(ErrorMessages.InvalidDateTime);
            }
        }
        private Answer GetAnswerToTimeConversionQuestion(Question question, DateToken knownDateToken, TimeToken knownTimeToken, CityOrTimezoneToken  knownCityOrTimezone, CityOrTimezoneToken  unknownCityOrTimezone)
        {
            var knownEntityOffsetDateTime = CreateUpdatedOffsetDateTimeFromTokens(knownCityOrTimezone.GetCurrentTimeAsOffsetDateTime(), knownDateToken, knownTimeToken);
            Instant knownCityOrTimezoneInstant;
            String note = null;
            if (knownCityOrTimezone.GetType() == typeof(CityToken))
            {
                var cityToken = (CityToken)knownCityOrTimezone;
                ZoneLocalMapping knownCityOrTimezoneZoneLocalMapping = DateTimeZoneProviders.Tzdb[cityToken.City.Timezone].MapLocal(knownEntityOffsetDateTime.LocalDateTime);
                if (knownCityOrTimezoneZoneLocalMapping.Count == 1)
                {
                    knownCityOrTimezoneInstant = knownCityOrTimezoneZoneLocalMapping.Single().ToInstant();
                }
                else if (knownCityOrTimezoneZoneLocalMapping.Count > 1)
                {
                    knownCityOrTimezoneInstant = knownCityOrTimezoneZoneLocalMapping.First().ToInstant();
                    note = String.Format("In {0} the time {1} occurs twice due to daylight saving time changes when clocks are put back, we are using the first occurance of that time.",
                        cityToken.City.FormattedName,
                        knownEntityOffsetDateTime.LocalDateTime.GetFormattedTimeAndDate());
                }
                else
                {
                    knownCityOrTimezoneInstant = knownCityOrTimezoneZoneLocalMapping.LateInterval.Start.WithOffset(knownCityOrTimezoneZoneLocalMapping.LateInterval.WallOffset).ToInstant();
                    note = String.Format("In {0} the time {1} does not occur due to daylight saving time changes when clocks are put forward, we are using the next valid time.",
                        cityToken.City.FormattedName,
                        knownEntityOffsetDateTime.LocalDateTime.GetFormattedTimeAndDate());
                }
            }
            else if (knownCityOrTimezone.GetType() == typeof(TimezoneToken))
            {
                var timezoneToken = (TimezoneToken)knownCityOrTimezone;
                knownCityOrTimezoneInstant = knownEntityOffsetDateTime.LocalDateTime.WithOffset(timezoneToken.Timezone.Offset).ToInstant();
            }
            else
            {
                throw new NotImplementedException();
            }

            var answerText = String.Format("It is {0} in {1} when it is {2} in {3}",
                                            unknownCityOrTimezone.GetLocalDateTime(knownCityOrTimezoneInstant).GetFormattedTimeAndDate(),
                                            unknownCityOrTimezone.GetFormattedNameAndTimezone(knownCityOrTimezoneInstant),
                                            knownEntityOffsetDateTime.LocalDateTime.GetFormattedTimeAndDate(),
                                            knownCityOrTimezone.GetFormattedNameAndTimezone(knownEntityOffsetDateTime.ToInstant()));

            var answer = new Answer(question, true, true, answerText);
            answer.Note = note;
            return answer;
        }