diff --git a/com.oracle.truffle.r.pkgs/graalvm/DESCRIPTION b/com.oracle.truffle.r.pkgs/graalvm/DESCRIPTION
new file mode 100644
index 0000000000000000000000000000000000000000..895818a9a3229e5f0ada80f3385e70e6fc44d91d
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/DESCRIPTION
@@ -0,0 +1,12 @@
+Package: graalvm
+Type: Package
+Title: GraalVM integration with GNUR
+Version: 1.0
+Date: 2017-04-06
+Author: Zbynek Slajchrt
+Maintainer: Zbynek Slajchrt <zbynek.slajchrt@oracle.com>
+Copyright: Oracle
+Description: It demonstrates FastR performance and polyglot capabilities of GraalVM to GNUR users.
+License: GPL-2
+Depends: curl, jsonlite
+RoxygenNote: 6.0.1
diff --git a/com.oracle.truffle.r.pkgs/graalvm/NAMESPACE b/com.oracle.truffle.r.pkgs/graalvm/NAMESPACE
new file mode 100644
index 0000000000000000000000000000000000000000..ce77a622a17c051ab5db2fc4bf8b50183bda16e3
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/NAMESPACE
@@ -0,0 +1,17 @@
+# Generated by roxygen2: do not edit by hand
+
+export(g)
+export(g.js)
+export(g.r)
+export(g.rb)
+export(gget)
+export(gget.js)
+export(gget.r)
+export(gget.rb)
+export(graalvm.setup)
+export(graalvm.start)
+export(graalvm.stop)
+export(gset)
+export(gset.js)
+export(gset.r)
+export(gset.rb)
diff --git a/com.oracle.truffle.r.pkgs/graalvm/R/g.R b/com.oracle.truffle.r.pkgs/graalvm/R/g.R
new file mode 100644
index 0000000000000000000000000000000000000000..11190d265a2eae66b34b16136912e434a2645e2c
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/R/g.R
@@ -0,0 +1,337 @@
+##
+ # Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License version 2 only, as
+ # published by the Free Software Foundation.
+ #
+ # This code is distributed in the hope that it will be useful, but WITHOUT
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ # version 2 for more details (a copy is included in the LICENSE file that
+ # accompanied this code).
+ #
+ # You should have received a copy of the GNU General Public License version
+ # 2 along with this work; if not, write to the Free Software Foundation,
+ # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ #
+ # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ # or visit www.oracle.com if you need additional information or have any
+ # questions.
+##
+
+graalvmEnv <- new.env(parent = emptyenv())
+graalvmEnv$status <- FALSE
+
+graalvm.status <- function() {
+	graalvmEnv$status
+}
+
+#' Set up the GraalVM agent
+#'
+#' @param home The home folder of the GraalVM installation
+#' @param host The local host name at which the GraalVM agent is listening
+#' @param port The port at which the GraalVM agent is listening
+#' @param rlibs The value of the FastR R_LIBS environmental variable. The default 
+#' value is calculated as paste0(graalvm.home, "/language/R/library").
+#' @examples
+#' graalvm.setup("~/work/graalvm-0.21")
+#' @export
+graalvm.setup <- function(home, host = "localhost", port = 9876, rlibs = paste0(home, "/language/R/library")) {
+	options(graalvm.home = home, graalvm.host = host, graalvm.port = port, graalvm.rlibs = rlibs)
+}
+
+commandURL <- function(cmd) {
+	gHost <- getOption("graalvm.host");
+	gPort <- getOption("graalvm.port");
+	sprintf("http://%s:%d/%s", gHost, gPort, cmd)
+}
+
+ping <- function() {
+	pingURL <- commandURL("ping")
+	tryCatch({ suppressWarnings(readLines(pingURL, warn=FALSE)); TRUE }, error = function(e) FALSE)
+}
+
+#' Start the GraalVM agent. The agent is normally started automatically upon the first
+#' code ecxecution.
+#' @export
+graalvm.start <- function() {
+	if (!ping()) {
+		graalvmEnv$status <- FALSE
+		gHome <- getOption("graalvm.home");
+		if (is.null(gHome)) stop("No GraalVM home configured. Use graalvm.setup() to specify it.")
+
+		serverScriptPath <- attr(packageDescription("graalvm"), "file")
+		serverScriptPath <-	substr(serverScriptPath, 1, nchar(serverScriptPath)-16)
+		serverScriptPath <- paste0(serverScriptPath, "data/server.js")
+	
+		libEnvVar <- paste0("R_LIBS=", getOption("graalvm.rlibs"))
+	
+		gHost <- getOption("graalvm.host");
+		gPort <- getOption("graalvm.port");
+	
+		nodeLaunchCmd <- paste0(libEnvVar, " ", gHome, "/bin/node ", serverScriptPath, " ", gHost, " ", gPort, " &")
+		system(nodeLaunchCmd, ignore.stdout = TRUE, ignore.stderr = TRUE)
+	
+		attempts <- 0L
+		while(!ping()) {
+			Sys.sleep(1)
+			attempts <- attempts + 1L
+			if (attempts >= 30) stop("Cannot launch GraalVM agent")
+		}
+
+		graalvmEnv$status <- TRUE
+	} 
+	
+	# register the function stopping the agent on exit
+	prevLast <- NULL
+	if (exists(".Last")) {
+		prevLast <- .Last
+	}
+	.Last <<- function() {
+		tryCatch(graalvm::graalvm.stop(), error = function(e) print(e))
+		# invoke the previous callback if any
+		if (!is.null(prevLast)) prevLast()
+	}
+	TRUE
+}
+
+#' Stop the GraalVM agent.
+#' @export
+graalvm.stop <- function() {
+	tryCatch({ 
+		suppressWarnings(readLines(commandURL("stop"), warn=FALSE))
+		graalvmEnv$status <- FALSE
+		TRUE
+	}, error = function(e) FALSE)
+}
+
+#' Execute code by GraalVM using the language interpreter that corresponds
+#' to the language mimetype.
+#'
+#' @param code the code to be executed. It must be a language element as long as the target
+#' language is R, otherwise it must be a string.
+#' @param echo controls whether this function returns the result of the interpreted code.
+#' The default value is TRUE.
+#' @param mimetype The mimetype of the target language. Currently supported values are
+#' "application/x-r", "text/javascript" and "application/x-ruby".
+#' @family execution functions
+#' @examples
+#' g(runif(10^3))
+#' g(runif(10^8), echo = FALSE) # We do not want that the result is returned due to its size
+#' g("1 < 2", mimetype = "text/javascript")
+#' @export
+g <- function(code, echo = TRUE, mimetype = "application/x-r") {
+	if (mimetype == "application/x-r") {
+		code <- deparse(substitute(code))
+	} else {
+		if (!is.character(code)) stop("The code argument must a character vector")
+	}
+	send(code, echo, mimetype)
+}
+
+#' Execute R code.
+#' @examples
+#' g.r("runif(10^3)")
+#' @family execution functions
+#' @export
+g.r <- function(code, echo = TRUE) {
+	if (!is.character(code)) stop("The code argument must a character vector")
+	send(code, echo, "application/x-r")
+}
+
+#' Execute JavaScript code.
+#' @examples
+#' g.js("1 < 2")
+#' @family execution functions
+#' @export
+g.js <- function(code, echo = TRUE) {
+	if (!is.character(code)) stop("The code argument must a character vector")
+	send(code, echo, "text/javascript")
+}
+
+#' Execute Ruby code.
+#' @examples
+#' g.rb("1 < 2")
+#' @family execution functions
+#' @export
+g.rb <- function(code, echo = TRUE) {
+	if (!is.character(code)) stop("The code argument must a character vector")
+	send(code, echo, "application/x-ruby")
+}
+
+#' Assign a value to a paired variable. The value is assigned both locally and remotely.
+#' The local variable must have been initialized by one of the language specific gget.* or
+#' ggset.* functions.
+#' 
+#' @family paired variables
+#' @examples
+#' # Create and initialize a variable in JS
+#' g.js("a = 1")
+#' # Pick up the a variable from JS and define its counterpart in GNUR
+#' gget.js(a)
+#' a
+#' # Increment the variable both locally and in JS 
+#' gset(a, a + 1)
+#' a
+#' g.js("a[0]")
+#' g.js("a[1] = 10")
+#' gget(a)
+#' a
+#' @export
+gset <- function(var, value = var) {
+	varName <- deparse(substitute(var))
+	if (exists(varName)) {
+		meta <- attr(var, "graalvm")
+		if (is.null(meta)) {
+			stop(paste("Unpaired variable ", varName))
+		}
+		deparsedValue = NULL
+		if (meta$mimetype == "application/x-r") {
+			deparsedValue <- paste(deparse(substitute(value)), collapse="\n")
+		}
+		setVar(varName, value, deparsedValue, meta$mimetype)
+	} else {
+		stop(paste("Undefined variable ", varName))
+	}
+}
+
+#' Assign the value to the paired variable in Graal FastR and locally.
+#'
+#' @family paired variables
+#' @export
+gset.r <- function(var, value) setVar(deparse(substitute(var)), value, paste(deparse(substitute(value)), collapse="\n"), "application/x-r")
+
+#' Assign the value to the paired variable in Graal JS and locally.
+#'
+#' @family paired variables
+#' @export
+gset.js <- function(var, value) setVar(deparse(substitute(var)), value, NULL, "text/javascript")
+
+#' Assign the value to the paired variable in Graal Ruby and locally.
+#'
+#' @family paired variables
+#' @export
+gset.rb <- function(var, value) setVar(deparse(substitute(var)), value, NULL, "application/x-ruby")
+
+#' Retrieve the variable defined in a GraalVM language. The local variable must have been 
+#' initialized by one of the language specific gget.* or ggset.* functions.
+#' 
+#' @family paired variables
+#' @export
+gget <- function(var) {
+	varName <- deparse(substitute(var))
+	if (exists(varName)) {
+		meta <- attr(var, "graalvm")
+		if (is.null(meta)) {
+			stop(paste("Unpaired variable ", varName))
+		}
+		getVar(varName, meta$mimetype) 
+	} else {
+		stop(paste("Undefined variable ", varName))
+	}
+}
+
+#' Retrieve the variable defined in GraalVM FastR.
+#'
+#' @family paired variables
+#' @export
+gget.r <- function(var) getVar(deparse(substitute(var)), "application/x-r")
+
+#' Retrieve the variable defined in GraalVM JS.
+#'
+#' @family paired variables
+#' @export
+gget.js <- function(var) getVar(deparse(substitute(var)), "text/javascript")
+
+#' Retrieve the variable defined in GraalVM Ruby.
+#'
+#' @family paired variables
+#' @export
+gget.rb <- function(var) getVar(deparse(substitute(var)), "application/x-ruby")
+
+setVar <- function(varName, value, deparsedValue, mimetype="application/x-r") {
+	localValue <- value
+	meta <- NULL
+	if (exists(varName)) {
+		meta <- attr(var, "graalvm")
+	} 
+	if (is.null(meta)) {
+		meta <- list(varName = varName, mimetype = mimetype)
+		attr(localValue, "graalvm") <- meta
+	}
+	if (meta$mimetype == "application/x-r") {
+		code <- paste0(meta$varName, "<-", deparsedValue) 
+	} else if (meta$mimetype == "text/javascript") {
+		code <- paste0(meta$varName, "=", toJSON(value)) 
+	} else if (meta$mimetype == "application/x-ruby") {
+		code <- paste0("$", meta$varName, "=", toJSON(value))
+	} else {
+		stop(paste("Unsupported language mimetype:", mimetype))
+	}
+	send(code, FALSE, meta$mimetype)
+	
+	assign(varName, localValue, inherits = TRUE)
+}
+
+getVar <- function(varName, mimetype="application/x-r") {
+	meta <- NULL
+	if (exists(varName)) {
+		meta <- attr(var, "graalvm")
+	} 
+	if (is.null(meta)) {
+		meta <- list(varName = varName, mimetype = mimetype)
+	}
+	if (meta$mimetype == "application/x-r") {
+		code <- meta$varName 
+	} else if (meta$mimetype == "text/javascript") {
+		code <- meta$varName 
+	} else if (meta$mimetype == "application/x-ruby") {
+		code <- paste0("$", meta$varName)
+	} else {
+		stop(paste("Unsupported language mimetype:", mimetype))
+	}
+	value <- send(code, TRUE, meta$mimetype)
+	
+	if (!is.null(value)) {
+		meta <- list("varName" = varName, "mimetype" = mimetype)
+		attr(value, "graalvm") <- meta
+	}
+	
+	assign(varName, value, inherits = TRUE)
+}
+
+send <- function(code, echo, mimetype) {
+	tryCatch(sendAttempt(code, echo, mimetype), error = function(e) {
+		# try to restart the agent and invoke it agains
+		graalvm.start()
+		sendAttempt(code, echo, mimetype)
+	})	
+}
+
+sendAttempt <- function(code, echo, mimetype) {
+	code <- paste(code, collapse="\n")
+	if (!graalvmEnv$status) {
+		graalvm.start()
+	}
+	h <- new_handle(failonerror = FALSE)
+	handle_setform(h, code=code, echo=as.character(echo), mimetype=mimetype)
+	url <- commandURL("")
+	resp <- curl_fetch_memory(url, handle = h)
+	respData <- rawToChar(resp$content)
+	respData <- strsplit(respData, "\r\n")[[1]]
+	if (mimetype == "application/x-r") {
+		respObj <- eval(parse(text=respData))
+	} else if (mimetype == "text/javascript") {
+		respObj <- fromJSON(respData)
+	} else if (mimetype == "application/x-ruby") {
+		respObj <- fromJSON(respData)
+	}
+	
+	if (resp$status_code >= 400) {
+		stop(respObj)
+	} else {
+		respObj
+	}
+}
diff --git a/com.oracle.truffle.r.pkgs/graalvm/R/graalvm.R b/com.oracle.truffle.r.pkgs/graalvm/R/graalvm.R
new file mode 100644
index 0000000000000000000000000000000000000000..2c6c4b66e7195f7e6c09c8bb991b06269e8a5044
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/R/graalvm.R
@@ -0,0 +1,53 @@
+#' GraalVM R package is supposed to demonstrate FastR performance and polyglot capabilities 
+#' of GraalVM to GNUR users.
+#'
+#' @name graalvm
+#' @examples
+#' # Loading and setting up
+#' 
+#' library(graalvm)
+#' graalvm.setup("~/work/graalvm-0.21")
+#' 
+#' # Code execution
+#' g(v <- runif(1e8))
+#' g(f <- function(x) { s <- 0; for (i in seq_along(x)) s <- s + x[[i]]; s })
+#' g(system.time(f(v)))
+#' g(system.time(f(v)))
+#' 
+#' g.js("1 < 2")
+#' g.rb("$a = 2")
+#' 
+#' 
+#' # Paired variables
+#' 
+#' # Create and initialize paired variables:
+#' gset.r(a1, TRUE) 
+#' gset.js(a2, c(1,2))
+#' gset.rb(a3, list(a=1,b="2")) 
+#' a1
+#' a2
+#' a3
+#' g.r("a1")
+#' g.js("a2")
+#' g.rb("$a3")
+#' 
+#' g(a1 <- FALSE)
+#' gget(a1)
+#' a1
+#' 
+#' # Paired functions
+#' 
+#' # Create a paired function
+#' gset.r(measure, function(n) { system.time(runif(n)) })
+#' # Execute the local version of the paired function
+#' measure(1e8)
+#' # Execute the remote version of the paired function
+#' g(measure(1e8))
+#' 
+#' # Executing a script file
+#' 
+#' tmp <- tempfile()
+#' writeLines(con = tmp, c("x<-10", "y<-x^2", "y"))
+#' g.r(readLines(con=tmp))
+#'
+NULL
diff --git a/com.oracle.truffle.r.pkgs/graalvm/data/handler.fr b/com.oracle.truffle.r.pkgs/graalvm/data/handler.fr
new file mode 100644
index 0000000000000000000000000000000000000000..d45d981de98a86d042f881a5e5d44ca06a9572e2
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/data/handler.fr
@@ -0,0 +1,44 @@
+##
+ # Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License version 2 only, as
+ # published by the Free Software Foundation.
+ #
+ # This code is distributed in the hope that it will be useful, but WITHOUT
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ # version 2 for more details (a copy is included in the LICENSE file that
+ # accompanied this code).
+ #
+ # You should have received a copy of the GNU General Public License version
+ # 2 along with this work; if not, write to the Free Software Foundation,
+ # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ #
+ # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ # or visit www.oracle.com if you need additional information or have any
+ # questions.
+##
+
+inp <- NULL
+out <- NULL
+err <- FALSE
+
+parser <- function(expr) {
+	# The expression is temporarily put into the block due to a bug in the FastR that is
+	# bundled into GraalVM 0.21, which causes that the expression eval(parse(text="x")) fails.
+	# The bug is already fixed in the newest version of FastR.
+	exp <<- parse(text = paste0("{", expr, "}"))
+}
+
+deparseObject <- function(obj) paste(deparse(obj), collapse = "\r\n")
+
+result <- function() deparseObject(out)
+
+isError <- function() err
+
+.fastr.interop.export('parser', parser)
+.fastr.interop.export('deparseObject', deparseObject)
+.fastr.interop.export('result', result)
+.fastr.interop.export('isError', isError)
diff --git a/com.oracle.truffle.r.pkgs/graalvm/data/handler.rb b/com.oracle.truffle.r.pkgs/graalvm/data/handler.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4189fed1626f53334576d32e2feaf7d55d5af30b
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/data/handler.rb
@@ -0,0 +1,37 @@
+=begin
+ Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.
+
+ This code is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ version 2 for more details (a copy is included in the LICENSE file that
+ accompanied this code).
+
+ You should have received a copy of the GNU General Public License version
+ 2 along with this work; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ or visit www.oracle.com if you need additional information or have any
+ questions.
+=end
+
+require 'json'
+
+$expr = ""
+
+def storeExpr(e)
+	$expr = Truffle::Interop.from_java_string(e)
+end
+
+def toJSON(res)
+	Truffle::Interop.to_java_string(res.to_json)
+end
+
+Truffle::Interop.export('storeExpr', method(:storeExpr))
+Truffle::Interop.export('rubyToJSON', method(:toJSON))
\ No newline at end of file
diff --git a/com.oracle.truffle.r.pkgs/graalvm/data/server.js b/com.oracle.truffle.r.pkgs/graalvm/data/server.js
new file mode 100644
index 0000000000000000000000000000000000000000..0e3604a98a1bb9be7897c69ef71b6e478c387edf
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/data/server.js
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+var fs = require('fs');
+var http = require("http");
+
+function parseParams(body) {
+	var lines = body.split('\r\n');
+	var paramName = null;
+	var paramValue = "";
+	var params = {};
+	for(var i = 0; i < lines.length; i++) {
+		if (lines[i].startsWith("--------------------------")) {
+			if (paramName != null) {
+				params[paramName] = paramValue;
+				paramName = null;
+				paramValue = "";
+			}
+			continue;
+		}
+		if (lines[i].startsWith("Content-Disposition:")) {
+			paramName = lines[i].split('=')[1];
+			paramName = paramName.substring(1, paramName.length - 1);
+			i++;
+			continue;
+		}
+		if (lines[i] === "") {
+			continue;
+		}
+		paramValue += lines[i];
+	}
+	
+	return params;
+}
+
+function evalJS(code, echo) {
+	//console.log("Executing JS code: '" + code + "'");
+	var res = {}; 
+	try {
+		r = eval(code)
+		res.isError = false;
+		if (echo) {
+			res.data = JSON.stringify(r);
+		} else {
+			res.data = JSON.stringify(null);
+		}
+	} catch (error) {
+		//console.log("Caught error:" + JSON.stringify(error));
+		res.isError = true;
+		res.data = "" + error;
+	}
+	return res;
+}
+
+var rHandlerScript = fs.readFileSync( __dirname + "/handler.fr", "utf8");
+Interop.eval("application/x-r", rHandlerScript);
+
+rParser = Interop.import('parser');
+rResult = Interop.import('result');
+rIsError = Interop.import('isError');
+deparseObject = Interop.import('deparseObject');
+
+function evalR(code, echo) {
+	rParser(code);
+	if (echo) {
+		Interop.eval("application/x-r", "err <- TRUE; out <- tryCatch({ err <- TRUE; r <- eval(exp); err <- FALSE; r }, error = function(e) e$message)");
+	} else {
+		Interop.eval("application/x-r", "err <- TRUE; out <- tryCatch({ err <- TRUE; eval(exp); err <- FALSE; NULL }, error = function(e) e$message)");
+	}
+	var res = {}
+	res.data = rResult();
+	res.isError = rIsError();
+	return res;
+}
+
+var rubyHandlerScript = fs.readFileSync( __dirname + "/handler.rb", "utf8");
+Interop.eval("application/x-ruby", rubyHandlerScript);
+rubyStoreExpr = Interop.import('storeExpr');
+rubyToJSON = Interop.import('rubyToJSON');
+
+function evalRuby(code, echo) {
+	rubyStoreExpr(code);
+	var r;
+	code = `begin
+		eval($expr)
+	rescue Exception => exc
+		-1
+	end`;
+	if (echo) {
+		r = Interop.eval("application/x-ruby", code);
+	} else {
+		r = Interop.eval("application/x-ruby", code);
+	}
+	var res = {}
+	rJSON = rubyToJSON(r);
+	//console.log("Result from Ruby:" + rJSON);
+	res.data = rJSON;
+	res.isError = false;
+	return res;
+}
+
+function processPost(request, response) {
+    var queryData = "";
+
+    if(request.method == 'POST') {
+        request.on('data', function(data) {
+            queryData += data;
+            if(queryData.length > 1e6) {
+                queryData = "";
+                response.writeHead(413, {'Content-Type': 'text/plain'}).end();
+                request.connection.destroy();
+            }
+        });
+
+        request.on('end', function() {
+        	var params = parseParams(queryData);
+			//console.log("Params: " + JSON.stringify(params));
+        	var echo = params.echo === "TRUE";
+        	var res;
+        	if (params.mimetype == "application/x-r") {
+	        	res = evalR(params.code, echo);
+			} else if (params.mimetype == "text/javascript") {
+	        	res = evalJS(params.code, echo);
+			} else if (params.mimetype == "application/x-ruby") {
+	        	res = evalRuby(params.code, echo);
+	      	} else {
+        		res = {
+        			isError : true,
+        			data : deparseObject("Unsupported language: " + params.mimetype)
+        		}
+        	}
+			if (res.isError) {
+				response.writeHead(400, {'Content-Type': 'text/plain'});
+			} else {
+				response.writeHead(200, "OK", {'Content-Type': 'text/plain'});
+			}
+			response.end(res.data);
+
+        });
+
+    } else {
+        response.writeHead(405, {'Content-Type': 'text/plain'});
+        response.end();
+    }
+}
+
+// Launch the server
+console.log("Starting GraalVM agent...");
+
+var server = http.createServer(function (inp, out) {
+	var command = inp.url.substring(1);
+	if (command == "ping") {
+		out.end("pong");
+	} else if (command == "stop") {
+		console.log("GraalVM agent stopped");
+		out.end(command, null, function() {
+			process.exit(0);
+		});
+	} else {
+		if(inp.method == 'POST') {
+			processPost(inp, out);
+		} else {
+			out.writeHead(200, "OK", {'Content-Type': 'text/plain'});
+			out.end();
+		}
+	}
+});
+
+host = process.argv[2]
+port = parseInt(process.argv[3])
+server.listen(port, host);
+server.on('error', function(err) {
+    console.log("Caught error: " + err);
+});
+
+console.log("GraalVM agent accepting at " + host + ":" + port);
diff --git a/com.oracle.truffle.r.pkgs/graalvm/man/g.Rd b/com.oracle.truffle.r.pkgs/graalvm/man/g.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..3038fd1e7f7b3d6e5308f699507ee072159f9d1f
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/man/g.Rd
@@ -0,0 +1,32 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/g.R
+\name{g}
+\alias{g}
+\title{Execute code by GraalVM using the language interpreter that corresponds
+to the language mimetype.}
+\usage{
+g(code, echo = TRUE, mimetype = "application/x-r")
+}
+\arguments{
+\item{code}{the code to be executed. It must be a language element as long as the target
+language is R, otherwise it must be a string.}
+
+\item{echo}{controls whether this function returns the result of the interpreted code.
+The default value is TRUE.}
+
+\item{mimetype}{The mimetype of the target language. Currently supported values are
+"application/x-r", "text/javascript" and "application/x-ruby".}
+}
+\description{
+Execute code by GraalVM using the language interpreter that corresponds
+to the language mimetype.
+}
+\examples{
+g(runif(10^3))
+g(runif(10^8), echo = FALSE) # We do not want that the result is returned due to its size
+g("1 < 2", mimetype = "text/javascript")
+}
+\seealso{
+Other execution functions: \code{\link{g.js}},
+  \code{\link{g.rb}}, \code{\link{g.r}}
+}
diff --git a/com.oracle.truffle.r.pkgs/graalvm/man/g.js.Rd b/com.oracle.truffle.r.pkgs/graalvm/man/g.js.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..7d9287f25b71c1d809c72a0d6eb58f592681c666
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/man/g.js.Rd
@@ -0,0 +1,18 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/g.R
+\name{g.js}
+\alias{g.js}
+\title{Execute JavaScript code.}
+\usage{
+g.js(code, echo = TRUE)
+}
+\description{
+Execute JavaScript code.
+}
+\examples{
+g.js("1 < 2")
+}
+\seealso{
+Other execution functions: \code{\link{g.rb}},
+  \code{\link{g.r}}, \code{\link{g}}
+}
diff --git a/com.oracle.truffle.r.pkgs/graalvm/man/g.r.Rd b/com.oracle.truffle.r.pkgs/graalvm/man/g.r.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..3566a2a0b4fd3f87e577ab3ad4db38f90c0619bc
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/man/g.r.Rd
@@ -0,0 +1,18 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/g.R
+\name{g.r}
+\alias{g.r}
+\title{Execute R code.}
+\usage{
+g.r(code, echo = TRUE)
+}
+\description{
+Execute R code.
+}
+\examples{
+g.r("runif(10^3)")
+}
+\seealso{
+Other execution functions: \code{\link{g.js}},
+  \code{\link{g.rb}}, \code{\link{g}}
+}
diff --git a/com.oracle.truffle.r.pkgs/graalvm/man/g.rb.Rd b/com.oracle.truffle.r.pkgs/graalvm/man/g.rb.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..f307ee4a34fc0c8e756eaff1470f830392cea509
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/man/g.rb.Rd
@@ -0,0 +1,18 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/g.R
+\name{g.rb}
+\alias{g.rb}
+\title{Execute Ruby code.}
+\usage{
+g.rb(code, echo = TRUE)
+}
+\description{
+Execute Ruby code.
+}
+\examples{
+g.rb("1 < 2")
+}
+\seealso{
+Other execution functions: \code{\link{g.js}},
+  \code{\link{g.r}}, \code{\link{g}}
+}
diff --git a/com.oracle.truffle.r.pkgs/graalvm/man/gget.Rd b/com.oracle.truffle.r.pkgs/graalvm/man/gget.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..e0515efb005afd1492d454b56ee438b9e77508d8
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/man/gget.Rd
@@ -0,0 +1,19 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/g.R
+\name{gget}
+\alias{gget}
+\title{Retrieve the variable defined in a GraalVM language. The local variable must have been 
+initialized by one of the language specific gget.* or ggset.* functions.}
+\usage{
+gget(var)
+}
+\description{
+Retrieve the variable defined in a GraalVM language. The local variable must have been 
+initialized by one of the language specific gget.* or ggset.* functions.
+}
+\seealso{
+Other paired variables: \code{\link{gget.js}},
+  \code{\link{gget.rb}}, \code{\link{gget.r}},
+  \code{\link{gset.js}}, \code{\link{gset.rb}},
+  \code{\link{gset.r}}, \code{\link{gset}}
+}
diff --git a/com.oracle.truffle.r.pkgs/graalvm/man/gget.js.Rd b/com.oracle.truffle.r.pkgs/graalvm/man/gget.js.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..7caf44f206c6d7ab4de17c4b6d6859963e53807e
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/man/gget.js.Rd
@@ -0,0 +1,17 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/g.R
+\name{gget.js}
+\alias{gget.js}
+\title{Retrieve the variable defined in GraalVM JS.}
+\usage{
+gget.js(var)
+}
+\description{
+Retrieve the variable defined in GraalVM JS.
+}
+\seealso{
+Other paired variables: \code{\link{gget.rb}},
+  \code{\link{gget.r}}, \code{\link{gget}},
+  \code{\link{gset.js}}, \code{\link{gset.rb}},
+  \code{\link{gset.r}}, \code{\link{gset}}
+}
diff --git a/com.oracle.truffle.r.pkgs/graalvm/man/gget.r.Rd b/com.oracle.truffle.r.pkgs/graalvm/man/gget.r.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..df1678e584988b605466d858358539f9ce29b430
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/man/gget.r.Rd
@@ -0,0 +1,17 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/g.R
+\name{gget.r}
+\alias{gget.r}
+\title{Retrieve the variable defined in GraalVM FastR.}
+\usage{
+gget.r(var)
+}
+\description{
+Retrieve the variable defined in GraalVM FastR.
+}
+\seealso{
+Other paired variables: \code{\link{gget.js}},
+  \code{\link{gget.rb}}, \code{\link{gget}},
+  \code{\link{gset.js}}, \code{\link{gset.rb}},
+  \code{\link{gset.r}}, \code{\link{gset}}
+}
diff --git a/com.oracle.truffle.r.pkgs/graalvm/man/gget.rb.Rd b/com.oracle.truffle.r.pkgs/graalvm/man/gget.rb.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..4dfe3fd3fef1f8f1a228aa829e49fa4f16f92a27
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/man/gget.rb.Rd
@@ -0,0 +1,17 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/g.R
+\name{gget.rb}
+\alias{gget.rb}
+\title{Retrieve the variable defined in GraalVM Ruby.}
+\usage{
+gget.rb(var)
+}
+\description{
+Retrieve the variable defined in GraalVM Ruby.
+}
+\seealso{
+Other paired variables: \code{\link{gget.js}},
+  \code{\link{gget.r}}, \code{\link{gget}},
+  \code{\link{gset.js}}, \code{\link{gset.rb}},
+  \code{\link{gset.r}}, \code{\link{gset}}
+}
diff --git a/com.oracle.truffle.r.pkgs/graalvm/man/graalvm.Rd b/com.oracle.truffle.r.pkgs/graalvm/man/graalvm.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..a77541d69d508e1551913b79f81c471d5ad9db42
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/man/graalvm.Rd
@@ -0,0 +1,59 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/graalvm.R
+\name{graalvm}
+\alias{graalvm}
+\title{GraalVM R package is supposed to demonstrate FastR performance and polyglot capabilities 
+of GraalVM to GNUR users.}
+\description{
+GraalVM R package is supposed to demonstrate FastR performance and polyglot capabilities 
+of GraalVM to GNUR users.
+}
+\examples{
+# Loading and setting up
+
+library(graalvm)
+graalvm.setup("~/work/graalvm-0.21")
+
+# Code execution
+g(v <- runif(1e8))
+g(f <- function(x) { s <- 0; for (i in seq_along(x)) s <- s + x[[i]]; s })
+g(system.time(f(v)))
+g(system.time(f(v)))
+
+g.js("1 < 2")
+g.rb("$a = 2")
+
+
+# Paired variables
+
+# Create and initialize paired variables:
+gset.r(a1, TRUE) 
+gset.js(a2, c(1,2))
+gset.rb(a3, list(a=1,b="2")) 
+a1
+a2
+a3
+g.r("a1")
+g.js("a2")
+g.rb("$a3")
+
+g(a1 = FALSE)
+gget(a1)
+a1
+
+# Paired functions
+
+# Create a paired function
+gset.r(measure, function(n) { system.time(runif(n)) })
+# Execute the local version of the paired function
+measure(1e8)
+# Execute the remote version of the paired function
+g(measure(1e8))
+
+# Executing a script file
+
+tmp <- tempfile()
+writeLines(con = tmp, c("x<-10", "y<-x^2", "y"))
+g.r(readLines(con=tmp))
+
+}
diff --git a/com.oracle.truffle.r.pkgs/graalvm/man/graalvm.setup.Rd b/com.oracle.truffle.r.pkgs/graalvm/man/graalvm.setup.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..9007932d6d936816d018cd3c0e24b8e3ec171a76
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/man/graalvm.setup.Rd
@@ -0,0 +1,25 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/g.R
+\name{graalvm.setup}
+\alias{graalvm.setup}
+\title{Set up the GraalVM agent}
+\usage{
+graalvm.setup(home, host = "localhost", port = 9876, rlibs = paste0(home,
+  "/language/R/library"))
+}
+\arguments{
+\item{home}{The home folder of the GraalVM installation}
+
+\item{host}{The local host name at which the GraalVM agent is listening}
+
+\item{port}{The port at which the GraalVM agent is listening}
+
+\item{rlibs}{The value of the FastR R_LIBS environmental variable. The default 
+value is calculated as paste0(graalvm.home, "/language/R/library").}
+}
+\description{
+Set up the GraalVM agent
+}
+\examples{
+graalvm.setup("~/work/graalvm-0.21")
+}
diff --git a/com.oracle.truffle.r.pkgs/graalvm/man/graalvm.start.Rd b/com.oracle.truffle.r.pkgs/graalvm/man/graalvm.start.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..1527a6cf91f2bb39dc5edb722599aeea5ee0e4fc
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/man/graalvm.start.Rd
@@ -0,0 +1,13 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/g.R
+\name{graalvm.start}
+\alias{graalvm.start}
+\title{Start the GraalVM agent. The agent is normally started automatically upon the first
+code ecxecution.}
+\usage{
+graalvm.start()
+}
+\description{
+Start the GraalVM agent. The agent is normally started automatically upon the first
+code ecxecution.
+}
diff --git a/com.oracle.truffle.r.pkgs/graalvm/man/graalvm.stop.Rd b/com.oracle.truffle.r.pkgs/graalvm/man/graalvm.stop.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..d559fddba1591d5d1785d13337ddd8613533fc35
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/man/graalvm.stop.Rd
@@ -0,0 +1,11 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/g.R
+\name{graalvm.stop}
+\alias{graalvm.stop}
+\title{Stop the GraalVM agent.}
+\usage{
+graalvm.stop()
+}
+\description{
+Stop the GraalVM agent.
+}
diff --git a/com.oracle.truffle.r.pkgs/graalvm/man/gset.Rd b/com.oracle.truffle.r.pkgs/graalvm/man/gset.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..9c139e088c901d71ca9df399909e1c8aea79c40f
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/man/gset.Rd
@@ -0,0 +1,35 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/g.R
+\name{gset}
+\alias{gset}
+\title{Assign a value to a paired variable. The value is assigned both locally and remotely.
+The local variable must have been initialized by one of the language specific gget.* or
+ggset.* functions.}
+\usage{
+gset(var, value = var)
+}
+\description{
+Assign a value to a paired variable. The value is assigned both locally and remotely.
+The local variable must have been initialized by one of the language specific gget.* or
+ggset.* functions.
+}
+\examples{
+# Create and initialize a variable in JS
+g.js("a = 1")
+# Pick up the a variable from JS and define its counterpart in GNUR
+gget.js(a)
+a
+# Increment the variable both locally and in JS 
+gset(a, a + 1)
+a
+g.js("a[0]")
+g.js("a[1] = 10")
+gget(a)
+a
+}
+\seealso{
+Other paired variables: \code{\link{gget.js}},
+  \code{\link{gget.rb}}, \code{\link{gget.r}},
+  \code{\link{gget}}, \code{\link{gset.js}},
+  \code{\link{gset.rb}}, \code{\link{gset.r}}
+}
diff --git a/com.oracle.truffle.r.pkgs/graalvm/man/gset.js.Rd b/com.oracle.truffle.r.pkgs/graalvm/man/gset.js.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..1cf7308f64ce9e3c396f393bc8fb374087211073
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/man/gset.js.Rd
@@ -0,0 +1,17 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/g.R
+\name{gset.js}
+\alias{gset.js}
+\title{Assign the value to the paired variable in Graal JS and locally.}
+\usage{
+gset.js(var, value)
+}
+\description{
+Assign the value to the paired variable in Graal JS and locally.
+}
+\seealso{
+Other paired variables: \code{\link{gget.js}},
+  \code{\link{gget.rb}}, \code{\link{gget.r}},
+  \code{\link{gget}}, \code{\link{gset.rb}},
+  \code{\link{gset.r}}, \code{\link{gset}}
+}
diff --git a/com.oracle.truffle.r.pkgs/graalvm/man/gset.r.Rd b/com.oracle.truffle.r.pkgs/graalvm/man/gset.r.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..669c2c700cab73040056c02fec68c9a55d1773c0
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/man/gset.r.Rd
@@ -0,0 +1,17 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/g.R
+\name{gset.r}
+\alias{gset.r}
+\title{Assign the value to the paired variable in Graal FastR and locally.}
+\usage{
+gset.r(var, value)
+}
+\description{
+Assign the value to the paired variable in Graal FastR and locally.
+}
+\seealso{
+Other paired variables: \code{\link{gget.js}},
+  \code{\link{gget.rb}}, \code{\link{gget.r}},
+  \code{\link{gget}}, \code{\link{gset.js}},
+  \code{\link{gset.rb}}, \code{\link{gset}}
+}
diff --git a/com.oracle.truffle.r.pkgs/graalvm/man/gset.rb.Rd b/com.oracle.truffle.r.pkgs/graalvm/man/gset.rb.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..45aaef4d8edb7caeb861c13c1c8501ab5ed9a05e
--- /dev/null
+++ b/com.oracle.truffle.r.pkgs/graalvm/man/gset.rb.Rd
@@ -0,0 +1,17 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/g.R
+\name{gset.rb}
+\alias{gset.rb}
+\title{Assign the value to the paired variable in Graal Ruby and locally.}
+\usage{
+gset.rb(var, value)
+}
+\description{
+Assign the value to the paired variable in Graal Ruby and locally.
+}
+\seealso{
+Other paired variables: \code{\link{gget.js}},
+  \code{\link{gget.rb}}, \code{\link{gget.r}},
+  \code{\link{gget}}, \code{\link{gset.js}},
+  \code{\link{gset.r}}, \code{\link{gset}}
+}