internal static object CalculateFrom(ValueAccessInfo valueAccessInfo, MethodDefinition methodDefinition, InvokeOutput invocationOutput, EnvironmentInfo environmentInfo, Dictionary <string, string> variablesMap)
        {
            var input = new CompileSQLOperationInput
            {
                MethodDefinition        = methodDefinition,
                MethodParametersInJson  = invocationOutput.InvocationParameters,
                MethodReturnValueInJson = invocationOutput.ExecutionResponseAsJson,
                SQL          = valueAccessInfo.Text.Trim(),
                VariablesMap = variablesMap
            };
            var sqlOperationOutput = CompileSQLOperation(input);

            if (valueAccessInfo.FetchFromDatabase == false)
            {
                if (sqlOperationOutput.SqlParameters.Count == 1)
                {
                    if (input.SQL != sqlOperationOutput.SQL)
                    {
                        return(sqlOperationOutput.SqlParameters[0].Value);
                    }

                    var isNamedParameter = input.SQL == "@output" ||
                                           methodDefinition.Parameters.Any(p => _.IntellisensePrefix + p.Name == input.SQL) ||
                                           variablesMap.ContainsKey(input.SQL);
                    if (isNamedParameter)
                    {
                        return(sqlOperationOutput.SqlParameters[0].Value);
                    }
                }

                return(valueAccessInfo.Text);
            }

            if (string.IsNullOrWhiteSpace(valueAccessInfo.DatabaseName))
            {
                return("Hata: DatabaseName is empty");
            }

            var database = Databases.Boa;

            if (!Enum.TryParse(valueAccessInfo.DatabaseName, true, out database))
            {
                return("Hata: DatabaseName is not recognized." + valueAccessInfo.DatabaseName);
            }

            DataTable sqlToDataTable()
            {
                var boaContext = new BOAContext(environmentInfo, Console.Write);

                var command = boaContext.Context.DBLayer.GetDBCommand(database, sqlOperationOutput.SQL, new SqlParameter[0], CommandType.Text);

                foreach (var item in sqlOperationOutput.SqlParameters)
                {
                    boaContext.Context.DBLayer.AddInParameter(command, item.Name, item.SqlDbType, item.Value);
                }

                var reader = command.ExecuteReader();
                var dt     = new DataTable();

                dt.Load(reader);
                reader.Close();

                boaContext.Dispose();

                return(dt);
            }

            var dataTable = sqlToDataTable();

            if (dataTable.Columns.Count == 1)
            {
                var list = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(dataTable.Columns[0].DataType));

                foreach (DataRow row in dataTable.Rows)
                {
                    list.Add(row[0]);
                }

                if (list.Count == 1)
                {
                    return(list[0]);
                }

                return(list);
            }

            return(dataTable);
        }
        static CompileSQLOperationOutput CompileSQLOperation(CompileSQLOperationInput input)
        {
            var methodDefinition = input.MethodDefinition;

            var allSuggestions = CecilHelper.GetPropertyPathsThatCanBeSQLParameterFromMethodDefinition(methodDefinition);



            var text = input.SQL;

            var sqlParameters = new Dictionary <string, DbParameterInfo>();

            SqlDbType getSqlDbType(object value)
            {
                if (value == null)
                {
                    return(SqlDbType.VarChar);
                }

                var typeMap = new Dictionary <Type, SqlDbType>
                {
                    [typeof(string)]         = SqlDbType.NVarChar,
                    [typeof(char[])]         = SqlDbType.NVarChar,
                    [typeof(byte)]           = SqlDbType.TinyInt,
                    [typeof(short)]          = SqlDbType.SmallInt,
                    [typeof(int)]            = SqlDbType.Int,
                    [typeof(long)]           = SqlDbType.BigInt,
                    [typeof(byte[])]         = SqlDbType.Image,
                    [typeof(bool)]           = SqlDbType.Bit,
                    [typeof(DateTime)]       = SqlDbType.DateTime2,
                    [typeof(DateTimeOffset)] = SqlDbType.DateTimeOffset,
                    [typeof(decimal)]        = SqlDbType.Money,
                    [typeof(float)]          = SqlDbType.Real,
                    [typeof(double)]         = SqlDbType.Float,
                    [typeof(TimeSpan)]       = SqlDbType.Time
                };

                var type = value.GetType();

                // Allow nullable types to be handled
                type = Nullable.GetUnderlyingType(type) ?? type;

                if (typeMap.ContainsKey(type))
                {
                    return(typeMap[type]);
                }

                return(SqlDbType.Structured);
            }

            void processSimpleSuggestion(string name, Func <object> getValue)
            {
                var prefix = IntellisensePrefix + name;

                if (!text.Contains(prefix))
                {
                    return;
                }

                var isComplex = text.Contains(IntellisensePrefix + name + ".");

                if (isComplex)
                {
                    return;
                }

                var key = name;

                if (sqlParameters.ContainsKey(key))
                {
                    return;
                }

                var value     = getValue();
                var parameter = new DbParameterInfo
                {
                    Name      = key,
                    Value     = value,
                    SqlDbType = getSqlDbType(value)
                };

                sqlParameters.Add(key, parameter);
            }

            void processComplexSuggestion(string name, Func <object> getValue)
            {
                var prefix = IntellisensePrefix + name + ".";

                var suggestions = from x in allSuggestions
                                  where x.StartsWith(prefix)
                                  orderby x.Length descending
                                  select x;



                void processSuggestion(string suggestion)
                {
                    if (!text.Contains(suggestion))
                    {
                        return;
                    }

                    var propertyPath = suggestion.RemoveIfStartsWith(prefix);

                    var key = suggestion.Replace(".", "_");

                    text = text.Replace(suggestion, key);

                    var value = getValue();

                    var sqlValue = ReflectionUtil.ReadPropertyPath(value, propertyPath);

                    var parameter = new DbParameterInfo
                    {
                        Name      = key,
                        Value     = sqlValue,
                        SqlDbType = getSqlDbType(sqlValue)
                    };

                    sqlParameters.Add(key, parameter);
                }

                foreach (var suggestion in suggestions)
                {
                    processSuggestion(suggestion);
                }
            }

            foreach (var parameterDefinition in methodDefinition.Parameters)
            {
                var parameterName = parameterDefinition.Name;

                object getParameterValue()
                {
                    var json = input.MethodParametersInJson[parameterDefinition.Index];

                    if (json == null)
                    {
                        return(null);
                    }

                    return(DeserializeForMethodParameter(json, parameterDefinition.ParameterType.GetDotNetType()));
                }

                processSimpleSuggestion(parameterName, getParameterValue);
                processComplexSuggestion(parameterName, getParameterValue);
            }

            if (!IsVoidMethod(methodDefinition))
            {
                object getReturnValue()
                {
                    return(DeserializeForMethodParameter(input.MethodReturnValueInJson, GetTypeReference(methodDefinition.ReturnType).GetDotNetType()));
                }

                processSimpleSuggestion("output", getReturnValue);
                processComplexSuggestion("output", getReturnValue);
            }

            foreach (var pair in input.VariablesMap)
            {
                processSimpleSuggestion(pair.Key.RemoveFromStart(IntellisensePrefix), () => pair.Value);
            }


            return(new CompileSQLOperationOutput
            {
                SQL = text,
                SqlParameters = sqlParameters.Values.ToList()
            });
        }