private static CoreLogic.Expressions.Expression ConvertModelToExpression(
            Models.Expression expressionModel,
            IEnumerable<CoreLogic.Parameter> inputVariables
        )
        {
            if (expressionModel.type == EXPR_CONJUNCTION)
            {
                var left = ConvertModelToExpression(expressionModel.left, inputVariables);
                var right = ConvertModelToExpression(expressionModel.right, inputVariables);
                return new CoreLogic.Expressions.Conjunction(left, right);
            }
            else if (expressionModel.type == EXPR_DISJUNCTION)
            {
                var left = ConvertModelToExpression(expressionModel.left, inputVariables);
                var right = ConvertModelToExpression(expressionModel.right, inputVariables);
                return new CoreLogic.Expressions.Disjunction(left, right);
            }
            else if (expressionModel.type == EXPR_NEGATION)
            {
                var argument = ConvertModelToExpression(expressionModel.arg, inputVariables);
                return new CoreLogic.Expressions.Negation(argument);
            }
            else if (expressionModel.type == EXPR_STATEMENT)
            {
                var parameter = inputVariables.FirstOrDefault(p => p.Name == expressionModel.var_name);
                if (parameter == null)
                {
                    throw new ArgumentException($"A statement references a non-existing input variable {expressionModel.var_name}.");
                }

                var clazz = parameter.Classes.FirstOrDefault(c => c.Name == expressionModel.class_name);
                if (clazz == null)
                {
                    throw new ArgumentException($"A statement references a non-existing input variable's class {expressionModel.class_name}.");
                }

                return new CoreLogic.Expressions.MembershipStatement(parameter, clazz);
            }
            else
            {
                throw new ArgumentException($"Attempt to handle an unknown type: {expressionModel.GetType().FullName}.");
            }
        }
        private static Models.Expression ConvertExpressionToModel(CoreLogic.Expressions.Expression expression)
        {
            var expressionModel = new Models.Expression();

            if (expression is CoreLogic.Expressions.Conjunction)
            {
                expressionModel.type = EXPR_CONJUNCTION;
                var conjunction = expression as CoreLogic.Expressions.Conjunction;
                expressionModel.left = ConvertExpressionToModel(conjunction.LeftArgument);
                expressionModel.right = ConvertExpressionToModel(conjunction.RightArgument);
            }
            else if (expression is CoreLogic.Expressions.Disjunction)
            {
                expressionModel.type = EXPR_DISJUNCTION;
                var disjunction = expression as CoreLogic.Expressions.Disjunction;
                expressionModel.left = ConvertExpressionToModel(disjunction.LeftArgument);
                expressionModel.right = ConvertExpressionToModel(disjunction.RightArgument);
            }
            else if (expression is CoreLogic.Expressions.Negation)
            {
                expressionModel.type = EXPR_NEGATION;
                var negation = expression as CoreLogic.Expressions.Negation;
                expressionModel.arg = ConvertExpressionToModel(negation.Argument);
            }
            else if (expression is CoreLogic.Expressions.MembershipStatement)
            {
                expressionModel.type = EXPR_STATEMENT;
                var statement = expression as CoreLogic.Expressions.MembershipStatement;
                expressionModel.var_name = statement.Parameter.Name;
                expressionModel.class_name = statement.Class.Name;
            }
            else
            {
                throw new ArgumentException($"Attempt to handle an unknown type: {expression.GetType().FullName}.");
            }

            return expressionModel;
        }