public async Task <State> GetNextUserStateAsync(UserContext userContext, State lastState, BotFlow botFlow) { var nextStateId = lastState.DefaultOutput.StateId; foreach (var outputCondition in lastState.OutputConditions) { var matchCondition = await outputCondition.Conditions.AllAsync(async o => { string toCompare = default; switch (o.Source) { case ConditionSource.Input: toCompare = (await _variableService.GetVariableValueAsync("input", userContext)).ToString(); break; case ConditionSource.Context: toCompare = await _variableService.ReplaceVariablesInStringAsync(o.Variable, userContext); break; case ConditionSource.Intent: toCompare = (await userContext.NlpResponse)?.Intent?.IntentName; break; case ConditionSource.Entity: toCompare = (await userContext.NlpResponse)?.Entities?[o.Entity]; break; } var comparisonType = _comparisonService.GetComparisonType(o.Comparison); switch (comparisonType) { case ComparisonType.Unary: var unaryComparer = _comparisonService.GetUnaryConditionComparator(o.Comparison); return(unaryComparer(toCompare)); case ComparisonType.Binary: var binaryComparer = _comparisonService.GetBinaryConditionComparator(o.Comparison); return(o.Values.Any(v => binaryComparer(toCompare, v))); } return(false); }); if (matchCondition) { nextStateId = outputCondition.StateId; break; } } return(botFlow.States[nextStateId] ?? botFlow.States.Single(x => x.Value.IsRoot).Value); }