@Override
	protected NodeValue exec(Node[] nodes, FunctionEnv env, SPINModuleRegistry registry) {
		
		Model baseModel = ModelFactory.createModelForGraph(env.getActiveGraph());
		Node exprNode = nodes[0];
		if(exprNode == null) {
			throw new ExprEvalException("No expression specified");
		}
		else if(exprNode.isLiteral()) {
			return NodeValue.makeNode(exprNode);
		}
		else {
			Model model = baseModel;
			if(!model.contains(SPIN._arg1, RDF.type, SP.Variable)) {
				MultiUnion multiUnion = new MultiUnion(new Graph[] {
						env.getActiveGraph(),
						SPIN.getModel().getGraph()
				});
				model = ModelFactory.createModelForGraph(multiUnion);
			}
			Resource exprRDFNode = (Resource) model.asRDFNode(exprNode);
			QuerySolutionMap bindings = getBindings(nodes, model);
			org.topbraid.spin.model.Query spinQuery = SPINFactory.asQuery((Resource)exprRDFNode);
			if(spinQuery instanceof Select || spinQuery instanceof Ask) {
				Query query = ARQFactory.get().createQuery((org.topbraid.spin.model.Query)spinQuery, registry);
				QueryExecution qexec = ARQFactory.get().createQueryExecution(query, model, bindings);
				if(query.isAskType()) {
					boolean result = qexec.execAsk();
					return NodeValue.makeBoolean(result);
				}
				else {
					ResultSet rs = qexec.execSelect();
					String var = rs.getResultVars().get(0);
					if(rs.hasNext()) {
						RDFNode r = rs.next().get(var);
						qexec.close();
						if(r != null) {
							return NodeValue.makeNode(r.asNode());
						}
					}
				}
			}
			else {
				RDFNode expr = SPINFactory.asExpression(exprRDFNode);
				RDFNode result = SPINExpressions.evaluate((Resource) expr, model, bindings, registry);
				if(result != null) {
					return NodeValue.makeNode(result.asNode());
				}
			}
			throw new ExprEvalException("Expression has no result");
		}
	}