diff --git a/.gitignore b/.gitignore
index a1b4ad8c171c249f4b64de267405318c95a4df97..e988817cdb19d21c8a0d576885cfcca7808b3d61 100644
--- a/.gitignore
+++ b/.gitignore
@@ -113,3 +113,4 @@ test_gnur
 test_fastr
 lib.install.cran*
 package.blacklist
+com.oracle.truffle.r.test.native/embedded/main
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
index 463577a1036c667f2531b4e405dd2d01bf450973..529fdd4f93ec77a50874ac6aeab7df547471cf70 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
@@ -62,7 +62,6 @@ import com.oracle.truffle.r.runtime.BrowserQuitException;
 import com.oracle.truffle.r.runtime.FastROptions;
 import com.oracle.truffle.r.runtime.RArguments;
 import com.oracle.truffle.r.runtime.RCaller;
-import com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RErrorHandling;
 import com.oracle.truffle.r.runtime.RInternalError;
@@ -70,6 +69,7 @@ import com.oracle.truffle.r.runtime.RInternalSourceDescriptions;
 import com.oracle.truffle.r.runtime.RParserFactory;
 import com.oracle.truffle.r.runtime.RProfile;
 import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.RStartParams.SA_TYPE;
 import com.oracle.truffle.r.runtime.ReturnException;
 import com.oracle.truffle.r.runtime.SubstituteVirtualFrame;
 import com.oracle.truffle.r.runtime.ThreadTimings;
@@ -179,9 +179,9 @@ final class REngine implements Engine, Engine.Timings {
                     throw new RInternalError(e, "error while parsing user profile from %s", userProfile.getName());
                 }
             }
-            if (!(context.getOptions().getBoolean(RCmdOption.NO_RESTORE) || context.getOptions().getBoolean(RCmdOption.NO_RESTORE_DATA))) {
+            if (!(context.getStartParams().getRestoreAction() == SA_TYPE.NORESTORE)) {
                 // call sys.load.image(".RData", RCmdOption.QUIET
-                checkAndRunStartupShutdownFunction("sys.load.image", new String[]{"\".RData\"", context.getOptions().getBoolean(RCmdOption.QUIET) ? "TRUE" : "FALSE"});
+                checkAndRunStartupShutdownFunction("sys.load.image", new String[]{"\".RData\"", context.getStartParams().getQuiet() ? "TRUE" : "FALSE"});
                 context.getConsoleHandler().setHistoryFrom(new File("./.Rhistory"));
             }
             checkAndRunStartupShutdownFunction(".First");
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/RCommand.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/RCommand.java
index edd3314671962989ab151741e632bf6caad0b808..8176d7d7975d5aa3a0a415576fad70fe86d29da6 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/RCommand.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/RCommand.java
@@ -25,15 +25,11 @@ package com.oracle.truffle.r.engine.shell;
 import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.EXPR;
 import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.FILE;
 import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.INTERACTIVE;
-import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.NO_ENVIRON;
-import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.NO_INIT_FILE;
 import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.NO_READLINE;
-import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.NO_RESTORE;
 import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.NO_SAVE;
 import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.QUIET;
 import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.SAVE;
 import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.SILENT;
-import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.SLAVE;
 import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.VANILLA;
 
 import java.io.Console;
@@ -54,8 +50,10 @@ import com.oracle.truffle.r.runtime.BrowserQuitException;
 import com.oracle.truffle.r.runtime.RCmdOptions;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.RStartParams;
 import com.oracle.truffle.r.runtime.RInternalSourceDescriptions;
 import com.oracle.truffle.r.runtime.Utils;
+import com.oracle.truffle.r.runtime.RStartParams.SA_TYPE;
 import com.oracle.truffle.r.runtime.Utils.DebugExitException;
 import com.oracle.truffle.r.runtime.context.ConsoleHandler;
 import com.oracle.truffle.r.runtime.context.ContextInfo;
@@ -78,53 +76,24 @@ public class RCommand {
     // CheckStyle: stop system..print check
 
     public static void main(String[] args) {
-        PolyglotEngine vm = createPolyglotEngine(args);
+        RCmdOptions options = RCmdOptions.parseArguments(RCmdOptions.Client.R, args, false);
+        options.printHelpAndVersion();
+        PolyglotEngine vm = createContextInfoFromCommandLine(options, false);
         // never returns
         readEvalPrint(vm);
         throw RInternalError.shouldNotReachHere();
     }
 
-    /**
-     * This exists as a separate method to support the Rembedded API.
-     */
-    static PolyglotEngine createPolyglotEngine(String[] args) {
-        RCmdOptions options = RCmdOptions.parseArguments(RCmdOptions.Client.R, args);
-        options.printHelpAndVersion();
-        PolyglotEngine vm = createContextInfoFromCommandLine(options);
-        return vm;
-    }
-
-    /**
-     * Creates the PolyglotEngine and initializes it. Called from native code when FastR is
-     * embedded.
-     */
-    static PolyglotEngine initialize(String[] args) {
-        PolyglotEngine vm = createPolyglotEngine(args);
-        // Any expression will do to initialize the engine.
-        doEcho(vm);
-        return vm;
-    }
-
-    static PolyglotEngine createContextInfoFromCommandLine(RCmdOptions options) {
-        if (options.getBoolean(SLAVE)) {
-            options.setValue(QUIET, true);
-            options.setValue(NO_SAVE, true);
-        }
-
-        if (options.getBoolean(VANILLA)) {
-            options.setValue(NO_SAVE, true);
-            options.setValue(NO_ENVIRON, true);
-            options.setValue(NO_INIT_FILE, true);
-            options.setValue(NO_RESTORE, true);
-        }
+    static PolyglotEngine createContextInfoFromCommandLine(RCmdOptions options, boolean embedded) {
+        RStartParams rsp = new RStartParams(options, embedded);
 
         String fileArg = options.getString(FILE);
         if (fileArg != null) {
             if (options.getStringList(EXPR) != null) {
                 Utils.fatalError("cannot use -e with -f or --file");
             }
-            if (!options.getBoolean(SLAVE)) {
-                options.setValue(NO_SAVE, true);
+            if (!rsp.getSlave()) {
+                rsp.setSaveAction(SA_TYPE.NOSAVE);
             }
             if (fileArg.equals("-")) {
                 // means stdin, but still implies NO_SAVE
@@ -156,8 +125,8 @@ public class RCommand {
             consoleHandler = new StringConsoleHandler(lines, System.out, filePath);
         } else if (options.getStringList(EXPR) != null) {
             List<String> exprs = options.getStringList(EXPR);
-            if (!options.getBoolean(SLAVE)) {
-                options.setValue(NO_SAVE, true);
+            if (!rsp.getSlave()) {
+                rsp.setSaveAction(SA_TYPE.NOSAVE);
             }
             consoleHandler = new StringConsoleHandler(exprs, System.out, RInternalSourceDescriptions.EXPRESSION_INPUT);
         } else {
@@ -189,7 +158,7 @@ public class RCommand {
                 consoleHandler = new DefaultConsoleHandler(consoleInput, consoleOutput);
             }
         }
-        return ContextInfo.create(options, ContextKind.SHARE_NOTHING, null, consoleHandler).apply(PolyglotEngine.newBuilder()).build();
+        return ContextInfo.create(rsp, ContextKind.SHARE_NOTHING, null, consoleHandler).apply(PolyglotEngine.newBuilder()).build();
     }
 
     private static final Source GET_ECHO = Source.fromText("invisible(getOption('echo'))", RInternalSourceDescriptions.GET_ECHO).withMimeType(TruffleRLanguage.MIME);
@@ -298,7 +267,7 @@ public class RCommand {
         }
     }
 
-    private static ContextInfo getContextInfo(PolyglotEngine vm) {
+    static ContextInfo getContextInfo(PolyglotEngine vm) {
         try {
             return (ContextInfo) vm.findGlobalSymbol(ContextInfo.GLOBAL_SYMBOL).get();
         } catch (IOException ex) {
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/REmbedded.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/REmbedded.java
new file mode 100644
index 0000000000000000000000000000000000000000..c37adfd81eada4a6c4754b30379c52f576a06e59
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/REmbedded.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016, 2016, 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.
+ */
+package com.oracle.truffle.r.engine.shell;
+
+import java.io.IOException;
+
+import com.oracle.truffle.api.source.Source;
+import com.oracle.truffle.api.vm.PolyglotEngine;
+import com.oracle.truffle.r.engine.TruffleRLanguage;
+import com.oracle.truffle.r.runtime.RCmdOptions;
+import com.oracle.truffle.r.runtime.RInternalSourceDescriptions;
+import com.oracle.truffle.r.runtime.RStartParams;
+import com.oracle.truffle.r.runtime.Utils;
+import com.oracle.truffle.r.runtime.context.RContext;
+
+public class REmbedded {
+
+    /**
+     * Creates the {@link PolyglotEngine} and initializes it. Called from native code when FastR is
+     * embedded. Corresponds to FFI method {@code Rf_initialize_R}. N.B. This does not actually
+     * initialize FastR as that happens indirectly when the {@link PolyglotEngine} does the first
+     * {@code eval} and we cannot do that until the embedding system has had a chance to adjust the
+     * {@link RStartParams}.
+     */
+    private static PolyglotEngine initializeR(String[] args) {
+        RCmdOptions options = RCmdOptions.parseArguments(RCmdOptions.Client.R, args, true);
+        PolyglotEngine vm = RCommand.createContextInfoFromCommandLine(options, true);
+        return vm;
+    }
+
+    private static final Source INIT = Source.fromText("1", RInternalSourceDescriptions.GET_ECHO).withMimeType(TruffleRLanguage.MIME);
+
+    /**
+     * Upcall from native code to prepare for the main read-eval-print loop, Since we are in
+     * embedded mode we first do a dummy eval that has the important side effect of creating the
+     * {@link RContext}. Then we use that to complete the initialization that was deferred.
+     *
+     * @param vm
+     */
+    private static void setupRmainloop(PolyglotEngine vm) {
+        try {
+            vm.eval(INIT);
+            RContext.getInstance().completeEmbeddedInitialization();
+        } catch (IOException ex) {
+            Utils.fatalError("setupRmainloop");
+        }
+    }
+
+    private static void mainloop(PolyglotEngine vm) {
+        setupRmainloop(vm);
+        runRmainloop(vm);
+    }
+
+    private static void runRmainloop(PolyglotEngine vm) {
+        RCommand.readEvalPrint(vm);
+    }
+
+    /**
+     * Testing vehicle, emulates a native upcall.
+     */
+    public static void main(String[] args) {
+        PolyglotEngine vm = initializeR(args);
+        RStartParams startParams = RCommand.getContextInfo(vm).getStartParams();
+        startParams.setEmbedded();
+        startParams.setLoadInitFile(false);
+        startParams.setNoRenviron(true);
+        mainloop(vm);
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/RStartParams.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/RStartParams.java
deleted file mode 100644
index 3c59c0dfb2a1dc371022c9ff4004a158b12a32b2..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/RStartParams.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 1995-2015, The R Core Team
- * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-package com.oracle.truffle.r.engine.shell;
-
-/**
- * Support for Rembedded. Defines startup parameters that can be customized by embedding apps.
- */
-public class RStartParams {
-
-    public enum SA_TYPE {
-        NORESTORE,
-        RESTORE,
-        DEFAULT,
-        NOSAVE,
-        SAVE,
-        SAVEASK,
-        SUICIDE
-    }
-
-    private boolean quiet;
-    private boolean slave;
-    private boolean interactive = true;
-    private boolean verbose;
-    private boolean loadSiteFile = true;
-    private boolean loadInitFile = true;
-    private boolean debugInitFile;
-    private SA_TYPE restoreAction = SA_TYPE.RESTORE;
-    private SA_TYPE saveAction = SA_TYPE.SAVEASK;
-    private boolean noRenviron;
-
-    private static RStartParams active;
-
-    private RStartParams() {
-
-    }
-
-    /**
-     * Only upcalled from native code.
-     */
-    public RStartParams(boolean quiet, boolean slave, boolean interactive, boolean verbose, boolean loadSiteFile,
-                    boolean loadInitFile, boolean debugInitFile, int restoreAction,
-                    int saveAction, boolean noRenviron) {
-        this.quiet = quiet;
-        this.slave = slave;
-        this.interactive = interactive;
-        this.verbose = verbose;
-        this.loadSiteFile = loadSiteFile;
-        this.loadInitFile = loadInitFile;
-        this.debugInitFile = debugInitFile;
-        this.restoreAction = SA_TYPE.values()[restoreAction];
-        this.saveAction = SA_TYPE.values()[saveAction];
-        this.noRenviron = noRenviron;
-    }
-
-    public static RStartParams getActive() {
-        if (active == null) {
-            active = new RStartParams();
-        }
-        return active;
-    }
-
-    public static void setParams(RStartParams rs) {
-        active = rs;
-    }
-
-}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/RscriptCommand.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/RscriptCommand.java
index 33108b010f1203946be2f97259c337e5c2e67254..18dee4e6ab23216a6581f87455c44953512c8a5e 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/RscriptCommand.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/RscriptCommand.java
@@ -99,9 +99,9 @@ public class RscriptCommand {
     public static void main(String[] args) {
         // Since many of the options are shared parse them from an RSCRIPT perspective.
         // Handle --help and --version specially, as they exit.
-        RCmdOptions options = RCmdOptions.parseArguments(RCmdOptions.Client.RSCRIPT, args);
+        RCmdOptions options = RCmdOptions.parseArguments(RCmdOptions.Client.RSCRIPT, args, false);
         preprocessRScriptOptions(options);
-        PolyglotEngine vm = RCommand.createContextInfoFromCommandLine(options);
+        PolyglotEngine vm = RCommand.createContextInfoFromCommandLine(options, false);
         // never returns
         RCommand.readEvalPrint(vm);
         throw RInternalError.shouldNotReachHere();
diff --git a/com.oracle.truffle.r.native/fficall/src/common/unimplemented.c b/com.oracle.truffle.r.native/fficall/src/common/unimplemented.c
index c03eda625456912a28ae407e33a0a614f56dc1b2..70ca795f33c4a57ea69fc9d2ef1d5d16a849fc23 100644
--- a/com.oracle.truffle.r.native/fficall/src/common/unimplemented.c
+++ b/com.oracle.truffle.r.native/fficall/src/common/unimplemented.c
@@ -126,3 +126,32 @@ SEXP R_Unserialize(R_inpstream_t stream)
 	unimplemented("R_Unserialize");
 	return NULL;
 }
+
+SEXP R_getS4DataSlot(SEXP obj, SEXPTYPE type) {
+	unimplemented("R_getS4DataSlot");
+	return NULL;
+}
+
+void Rf_checkArityCall(SEXP a, SEXP b, SEXP c) {
+	unimplemented("Rf_checkArityCall");
+}
+
+SEXP NewEnvironment(SEXP a, SEXP b, SEXP c) {
+	unimplemented("NewEnvironment");
+	return NULL;
+}
+
+void* PRIMFUN(SEXP x) {
+	unimplemented("NewEnvironment");
+	return NULL;
+}
+
+SEXP coerceToSymbol(SEXP v) {
+	unimplemented("coerceToSymbol");
+}
+
+int IntegerFromString(SEXP a, int* b) {
+	unimplemented("IntegerFromString");
+	return 0;
+}
+
diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c b/com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c
index d071862f1cd4b368754dcf6699eaeab6caf8194a..76af2dc91aa21dbb0279ff14595d1f8e3520ee35 100644
--- a/com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c
+++ b/com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c
@@ -20,7 +20,7 @@ static JNIEnv *jniEnv;
 static jobject engine;
 static int initialized = 0;
 
-static jclass rcommandClass;
+static jclass rembeddedClass;
 static jclass rStartParamsClass;
 
 typedef jint (JNICALL *JNI_CreateJavaVMFunc)
@@ -35,6 +35,21 @@ static void *dlopen_jvmlib(char *libpath) {
 	return handle;
 }
 
+// separate vm args from user args
+static int process_vmargs(int argc, char *argv[], char *vmargv[], char *uargv[]) {
+	int vcount = 0;
+	int ucount = 0;
+	for (int i = 0; i < argc; i++) {
+		char *arg = argv[i];
+		if (arg[0] == '-' && arg[1] == 'X') {
+			vmargv[vcount++] = arg;
+		} else {
+			uargv[ucount++] = arg;
+		}
+	}
+	return vcount;
+}
+
 int Rf_initialize_R(int argc, char *argv[]) {
 	if (initialized) {
 		fprintf(stderr, "%s", "R is already initialized\n");
@@ -71,7 +86,6 @@ int Rf_initialize_R(int argc, char *argv[]) {
 	}
 
 	// TODO getting the correct classpath is hard, need a helper program
-	JavaVMOption vm_options[1];
 	char *vm_cp = getenv("FASTR_CLASSPATH");
 	if (vm_cp == NULL) {
 		printf("Rf_initialize_R: FASTR_CLASSPATH env var not set\n");
@@ -82,13 +96,24 @@ int Rf_initialize_R(int argc, char *argv[]) {
 	char *cp = malloc(cplen + 32);
 	strcpy(cp, "-Djava.class.path=");
 	strcat(cp, vm_cp);
+
+	char **vmargs = malloc(argc * sizeof(char*));
+	char **uargs = malloc(argc * sizeof(char*));
+	int vmargc = process_vmargs(argc, argv, vmargs, uargs);
+	argc -= vmargc;
+	argv = uargs;
+	JavaVMOption vm_options[1 + vmargc];
+
 	vm_options[0].optionString = cp;
+	for (int i = 0; i < vmargc; i++) {
+		vm_options[i + 1].optionString = vmargs[i];
+	}
 
 	printf("creating vm\n");
 
 	JavaVMInitArgs vm_args;
 	vm_args.version = JNI_VERSION_1_8;
-	vm_args.nOptions = 1;
+	vm_args.nOptions = 1 + vmargc;
 	vm_args.options = vm_options;
 	vm_args.ignoreUnrecognized = JNI_TRUE;
 
@@ -99,22 +124,25 @@ int Rf_initialize_R(int argc, char *argv[]) {
 		return 1;
 	}
 
-	rcommandClass = checkFindClass(jniEnv, "com/oracle/truffle/r/engine/shell/RCommand");
-	rStartParamsClass = checkFindClass(jniEnv, "com/oracle/truffle/r/engine/shell/RStartParams");
+	rembeddedClass = checkFindClass(jniEnv, "com/oracle/truffle/r/engine/shell/REmbedded");
+	rStartParamsClass = checkFindClass(jniEnv, "com/oracle/truffle/r/runtime/RStartParams");
 	jclass stringClass = checkFindClass(jniEnv, "java/lang/String");
-	jmethodID initializeMethod = checkGetMethodID(jniEnv, rcommandClass, "initialize",
+	jmethodID initializeMethod = checkGetMethodID(jniEnv, rembeddedClass, "initializeR",
 			"([Ljava/lang/String;)Lcom/oracle/truffle/api/vm/PolyglotEngine;", 1);
-	int argLength = 0;
-	jobjectArray argsArray = (*jniEnv)->NewObjectArray(jniEnv, argLength, stringClass, NULL);
+	jobjectArray argsArray = (*jniEnv)->NewObjectArray(jniEnv, argc, stringClass, NULL);
+	for (int i = 0; i < argc; i++) {
+		jstring arg = (*jniEnv)->NewStringUTF(jniEnv, argv[i]);
+		(*jniEnv)->SetObjectArrayElement(jniEnv, argsArray, i, arg);
+	}
 
-	engine = checkRef(jniEnv, (*jniEnv)->CallStaticObjectMethod(jniEnv, rcommandClass, initializeMethod, argsArray));
+	engine = checkRef(jniEnv, (*jniEnv)->CallStaticObjectMethod(jniEnv, rembeddedClass, initializeMethod, argsArray));
 	initialized++;
 	return 0;
 }
 
 void setup_Rmainloop(void) {
-	// In GnuR R_initialize_R and setup_Rmainloop do different things.
-	// In FastR we don't (yet?) have the distinction, so there is nothing more to do here
+	jmethodID setupMethod = checkGetMethodID(jniEnv, rembeddedClass, "setupRmainloop", "(Lcom/oracle/truffle/api/vm/PolyglotEngine;)V", 1);
+	(*jniEnv)->CallStaticVoidMethod(jniEnv, rembeddedClass, setupMethod, engine);
 }
 
 void R_DefParams(Rstart rs) {
@@ -138,12 +166,10 @@ void R_DefParams(Rstart rs) {
 }
 
 void R_SetParams(Rstart rs) {
-	jmethodID setParamsMethodID = checkGetMethodID(jniEnv, rStartParamsClass, "setParams", "(Lcom/oracle/truffle/r/engine/shell/RStartParams;)V", 1);
-	jmethodID consMethodID = checkGetMethodID(jniEnv, rStartParamsClass, "<init>", "(ZZZZZZZIIZ)V", 0);
-	jobject javaRSParams = (*jniEnv)->NewObject(jniEnv, rStartParamsClass, consMethodID, rs->R_Quiet, rs->R_Slave, rs->R_Interactive,
+	jmethodID setParamsMethodID = checkGetMethodID(jniEnv, rStartParamsClass, "setParams", "(ZZZZZZZIIZ)V", 1);
+	(*jniEnv)->CallStaticVoidMethod(jniEnv, rStartParamsClass, setParamsMethodID, rs->R_Quiet, rs->R_Slave, rs->R_Interactive,
 			rs->R_Verbose, rs->LoadSiteFile, rs->LoadInitFile, rs->DebugInitFile,
 			rs->RestoreAction, rs->SaveAction, rs->NoRenviron);
-	(*jniEnv)->CallStaticVoidMethod(jniEnv, rStartParamsClass, setParamsMethodID, javaRSParams);
 }
 
 void R_SizeFromEnv(Rstart rs) {
@@ -172,8 +198,13 @@ void Rf_endEmbeddedR(int fatal) {
 }
 
 void Rf_mainloop(void) {
-	jmethodID readEvalPrintMethod = checkGetMethodID(jniEnv, rcommandClass, "readEvalPrint", "(Lcom/oracle/truffle/api/vm/PolyglotEngine;)V", 1);
-	(*jniEnv)->CallStaticVoidMethod(jniEnv, rcommandClass, readEvalPrintMethod, engine);
+	jmethodID mainloopMethod = checkGetMethodID(jniEnv, rembeddedClass, "mainloop", "(Lcom/oracle/truffle/api/vm/PolyglotEngine;)V", 1);
+	(*jniEnv)->CallStaticVoidMethod(jniEnv, rembeddedClass, mainloopMethod, engine);
+}
+
+void run_Rmainloop(void) {
+	jmethodID mainloopMethod = checkGetMethodID(jniEnv, rembeddedClass, "runRmainloop", "(Lcom/oracle/truffle/api/vm/PolyglotEngine;)V", 1);
+	(*jniEnv)->CallStaticVoidMethod(jniEnv, rembeddedClass, mainloopMethod, engine);
 }
 
 // function ptrs that can be assigned by an embedded client to change behavior
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CapabilitiesFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CapabilitiesFunctions.java
index 9d9cf7ea93c4cb2e9abf7b9237251b77b1816814..9747ccc12e44080a9ec23d3b90fb4b82eeea13ce 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CapabilitiesFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CapabilitiesFunctions.java
@@ -26,7 +26,6 @@ import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.RBuiltin;
 import com.oracle.truffle.r.runtime.RBuiltinKind;
-import com.oracle.truffle.r.runtime.RCmdOptions;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -82,7 +81,7 @@ public class CapabilitiesFunctions {
                 boolean value = c.defValue;
                 switch (c) {
                     case cledit:
-                        value = RContext.getInstance().isInteractive() && !RContext.getInstance().getOptions().getBoolean(RCmdOptions.RCmdOption.NO_READLINE);
+                        value = RContext.getInstance().isInteractive() && !RContext.getInstance().getStartParams().getNoReadline();
                         break;
                 }
                 data[c.ordinal()] = RRuntime.asLogical(value);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CommandArgs.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CommandArgs.java
index 9e784aad764cfe8bf3cc0ff1dac668a767e672af..c491925fb9f6dd92424951659659d279745f9400 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CommandArgs.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CommandArgs.java
@@ -38,7 +38,7 @@ public abstract class CommandArgs extends RBuiltinNode {
     @Specialization
     @TruffleBoundary
     protected RStringVector commandArgs() {
-        String[] s = RContext.getInstance().getOptions().getArguments();
+        String[] s = RContext.getInstance().getStartParams().getArguments();
         return RDataFactory.createStringVector(s, RDataFactory.COMPLETE_VECTOR);
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Quit.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Quit.java
index b6f1ef4b27059cb5ca0df35a5e6a647a0035ba45..d4635df06ea5cc9c2a80416244ec23912ca838f3 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Quit.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Quit.java
@@ -31,8 +31,8 @@ import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.helpers.BrowserInteractNode;
 import com.oracle.truffle.r.runtime.RBuiltin;
-import com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption;
 import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RStartParams.SA_TYPE;
 import com.oracle.truffle.r.runtime.RVisibility;
 import com.oracle.truffle.r.runtime.Utils;
 import com.oracle.truffle.r.runtime.context.ConsoleHandler;
@@ -71,7 +71,7 @@ public abstract class Quit extends RBuiltinNode {
         // Quit does not divert its output to sink
         ConsoleHandler consoleHandler = RContext.getInstance().getConsoleHandler();
         if (save.equals("default")) {
-            if (RContext.getInstance().getOptions().getBoolean(RCmdOption.NO_SAVE)) {
+            if (RContext.getInstance().getStartParams().getSaveAction() == SA_TYPE.NOSAVE) {
                 save = "no";
             } else {
                 if (consoleHandler.isInteractive()) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRContext.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRContext.java
index 3af03e8051699d3d5f1dfb1dcd318a1332a6bb6d..4171f2d54938a72f8473e695c86ae21ff9e67187 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRContext.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRContext.java
@@ -40,6 +40,7 @@ import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RInternalSourceDescriptions;
 import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.RStartParams;
 import com.oracle.truffle.r.runtime.RVisibility;
 import com.oracle.truffle.r.runtime.conn.StdConnections;
 import com.oracle.truffle.r.runtime.context.ContextInfo;
@@ -69,8 +70,8 @@ public class FastRContext {
         protected int create(RAbstractStringVector args, RAbstractStringVector kindVec) {
             try {
                 RContext.ContextKind kind = RContext.ContextKind.valueOf(kindVec.getDataAt(0));
-                RCmdOptions options = RCmdOptions.parseArguments(Client.RSCRIPT, args.materialize().getDataCopy());
-                return ContextInfo.createDeferred(options, kind, RContext.getInstance(), RContext.getInstance().getConsoleHandler());
+                RStartParams startParams = new RStartParams(RCmdOptions.parseArguments(Client.RSCRIPT, args.materialize().getDataCopy(), false), embedded);
+                return ContextInfo.createDeferred(startParams, kind, RContext.getInstance(), RContext.getInstance().getConsoleHandler());
             } catch (IllegalArgumentException ex) {
                 throw RError.error(this, RError.Message.GENERIC, "invalid kind argument");
             }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCmdOptions.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCmdOptions.java
index 65fa24a348450aa6401eb5ca266cf08d73a88d70..006e150e82cd7e46a4d7a925b1d89f1c1c577ba0 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCmdOptions.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCmdOptions.java
@@ -278,11 +278,12 @@ public final class RCmdOptions {
      * The spec for {@code commandArgs()} states that it returns the executable by which R was
      * invoked in element 0, which is consistent with the C {@code main} function, but defines the
      * exact form to be platform independent. Java does not provide the executable (for obvious
-     * reasons) so we use "FastR".
+     * reasons) so we use "FastR". However, embedded mode does pass the executable in
+     * {@code args[0]} and we do not want to parse that!
      */
-    public static RCmdOptions parseArguments(Client client, String[] args) {
+    public static RCmdOptions parseArguments(Client client, String[] args, boolean embedded) {
         EnumMap<RCmdOption, Object> options = new EnumMap<>(RCmdOption.class);
-        int i = 0;
+        int i = embedded ? 1 : 0;
         int firstNonOptionArgIndex = args.length;
         while (i < args.length) {
             final String arg = args[i];
@@ -327,9 +328,14 @@ public final class RCmdOptions {
                 }
             }
         }
-        String[] xargs = new String[args.length + 1];
-        xargs[0] = "FastR";
-        System.arraycopy(args, 0, xargs, 1, args.length);
+        String[] xargs;
+        if (embedded) {
+            xargs = args;
+        } else {
+            xargs = new String[args.length + 1];
+            xargs[0] = "FastR";
+            System.arraycopy(args, 0, xargs, 1, args.length);
+        }
 
         // adjust for inserted executable name
         return new RCmdOptions(options, xargs, firstNonOptionArgIndex + 1);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/REnvVars.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/REnvVars.java
index b6fe1483d2e51109a49047d6765768f07d9156b7..e8d68692064e190abdaae38f28d52c457d599a63 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/REnvVars.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/REnvVars.java
@@ -32,7 +32,6 @@ import java.util.HashMap;
 import java.util.Map;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
 
@@ -67,7 +66,7 @@ public final class REnvVars implements RContext.ContextState {
             // This gets expanded by R code in the system profile
         }
 
-        if (!context.getOptions().getBoolean(RCmdOption.NO_ENVIRON)) {
+        if (!context.getStartParams().getNoRenviron()) {
             String siteFile = envVars.get("R_ENVIRON");
             if (siteFile == null) {
                 siteFile = fileSystem.getPath(rHome, "etc", "Renviron.site").toString();
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ROptions.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ROptions.java
index 831548d3a7d675514a826cd64db564c7d57b0962..ffc362a8e899fa0aa5d1f17e95ef4f5e67b26087 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ROptions.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ROptions.java
@@ -18,7 +18,6 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
-import com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.context.RContext.ContextKind;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -90,7 +89,7 @@ public class ROptions {
         public static ContextStateImpl newContext(RContext context, REnvVars envVars) {
             HashMap<String, Object> map = new HashMap<>();
             if (context.getKind() == ContextKind.SHARE_NOTHING) {
-                applyDefaults(map, context.getOptions(), envVars);
+                applyDefaults(map, context.getStartParams(), envVars);
             } else {
                 map.putAll(context.getParent().stateROptions.map);
             }
@@ -114,13 +113,13 @@ public class ROptions {
                     "rl_word_breaks", "warnPartialMatchDollar", "warnPartialMatchArgs", "warnPartialMatchAttr", "showWarnCalls", "showErrorCalls", "showNCalls", "par.ask.default",
                     "browserNLdisabled", "CBoundsCheck"));
 
-    private static void applyDefaults(HashMap<String, Object> map, RCmdOptions options, REnvVars envVars) {
+    private static void applyDefaults(HashMap<String, Object> map, RStartParams startParams, REnvVars envVars) {
         map.put("add.smooth", RDataFactory.createLogicalVectorFromScalar(true));
         map.put("check.bounds", RDataFactory.createLogicalVectorFromScalar(false));
         map.put("continue", RDataFactory.createStringVector("+ "));
         map.put("deparse.cutoff", RDataFactory.createIntVectorFromScalar(60));
         map.put("digits", RDataFactory.createIntVectorFromScalar(7));
-        map.put("echo", RDataFactory.createLogicalVectorFromScalar(options.getBoolean(RCmdOption.SLAVE) ? false : true));
+        map.put("echo", RDataFactory.createLogicalVectorFromScalar(startParams.getSlave() ? false : true));
         map.put("encoding", RDataFactory.createStringVector("native.enc"));
         map.put("expressions", RDataFactory.createIntVectorFromScalar(5000));
         boolean keepPkgSource = optionFromEnvVar("R_KEEP_PKG_SOURCE", envVars);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RProfile.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RProfile.java
index c7b6bc7651e890734695c5fe4d1c560983b9ad0c..61b609d21a42bd0351ded9ae345cdb2aecae238d 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RProfile.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RProfile.java
@@ -22,9 +22,6 @@
  */
 package com.oracle.truffle.r.runtime;
 
-import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.NO_INIT_FILE;
-import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.NO_SITE_FILE;
-
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.FileSystem;
@@ -47,7 +44,7 @@ public final class RProfile implements RContext.ContextState {
         Source newSiteProfile = null;
         Source newUserProfile = null;
 
-        if (!context.getOptions().getBoolean(NO_SITE_FILE)) {
+        if (context.getStartParams().getLoadSiteFile()) {
             String siteProfilePath = envVars.get("R_PROFILE");
             if (siteProfilePath == null) {
                 siteProfilePath = fileSystem.getPath(rHome, "etc", "Rprofile.site").toString();
@@ -60,7 +57,7 @@ public final class RProfile implements RContext.ContextState {
             }
         }
 
-        if (!context.getOptions().getBoolean(NO_INIT_FILE)) {
+        if (context.getStartParams().getLoadInitFile()) {
             String userProfilePath = envVars.get("R_PROFILE_USER");
             if (userProfilePath == null) {
                 String dotRenviron = ".Rprofile";
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RStartParams.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RStartParams.java
new file mode 100644
index 0000000000000000000000000000000000000000..59404fa69961590654bfb4eab314e47fd405c6b5
--- /dev/null
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RStartParams.java
@@ -0,0 +1,214 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 1995-2015, The R Core Team
+ * Copyright (c) 2003, The R Foundation
+ * Copyright (c) 2016, 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.runtime;
+
+import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.RESTORE;
+import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.NO_READLINE;
+import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.NO_RESTORE;
+import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.NO_RESTORE_DATA;
+import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.SAVE;
+import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.NO_SAVE;
+import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.SLAVE;
+import static com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption.VANILLA;
+
+import com.oracle.truffle.r.runtime.context.RContext;
+
+/**
+ * Defines startup parameters (that can be customized by embedding apps).
+ */
+public class RStartParams {
+
+    public enum SA_TYPE {
+        NORESTORE,
+        RESTORE,
+        DEFAULT,
+        NOSAVE,
+        SAVE,
+        SAVEASK,
+        SUICIDE
+    }
+
+    private boolean quiet;
+    private boolean slave;
+    private boolean interactive = true;
+    private boolean verbose;
+    private boolean loadSiteFile = true;
+    private boolean loadInitFile = true;
+    private boolean debugInitFile;
+    private SA_TYPE restoreAction = SA_TYPE.RESTORE;
+    private SA_TYPE saveAction = SA_TYPE.SAVEASK;
+    private boolean noRenviron;
+    /**
+     * This is not a configurable option, but it is set on the command line and needs to be stored
+     * somewhere.
+     */
+    private boolean noReadline;
+
+    /**
+     * The original command line arguments that were parsed by {@link RCmdOptions}.
+     */
+    private String[] arguments;
+
+    /**
+     * Indicates that FastR is running embedded.
+     */
+    private boolean embedded;
+
+    public RStartParams(RCmdOptions options, boolean embedded) {
+        this.arguments = options.getArguments();
+        this.embedded = embedded;
+
+        if (options.getBoolean(SAVE)) {
+            this.saveAction = SA_TYPE.SAVE;
+        }
+        if (options.getBoolean(NO_SAVE)) {
+            this.saveAction = SA_TYPE.NOSAVE;
+        }
+        if (options.getBoolean(RESTORE)) {
+            this.restoreAction = SA_TYPE.RESTORE;
+        }
+        if (options.getBoolean(NO_RESTORE) || options.getBoolean(NO_RESTORE_DATA)) {
+            this.restoreAction = SA_TYPE.NORESTORE;
+        }
+        if (options.getBoolean(NO_READLINE)) {
+            this.noReadline = true;
+        }
+        if (options.getBoolean(SLAVE)) {
+            this.slave = true;
+            this.quiet = true;
+            this.setSaveAction(SA_TYPE.NOSAVE);
+        }
+
+        if (options.getBoolean(VANILLA)) {
+            this.setSaveAction(SA_TYPE.NOSAVE);
+            this.noRenviron = true;
+            this.loadInitFile = false;
+            this.restoreAction = SA_TYPE.NORESTORE;
+        }
+    }
+
+    /**
+     * Only upcalled from native code.
+     */
+    @SuppressWarnings("unused")
+    private static void setParams(boolean quietA, boolean slaveA, boolean interactiveA, boolean verboseA, boolean loadSiteFileA,
+                    boolean loadInitFileA, boolean debugInitFileA, int restoreActionA,
+                    int saveActionA, boolean noRenvironA) {
+        RStartParams params = RContext.getInstance().getStartParams();
+        params.setQuiet(quietA);
+        params.setSlave(slaveA);
+        params.setInteractive(interactiveA);
+        params.setVerbose(verboseA);
+        params.setLoadSiteFile(loadSiteFileA);
+        params.setLoadInitFile(loadInitFileA);
+        params.setDebugInitFile(debugInitFileA);
+        params.setSaveAction(SA_TYPE.values()[saveActionA]);
+        params.setRestoreAction(SA_TYPE.values()[restoreActionA]);
+        params.setNoRenviron(noRenvironA);
+    }
+
+    public boolean getQuiet() {
+        return this.quiet;
+    }
+
+    public void setQuiet(boolean b) {
+        this.quiet = b;
+    }
+
+    public boolean getSlave() {
+        return slave;
+    }
+
+    public void setSlave(boolean b) {
+        this.slave = b;
+    }
+
+    public boolean getInteractive() {
+        return this.interactive;
+    }
+
+    public void setInteractive(boolean b) {
+        this.interactive = b;
+    }
+
+    public boolean getVerbose() {
+        return this.verbose;
+    }
+
+    public void setVerbose(boolean b) {
+        this.verbose = b;
+    }
+
+    public boolean getLoadSiteFile() {
+        return this.loadSiteFile;
+    }
+
+    public void setLoadSiteFile(boolean b) {
+        this.loadSiteFile = b;
+    }
+
+    public boolean getLoadInitFile() {
+        return this.loadInitFile;
+    }
+
+    public void setLoadInitFile(boolean b) {
+        this.loadInitFile = b;
+    }
+
+    public boolean getDebugInitFile() {
+        return this.debugInitFile;
+    }
+
+    public void setDebugInitFile(boolean b) {
+        this.debugInitFile = b;
+    }
+
+    public SA_TYPE getRestoreAction() {
+        return this.restoreAction;
+    }
+
+    public void setRestoreAction(SA_TYPE a) {
+        this.restoreAction = a;
+    }
+
+    public SA_TYPE getSaveAction() {
+        return this.saveAction;
+    }
+
+    public void setSaveAction(SA_TYPE a) {
+        this.saveAction = a;
+    }
+
+    public boolean getNoRenviron() {
+        return this.noRenviron;
+    }
+
+    public void setNoRenviron(boolean b) {
+        this.noRenviron = b;
+    }
+
+    public boolean getNoReadline() {
+        return this.noReadline;
+    }
+
+    public String[] getArguments() {
+        return arguments;
+    }
+
+    public void setEmbedded() {
+        this.embedded = true;
+    }
+
+    public boolean getEmbedded() {
+        return embedded;
+    }
+}
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java
index 9757b838778cab34a04efd31c01d6ddc949c1cc5..484aad8dc3015793cc88e8d36444ffcdcf349105 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java
@@ -50,7 +50,6 @@ import com.oracle.truffle.api.frame.FrameSlot;
 import com.oracle.truffle.api.nodes.GraphPrintVisitor;
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.source.SourceSection;
-import com.oracle.truffle.r.runtime.RCmdOptions.RCmdOption;
 import com.oracle.truffle.r.runtime.conn.StdConnections;
 import com.oracle.truffle.r.runtime.context.ConsoleHandler;
 import com.oracle.truffle.r.runtime.context.RContext;
@@ -153,7 +152,7 @@ public final class Utils {
          * polyglot context are.
          */
         RPerfStats.report();
-        if (RContext.getInstance() != null && RContext.getInstance().getOptions() != null && RContext.getInstance().getOptions().getString(RCmdOption.DEBUGGER) != null) {
+        if (RContext.getInstance() != null && RContext.getInstance().getStartParams() != null && RContext.getInstance().getStartParams().getDebugInitFile()) {
             throw new DebugExitException();
         } else {
             try {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/ContextInfo.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/ContextInfo.java
index 632570262291c58849151f99fdea3233aebf44f4..0452fb924b61a37cc3ac98e60c4c62a66ae3e307 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/ContextInfo.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/ContextInfo.java
@@ -29,7 +29,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 import com.oracle.truffle.api.interop.ForeignAccess;
 import com.oracle.truffle.api.interop.TruffleObject;
 import com.oracle.truffle.api.vm.PolyglotEngine;
-import com.oracle.truffle.r.runtime.RCmdOptions;
+import com.oracle.truffle.r.runtime.RStartParams;
 import com.oracle.truffle.r.runtime.context.RContext.ContextKind;
 
 /**
@@ -45,7 +45,7 @@ public final class ContextInfo implements TruffleObject {
     private static final ConcurrentHashMap<Integer, ContextInfo> contextInfos = new ConcurrentHashMap<>();
     private static final AtomicInteger contextInfoIds = new AtomicInteger();
 
-    private final RCmdOptions options;
+    private final RStartParams startParams;
     private final RContext.ContextKind kind;
     private final TimeZone systemTimeZone;
 
@@ -57,8 +57,8 @@ public final class ContextInfo implements TruffleObject {
     private final ConsoleHandler consoleHandler;
     private final int id;
 
-    private ContextInfo(RCmdOptions options, ContextKind kind, RContext parent, ConsoleHandler consoleHandler, TimeZone systemTimeZone, int id) {
-        this.options = options;
+    private ContextInfo(RStartParams startParams, ContextKind kind, RContext parent, ConsoleHandler consoleHandler, TimeZone systemTimeZone, int id) {
+        this.startParams = startParams;
         this.kind = kind;
         this.parent = parent;
         this.consoleHandler = consoleHandler;
@@ -76,21 +76,21 @@ public final class ContextInfo implements TruffleObject {
      * @param parent if non-null {@code null}, the parent creating the context
      * @param kind defines the degree to which this context shares base and package environments
      *            with its parent
-     * @param options the command line arguments passed this R session
+     * @param startParams the start parameters passed this R session
      * @param consoleHandler a {@link ConsoleHandler} for output
      * @param systemTimeZone the system's time zone
      */
-    public static ContextInfo create(RCmdOptions options, ContextKind kind, RContext parent, ConsoleHandler consoleHandler, TimeZone systemTimeZone) {
+    public static ContextInfo create(RStartParams startParams, ContextKind kind, RContext parent, ConsoleHandler consoleHandler, TimeZone systemTimeZone) {
         int id = contextInfoIds.incrementAndGet();
-        return new ContextInfo(options, kind, parent, consoleHandler, systemTimeZone, id);
+        return new ContextInfo(startParams, kind, parent, consoleHandler, systemTimeZone, id);
     }
 
-    public static ContextInfo create(RCmdOptions options, ContextKind kind, RContext parent, ConsoleHandler consoleHandler) {
-        return create(options, kind, parent, consoleHandler, TimeZone.getDefault());
+    public static ContextInfo create(RStartParams startParams, ContextKind kind, RContext parent, ConsoleHandler consoleHandler) {
+        return create(startParams, kind, parent, consoleHandler, TimeZone.getDefault());
     }
 
-    public static int createDeferred(RCmdOptions options, ContextKind kind, RContext parent, ConsoleHandler consoleHandler) {
-        ContextInfo info = create(options, kind, parent, consoleHandler, TimeZone.getDefault());
+    public static int createDeferred(RStartParams startParams, ContextKind kind, RContext parent, ConsoleHandler consoleHandler) {
+        ContextInfo info = create(startParams, kind, parent, consoleHandler, TimeZone.getDefault());
         contextInfos.put(info.id, info);
         return info.id;
     }
@@ -99,8 +99,8 @@ public final class ContextInfo implements TruffleObject {
         return contextInfos.get(id);
     }
 
-    public RCmdOptions getOptions() {
-        return options;
+    public RStartParams getStartParams() {
+        return startParams;
     }
 
     public ContextKind getKind() {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java
index 3f5116190ac4118611371881a6ebc0982956e5d8..76441461f484e189a16d8ed7fc40320197248945 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java
@@ -58,6 +58,7 @@ import com.oracle.truffle.r.runtime.RProfile;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RRuntimeASTAccess;
 import com.oracle.truffle.r.runtime.RSerialize;
+import com.oracle.truffle.r.runtime.RStartParams;
 import com.oracle.truffle.r.runtime.RVisibility;
 import com.oracle.truffle.r.runtime.Utils;
 import com.oracle.truffle.r.runtime.conn.ConnectionSupport;
@@ -351,9 +352,9 @@ public final class RContext extends ExecutionContext implements TruffleObject {
      * could do this more dynamically with a registration process, perhaps driven by an annotation
      * processor, but the set is relatively small, so we just enumerate them here.
      */
-    public final REnvVars stateREnvVars;
-    public final RProfile stateRProfile;
-    public final ROptions.ContextStateImpl stateROptions;
+    public REnvVars stateREnvVars;
+    public RProfile stateRProfile;
+    public ROptions.ContextStateImpl stateROptions;
     public final REnvironment.ContextStateImpl stateREnvironment;
     public final RErrorHandling.ContextStateImpl stateRErrorHandling;
     public final ConnectionSupport.ContextStateImpl stateRConnection;
@@ -365,6 +366,8 @@ public final class RContext extends ExecutionContext implements TruffleObject {
     public final TraceState.ContextStateImpl stateTraceHandling;
     public final ContextStateImpl stateInternalCode;
 
+    private final boolean embedded;
+
     private ContextState[] contextStates() {
         return new ContextState[]{stateREnvVars, stateRProfile, stateROptions, stateREnvironment, stateRErrorHandling, stateRConnection, stateStdConnections, stateRNG, stateRFFI, stateRSerialize,
                         stateLazyDBCache, stateTraceHandling};
@@ -373,7 +376,12 @@ public final class RContext extends ExecutionContext implements TruffleObject {
     private RContext(Env env, Instrumenter instrumenter, boolean isInitial) {
         ContextInfo initialInfo = (ContextInfo) env.importSymbol(ContextInfo.GLOBAL_SYMBOL);
         if (initialInfo == null) {
-            this.info = ContextInfo.create(RCmdOptions.parseArguments(Client.R, new String[0]), ContextKind.SHARE_NOTHING, null, new DefaultConsoleHandler(env.in(), env.out()));
+            /*
+             * This implies that FastR is being invoked initially from another Truffle language and
+             * not via RCommand/RscriptCommand.
+             */
+            this.info = ContextInfo.create(new RStartParams(RCmdOptions.parseArguments(Client.R, new String[0], false), false), ContextKind.SHARE_NOTHING, null,
+                            new DefaultConsoleHandler(env.in(), env.out()));
         } else {
             this.info = initialInfo;
         }
@@ -420,9 +428,10 @@ public final class RContext extends ExecutionContext implements TruffleObject {
         assert !active;
         active = true;
         attachThread();
-        stateREnvVars = REnvVars.newContext(this);
-        stateRProfile = RProfile.newContext(this, stateREnvVars);
-        stateROptions = ROptions.ContextStateImpl.newContext(this, stateREnvVars);
+        embedded = info.getStartParams().getEmbedded();
+        if (!embedded) {
+            doEnvOptionsProfileInitialization();
+        }
         stateREnvironment = REnvironment.ContextStateImpl.newContext(this);
         stateRErrorHandling = RErrorHandling.ContextStateImpl.newContext(this);
         stateRConnection = ConnectionSupport.ContextStateImpl.newContext(this);
@@ -433,7 +442,11 @@ public final class RContext extends ExecutionContext implements TruffleObject {
         stateLazyDBCache = LazyDBCache.ContextStateImpl.newContext(this);
         stateTraceHandling = TraceState.newContext(this);
         stateInternalCode = ContextStateImpl.newContext(this);
-        engine.activate(stateREnvironment);
+
+        if (!embedded) {
+            validateContextStates();
+            engine.activate(stateREnvironment);
+        }
 
         if (info.getKind() == ContextKind.SHARE_PARENT_RW) {
             if (info.getParent().sharedChild != null) {
@@ -444,12 +457,32 @@ public final class RContext extends ExecutionContext implements TruffleObject {
             // that methods package is loaded
             this.methodTableDispatchOn = info.getParent().methodTableDispatchOn;
         }
+        if (isInitial && !embedded) {
+            initialContextInitialized = true;
+        }
+    }
+
+    /**
+     * Factored out for embedded setup, where this initialization may be customized after the
+     * context is created but before VM really starts execution.
+     */
+    private void doEnvOptionsProfileInitialization() {
+        stateREnvVars = REnvVars.newContext(this);
+        stateROptions = ROptions.ContextStateImpl.newContext(this, stateREnvVars);
+        stateRProfile = RProfile.newContext(this, stateREnvVars);
+    }
+
+    public void completeEmbeddedInitialization() {
+        doEnvOptionsProfileInitialization();
+        validateContextStates();
+        engine.activate(stateREnvironment);
+        initialContextInitialized = true;
+    }
+
+    private void validateContextStates() {
         for (ContextState state : contextStates()) {
             assert state != null;
         }
-        if (isInitial) {
-            initialContextInitialized = true;
-        }
     }
 
     /**
@@ -537,7 +570,12 @@ public final class RContext extends ExecutionContext implements TruffleObject {
 
     public void setVisible(boolean v) {
         if (!FastROptions.IgnoreVisibility.getBooleanValue()) {
-            resultVisible = v;
+            /*
+             * Prevent printing the dummy expression used to force creation of initial context
+             */
+            if (initialContextInitialized || !embedded) {
+                resultVisible = v;
+            }
         }
     }
 
@@ -642,8 +680,8 @@ public final class RContext extends ExecutionContext implements TruffleObject {
         return foreignAccessFactory;
     }
 
-    public RCmdOptions getOptions() {
-        return info.getOptions();
+    public RStartParams getStartParams() {
+        return info.getStartParams();
     }
 
     @Override
diff --git a/com.oracle.truffle.r.test.native/Makefile b/com.oracle.truffle.r.test.native/Makefile
index d764e42992ffedf7d4e641901334ea62953ca339..80679c40d2ff0951d6a7e825633c0cd11f11c299 100644
--- a/com.oracle.truffle.r.test.native/Makefile
+++ b/com.oracle.truffle.r.test.native/Makefile
@@ -28,7 +28,9 @@ export TOPDIR = $(CURDIR)
 all:
 	$(MAKE) -C urand
 	$(MAKE) -C packages
+	$(MAKE) -C embedded
 
 clean:
 	$(MAKE) -C urand clean
 	$(MAKE) -C packages clean
+	$(MAKE) -C embedded clean
diff --git a/com.oracle.truffle.r.test.native/embedded/Makefile b/com.oracle.truffle.r.test.native/embedded/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..d6a3fe704c1b3df2c8e1017a920bc799c107dd8f
--- /dev/null
+++ b/com.oracle.truffle.r.test.native/embedded/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2016, 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.
+#
+
+ifeq ($(TOPDIR),)
+    TOPDIR = $(abspath ..)
+endif
+
+NATIVE_PROJECT = $(subst test.native,native,$(TOPDIR))
+
+.PHONY: all clean
+
+OBJ = lib
+SRC = src
+C_SOURCES := $(wildcard $(SRC)/*.c)
+C_OBJECTS := $(subst $(SRC),$(OBJ),$(C_SOURCES:.c=.o))
+
+
+INCLUDE_DIR := $(NATIVE_PROJECT)/include
+
+all: $(OBJ)/main
+
+$(OBJ):
+	mkdir -p $(OBJ)
+
+$(OBJ)/main: $(SRC)/main.c
+	$(CC) $(CFLAGS) -I$(INCLUDE_DIR) $< -o main -ldl
+
+clean:
+	rm -rf $(OBJ)
diff --git a/com.oracle.truffle.r.test.native/embedded/src/main.c b/com.oracle.truffle.r.test.native/embedded/src/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..3c1a2f08d89f15a16e9ebd8bf5c626acdfb6667d
--- /dev/null
+++ b/com.oracle.truffle.r.test.native/embedded/src/main.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014, 2016, 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.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <Rembedded.h>
+#include <R_ext/RStartup.h>
+/*
+ * Copyright (c) 2016, 2016, 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.
+ */
+
+// A simple test program for FastR embedded mode.
+// compile with "gcc -I include main.c -ldl
+
+#include <dlfcn.h>
+#include <sys/utsname.h>
+#include <string.h>
+
+
+typedef int (*Rf_initEmbeddedRFunc)(int, char**);
+typedef void (*Rf_endEmbeddedRFunc)(int);
+typedef void (*Rf_mainloopFunc)(void);
+typedef void (*R_DefParamsFunc)(Rstart);
+typedef void (*R_SetParamsFunc)(Rstart);
+
+int main(int argc, char **argv) {
+  struct utsname utsname;
+  uname(&utsname);
+  char *r_home = getenv("R_HOME");
+  if (r_home == NULL) {
+    printf("R_HOME must be set\n");
+    exit(1);
+  }
+
+  char libr_path[256];
+  strcpy(libr_path, r_home);
+  if (strcmp(utsname.sysname, "Linux") == 0) {
+    strcat(libr_path, "lib/libR.so");
+  } else if (strcmp(utsname.sysname, "Darwin") == 0) {
+    strcat(libr_path, "lib/libR.dylib");
+  }
+
+  void *handle = dlopen(libr_path, RTLD_LAZY | RTLD_GLOBAL);
+  if (handle == NULL) {
+    printf("failed to open libR: %s\n", dlerror());
+    exit(1);
+  }
+  Rf_initEmbeddedRFunc init = (Rf_initEmbeddedRFunc) dlsym(handle, "Rf_initEmbeddedR");
+  Rf_mainloopFunc mainloop = (Rf_mainloopFunc) dlsym(handle, "run_Rmainloop");
+  Rf_endEmbeddedRFunc end = (Rf_endEmbeddedRFunc) dlsym(handle, "Rf_endEmbeddedR");
+  if (init == NULL || mainloop == NULL || end == NULL) {
+    printf("failed to find R embedded functions\n");
+    exit(1);
+  }
+  (*init)(argc, argv);
+     structRstart rp;
+   Rstart Rp = &rp;
+   R_DefParamsFunc defp = (R_DefParamsFunc) dlsym(handle, "R_DefParams");
+   (*defp)(Rp);
+   Rp->SaveAction = SA_NOSAVE;
+   R_SetParamsFunc setp = (R_SetParamsFunc) dlsym(handle, "R_SetParams");
+   (*setp)(Rp);
+  (*mainloop)();
+  (*end)(0);
+}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java
index 2676ef74024676c4fb19b609c37a9e9644671ae9..e8a3aaa2b9321900fad4ae856d9aef0b71ab8134 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java
@@ -39,6 +39,7 @@ import com.oracle.truffle.r.runtime.RCmdOptions;
 import com.oracle.truffle.r.runtime.RCmdOptions.Client;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RInternalError;
+import com.oracle.truffle.r.runtime.RStartParams;
 import com.oracle.truffle.r.runtime.context.ConsoleHandler;
 import com.oracle.truffle.r.runtime.context.ContextInfo;
 import com.oracle.truffle.r.runtime.context.Engine.IncompleteSourceException;
@@ -154,15 +155,15 @@ public final class FastRSession implements RSession {
     }
 
     public ContextInfo createContextInfo(ContextKind contextKind) {
-        RCmdOptions options = RCmdOptions.parseArguments(Client.RSCRIPT, new String[0]);
-        return ContextInfo.create(options, contextKind, mainContext, consoleHandler, TimeZone.getTimeZone("CET"));
+        RStartParams params = new RStartParams(RCmdOptions.parseArguments(Client.RSCRIPT, new String[0], false), false);
+        return ContextInfo.create(params, contextKind, mainContext, consoleHandler, TimeZone.getTimeZone("CET"));
     }
 
     private FastRSession() {
         consoleHandler = new TestConsoleHandler();
         try {
-            RCmdOptions options = RCmdOptions.parseArguments(Client.RSCRIPT, new String[]{"--no-restore"});
-            ContextInfo info = ContextInfo.create(options, ContextKind.SHARE_NOTHING, null, consoleHandler);
+            RStartParams params = new RStartParams(RCmdOptions.parseArguments(Client.RSCRIPT, new String[]{"--no-restore"}, false), false);
+            ContextInfo info = ContextInfo.create(params, ContextKind.SHARE_NOTHING, null, consoleHandler);
             main = info.apply(PolyglotEngine.newBuilder()).build();
             try {
                 mainContext = main.eval(GET_CONTEXT).as(RContext.class);
diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides
index bac61dc04dec6fd5d5d85ab667d32a878d80a5de..d401042d2b7b1744840a32073d9d391136c71bbc 100644
--- a/mx.fastr/copyrights/overrides
+++ b/mx.fastr/copyrights/overrides
@@ -1,4 +1,3 @@
-com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/RStartParams.java,gnu_r.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/BaseGraphicsSystem.java,gnu_r_graphics.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/core/AbstractGraphicsSystem.java,gnu_r_graphics.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/core/drawables/CoordinatesDrawableObject.java,gnu_r_graphics.copyright
@@ -189,6 +188,7 @@ com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/InheritsNode.jav
 com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/IsFactorNode.java,purdue.copyright
 com.oracle.truffle.r.parser/src/com/oracle/truffle/r/parser/R.g,purdue.copyright
 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSrcref.java,gnu_r.copyright
+com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RStartParams.java,gnu_r.copyright
 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RTypedValue.java,gnu_r_gentleman_ihaka.copyright
 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java,gnu_r.copyright
 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/gnur/SEXPTYPE.java,gnu_r.copyright
diff --git a/mx.fastr/mx_fastr.py b/mx.fastr/mx_fastr.py
index 9c32408af000218333c29fb4377ba389afbecc88..ff4533e1df81730be1bf29c7a1468887ee6b5833 100644
--- a/mx.fastr/mx_fastr.py
+++ b/mx.fastr/mx_fastr.py
@@ -69,7 +69,9 @@ _r_command_project = 'com.oracle.truffle.r.engine'
 _repl_command = 'com.oracle.truffle.tools.debug.shell.client.SimpleREPLClient'
 _command_class_dict = {'r': _r_command_project + ".shell.RCommand",
                        'rscript': _r_command_project + ".shell.RscriptCommand",
-                        'rrepl': _repl_command}
+                        'rrepl': _repl_command,
+                        'rembed': _r_command_project + ".shell.REmbedded",
+                    }
 # benchmarking support
 def r_path():
     return join(_fastr_suite.dir, 'bin', 'R')
@@ -239,6 +241,9 @@ def rrepl(args, nonZeroIsFatal=True, extraVmArgs=None):
     '''run R repl'''
     run_r(args, 'rrepl')
 
+def rembed(args, nonZeroIsFatal=True, extraVmArgs=None):
+    run_r(args, 'rembed')
+
 def build(args):
     '''FastR build'''
     # workaround for Hotspot Mac OS X build problem
@@ -527,6 +532,7 @@ _commands = {
     'rcmplib' : [rcmplib, ['options']],
     'pkgtest' : [mx_fastr_pkgs.pkgtest, ['options']],
     'rrepl' : [rrepl, '[options]'],
+    'rembed' : [rembed, '[options]'],
     'installpkgs' : [installpkgs, '[options]'],
     'installcran' : [installpkgs, '[options]'],
     }