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 7dee98d92d2b02ac9c35d3c686f4d4dd60afe789..ab19a0a278d18db88e0756d2cf7244c49d118e92 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
@@ -295,16 +295,18 @@ final class REngine implements Engine, Engine.Timings {
     @Override
     public CallTarget parseToCallTarget(Source source, MaterializedFrame executionFrame) throws ParseException {
         List<RSyntaxNode> statements = parseImpl(source);
-        return Truffle.getRuntime().createCallTarget(new PolyglotEngineRootNode(statements, createSourceSection(statements), executionFrame));
+        return Truffle.getRuntime().createCallTarget(new PolyglotEngineRootNode(statements, createSourceSection(source, statements), executionFrame));
     }
 
-    private static SourceSection createSourceSection(List<RSyntaxNode> statements) {
+    private static SourceSection createSourceSection(Source source, List<RSyntaxNode> statements) {
         // All statements come from the same "Source"
-        if (statements.size() == 1) {
+        if (statements.isEmpty()) {
+            return source.createSection(0, source.getLength());
+        } else if (statements.size() == 1) {
             return statements.get(0).getSourceSection();
         } else {
-            Source source = statements.get(0).getSourceSection().getSource();
-            return source.createSection(0, statements.get(statements.size() - 1).getSourceSection().getCharEndIndex());
+            Source newSource = statements.get(0).getSourceSection().getSource();
+            return newSource.createSection(0, statements.get(statements.size() - 1).getSourceSection().getCharEndIndex());
         }
     }
 
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java
index f5710f0c5060e0b433b8ebe8f6b5e8434289a976..0c7606c8f3ef30a06a7a5c0eecb5c113041a1753 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java
@@ -92,7 +92,6 @@ import com.oracle.truffle.r.runtime.nodes.RCodeBuilder.Argument;
 import com.oracle.truffle.r.runtime.nodes.RInstrumentableNode;
 import com.oracle.truffle.r.runtime.nodes.RNode;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxCall;
-import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxElement;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxFunction;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup;
@@ -133,17 +132,6 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
  */
 class RRuntimeASTAccessImpl implements RRuntimeASTAccess {
 
-    private static Object getIntrinsicValue(Object result) {
-        if (result instanceof RSyntaxConstant) {
-            return ((RSyntaxConstant) result).getValue();
-        } else if (result instanceof RSyntaxLookup) {
-            return RDataFactory.createSymbolInterned(((RSyntaxLookup) result).getIdentifier());
-        } else {
-            assert result instanceof RSyntaxCall || result instanceof RSyntaxFunction : result.getClass();
-            return RDataFactory.createLanguage(((RSyntaxNode) result).asRNode());
-        }
-    }
-
     @TruffleBoundary
     @Override
     public RLanguage.RepType getRepType(RLanguage rl) {
@@ -203,7 +191,7 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess {
 
                     Object list = RNull.instance;
                     for (int i = sig.getLength() - 1; i >= 0; i--) {
-                        list = RDataFactory.createPairList(defaults[i] == null ? RSymbol.MISSING : getIntrinsicValue(defaults[i]), list,
+                        list = RDataFactory.createPairList(defaults[i] == null ? RSymbol.MISSING : RASTUtils.createLanguageElement(defaults[i]), list,
                                         RDataFactory.createSymbolInterned(sig.getName(i)));
                     }
                     return list;
@@ -228,7 +216,7 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess {
         /*
          * Constants and lookups are converted to their intrinsic value:
          */
-        return getIntrinsicValue(result);
+        return RASTUtils.createLanguageElement(result);
     }
 
     @Override
diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c
index 92b618c6f10d6e92dcbdb2ea16f1b375b9cdb1c8..225e41a48e016d01a5699e8aa925e32bffbb558c 100644
--- a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c
+++ b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c
@@ -112,6 +112,10 @@ static jmethodID ENCLOSMethodID;
 static jmethodID PRVALUEMethodID;
 static jmethodID R_lsInternal3MethodID;
 static jmethodID R_do_MAKE_CLASS_MethodID;
+static jmethodID PRSEENMethodID;
+static jmethodID PRENVMethodID;
+static jmethodID R_PromiseExprMethodID;
+static jmethodID PRCODEMethodID;
 
 static jmethodID R_ToplevelExecMethodID;
 static jmethodID restoreHandlerStacksMethodID;
@@ -215,6 +219,10 @@ void init_internals(JNIEnv *env) {
 	ENCLOSMethodID = checkGetMethodID(env, UpCallsRFFIClass, "ENCLOS", "(Ljava/lang/Object;)Ljava/lang/Object;", 0);
 	PRVALUEMethodID = checkGetMethodID(env, UpCallsRFFIClass, "PRVALUE", "(Ljava/lang/Object;)Ljava/lang/Object;", 0);
 	R_lsInternal3MethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_lsInternal3", "(Ljava/lang/Object;II)Ljava/lang/Object;", 0);
+	PRSEENMethodID = checkGetMethodID(env, UpCallsRFFIClass, "PRSEEN", "(Ljava/lang/Object;)I", 0);
+	PRENVMethodID = checkGetMethodID(env, UpCallsRFFIClass, "PRENV", "(Ljava/lang/Object;)Ljava/lang/Object;", 0);
+	R_PromiseExprMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_PromiseExpr", "(Ljava/lang/Object;)Ljava/lang/Object;", 0);
+	PRCODEMethodID = checkGetMethodID(env, UpCallsRFFIClass, "PRCODE", "(Ljava/lang/Object;)Ljava/lang/Object;", 0);
 
 	R_ToplevelExecMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_ToplevelExec", "()Ljava/lang/Object;", 0);
 	restoreHandlerStacksMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_ToplevelExecRestoreErrorHandlerStacks", "(Ljava/lang/Object;)V", 0);
@@ -1047,14 +1055,15 @@ void SET_HASHTAB(SEXP x, SEXP v) {
 	unimplemented("SET_HASHTAB");
 }
 
-
 SEXP PRCODE(SEXP x) {
-	return unimplemented("PRCODE");
+    JNIEnv *thisenv = getEnv();
+    return (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, PRCODEMethodID, x);
 }
 
 SEXP PRENV(SEXP x) {
-	unimplemented("PRSEEN");
-    return 0;
+    JNIEnv *thisenv = getEnv();
+    SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, PRENVMethodID, x);
+    return checkRef(thisenv, result);
 }
 
 SEXP PRVALUE(SEXP x) {
@@ -1064,7 +1073,8 @@ SEXP PRVALUE(SEXP x) {
 }
 
 int PRSEEN(SEXP x) {
-	return (int) unimplemented("PRSEEN");
+    JNIEnv *thisenv = getEnv();
+    return (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, PRSEENMethodID, x);
 }
 
 void SET_PRSEEN(SEXP x, int v) {
@@ -1494,7 +1504,8 @@ double R_strtod(const char *c, char **end) {
 }
 
 SEXP R_PromiseExpr(SEXP x) {
-	return unimplemented("R_PromiseExpr");
+    JNIEnv *thisenv = getEnv();
+    return (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, R_PromiseExprMethodID, x);
 }
 
 SEXP R_ClosureExpr(SEXP x) {
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c
index ccdcdcd041973e0a3ec5b868d22a004ca18b0a66..db953ec45718afe03c0a084dbe838bc399c77bd2 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c
@@ -715,7 +715,7 @@ SEXP PRCODE(SEXP x) {
 }
 
 SEXP PRENV(SEXP x) {
-	unimplemented("PRSEEN");
+	unimplemented("PRENV");
     return 0;
 }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsATTY.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsATTY.java
index 92198306f2147525fa9cb044ecd8b4afad4a675f..32fe9994366140e09659f5fd7309885739dc5d9b 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsATTY.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsATTY.java
@@ -40,6 +40,10 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 @RBuiltin(name = "isatty", kind = INTERNAL, parameterNames = {"con"}, behavior = PURE)
 public abstract class IsATTY extends RBuiltinNode {
 
+    static {
+        Casts.noCasts(IsATTY.class);
+    }
+
     @Specialization
     @TruffleBoundary
     protected byte isATTYNonConnection(RAbstractIntVector con) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInspect.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInspect.java
index b3ee8227c3d2db6bb72e83df13246bc4a9b42f40..39cb3d17be08313cfcb2b864857c22afde8472db 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInspect.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInspect.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -37,6 +37,11 @@ import com.oracle.truffle.r.runtime.data.RNull;
  */
 @RBuiltin(name = ".fastr.inspect", visibility = OFF, kind = PRIMITIVE, parameterNames = {"..."}, behavior = COMPLEX)
 public abstract class FastRInspect extends RBuiltinNode {
+
+    static {
+        Casts.noCasts(FastRInspect.class);
+    }
+
     @Specialization
     public Object call(@SuppressWarnings("unused") RArgsValuesAndNames args) {
         return RNull.instance;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java
index 21a4e1293a6cecd42faaa778194bc48c1d43944a..2b3bbc78a7ea4c918f19177824499d8017c458da 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -134,7 +134,7 @@ public class RASTUtils {
      * variables and actual values for constants.
      */
     @TruffleBoundary
-    public static Object createLanguageElement(RSyntaxNode element) {
+    public static Object createLanguageElement(RSyntaxElement element) {
         assert element != null;
         if (element instanceof RSyntaxConstant) {
             Object value = ((RSyntaxConstant) element).getValue();
@@ -149,7 +149,7 @@ public class RASTUtils {
             return RDataFactory.createSymbol(id);
         } else {
             assert element instanceof RSyntaxCall || element instanceof RSyntaxFunction;
-            return RDataFactory.createLanguage(element.asRNode());
+            return RDataFactory.createLanguage(((RSyntaxNode) element).asRNode());
         }
     }
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java
index 8441fc32c7dec2c65d0a48bd48be67c685ac538c..4aa1e8d9dc89dc6398662e02dac477b57b5a7b03 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java
@@ -22,7 +22,9 @@
  */
 package com.oracle.truffle.r.nodes.ffi;
 
-import static com.oracle.truffle.r.nodes.ffi.RFFIUtils.*;
+import static com.oracle.truffle.r.nodes.ffi.RFFIUtils.guarantee;
+import static com.oracle.truffle.r.nodes.ffi.RFFIUtils.guaranteeInstanceOf;
+import static com.oracle.truffle.r.nodes.ffi.RFFIUtils.unimplemented;
 
 import java.nio.charset.StandardCharsets;
 import java.util.function.Function;
@@ -30,9 +32,11 @@ import java.util.function.Function;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.frame.Frame;
 import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
+import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.source.SourceSection;
+import com.oracle.truffle.r.nodes.RASTUtils;
 import com.oracle.truffle.r.nodes.ffi.ParseResult.ParseStatus;
 import com.oracle.truffle.r.runtime.RArguments;
 import com.oracle.truffle.r.runtime.RCaller;
@@ -81,11 +85,12 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.env.REnvironment.PutException;
 import com.oracle.truffle.r.runtime.ffi.CharSXPWrapper;
-import com.oracle.truffle.r.runtime.ffi.UpCallsRFFI;
 import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
+import com.oracle.truffle.r.runtime.ffi.UpCallsRFFI;
 import com.oracle.truffle.r.runtime.gnur.SEXPTYPE;
 import com.oracle.truffle.r.runtime.nodes.DuplicationHelper;
 import com.oracle.truffle.r.runtime.nodes.RNode;
+import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 import com.oracle.truffle.r.runtime.rng.RRNG;
 
 /**
@@ -1142,4 +1147,31 @@ public class JavaUpCallsRFFIImpl implements UpCallsRFFI {
         return env;
     }
 
+    @Override
+    public int PRSEEN(Object x) {
+        RPromise promise = RFFIUtils.guaranteeInstanceOf(x, RPromise.class);
+        return promise.getGPBits();
+    }
+
+    @Override
+    public Object PRENV(Object x) {
+        RPromise promise = RFFIUtils.guaranteeInstanceOf(x, RPromise.class);
+        final MaterializedFrame frame = promise.getFrame();
+        return frame != null ? REnvironment.frameToEnvironment(frame) : RNull.instance;
+    }
+
+    @Override
+    public Object R_PromiseExpr(Object x) {
+        // R_PromiseExpr usually checks, if 'x' is a byte code object. This is not possible in
+        // FastR, so simply call PRCODE.
+        return PRCODE(x);
+    }
+
+    @Override
+    public Object PRCODE(Object x) {
+        RPromise promise = RFFIUtils.guaranteeInstanceOf(x, RPromise.class);
+        RSyntaxNode expr = RASTUtils.unwrap(promise.getRep()).asRSyntaxNode();
+        return RASTUtils.createLanguageElement(expr);
+    }
+
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/UpCallsRFFIImpl.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/UpCallsRFFIImpl.java
index 59a0dbc1390adbfc6f9c1ebe90fffe5874ce4235..f0efb662604f09ce4ba0ff9836f5503e7b6681b5 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/UpCallsRFFIImpl.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/UpCallsRFFIImpl.java
@@ -927,6 +927,38 @@ public final class UpCallsRFFIImpl implements UpCallsRFFI {
         return delegate.R_NewHashedEnv(parent, initialSize);
     }
 
+    @Override
+    public int PRSEEN(Object x) {
+        if (tracing) {
+            RFFIUtils.traceUpCall("PRSEEN", x);
+        }
+        return delegate.PRSEEN(x);
+    }
+
+    @Override
+    public Object PRENV(Object x) {
+        if (tracing) {
+            RFFIUtils.traceUpCall("PRENV", x);
+        }
+        return delegate.PRENV(x);
+    }
+
+    @Override
+    public Object R_PromiseExpr(Object x) {
+        if (tracing) {
+            RFFIUtils.traceUpCall("R_PromiseExpr", x);
+        }
+        return delegate.R_PromiseExpr(x);
+    }
+
+    @Override
+    public Object PRCODE(Object x) {
+        if (tracing) {
+            RFFIUtils.traceUpCall("PRCODE", x);
+        }
+        return delegate.PRCODE(x);
+    }
+
     // Implementation specific support
 
     /**
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/FileConnections.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/FileConnections.java
index 10e9a7ce172cdb19cf95775c1b76f9566cca8bc4..77c0e2875edf4e45f279d1eea5742f279efdd91d 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/FileConnections.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/FileConnections.java
@@ -462,8 +462,7 @@ public class FileConnections {
             raf.seek(writeOffset);
             byte[] sepData = sep.getBytes();
             for (int i = 0; i < lines.getLength(); i++) {
-                byte[] data = lines.getDataAt(i).getBytes();
-                raf.write(data);
+                writeString(lines.getDataAt(i), false);
                 raf.write(sepData);
             }
             writeOffset = raf.getFilePointer();
@@ -476,7 +475,10 @@ public class FileConnections {
 
         @Override
         public void writeString(String s, boolean nl) throws IOException {
-            throw RInternalError.unimplemented();
+            raf.write(s.getBytes());
+            if (nl) {
+                raf.writeBytes(System.lineSeparator());
+            }
         }
 
         @Override
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StdUpCallsRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StdUpCallsRFFI.java
index b8f0ecf89d961d276e182a8fdb62576e4a77a304..60a8de076bafa2a716962eb7a4ac8566957877da 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StdUpCallsRFFI.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StdUpCallsRFFI.java
@@ -240,4 +240,12 @@ public interface StdUpCallsRFFI {
 
     REnvironment R_NewHashedEnv(REnvironment parent, int initialSize);
 
+    int PRSEEN(Object x);
+
+    Object PRENV(Object x);
+
+    Object R_PromiseExpr(Object x);
+
+    Object PRCODE(Object x);
+
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index 6a8a449ed938b77889963326a092a789242a536f..14957271ae4861476e601f32f157aa17b1e65741 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -5466,7 +5466,7 @@ character(0)
 #argv <- list(list(epsilon = 1e-08, maxit = 25, trace = FALSE));as.character(argv[[1]]);
 [1] "1e-08" "25"    "FALSE"
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_ascharacter.testascharacter19#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_ascharacter.testascharacter19#
 #argv <- list(structure(list(structure(list(given = c('George', 'E.', 'P.'), family = 'Box', role = NULL, email = NULL, comment = NULL), .Names = c('given', 'family', 'role', 'email', 'comment')), structure(list(given = c('David', 'R.'), family = 'Cox', role = NULL, email = NULL, comment = NULL), .Names = c('given', 'family', 'role', 'email', 'comment'))), class = 'person'));as.character(argv[[1]]);
 [1] "George E. P. Box" "David R. Cox"
 
@@ -5577,7 +5577,7 @@ character(0)
 [4] "2012-06-04 04:00:00" "2012-06-05 04:00:00" "2012-06-06 04:00:00"
 [7] "2012-06-07 04:00:00"
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_ascharacter.testascharacter32#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_ascharacter.testascharacter32#
 #argv <- list(structure(1:4, class = 'roman'));as.character(argv[[1]]);
 [1] "I"   "II"  "III" "IV"
 
@@ -6231,7 +6231,7 @@ a + foo(c) * b
 #foo <- function(x) x*2; f <- function() a+foo(c)*b; as.function(c(alist(a=1+14, b=foo(x),c=), body(f)))(c=3,b=1)
 [1] 21
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asfunction.testasfunction#Output.IgnoreErrorContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asfunction.testasfunction#
 #{ .Internal(as.function.default(alist(a+b), "foo")) }
 Error in as.function.default(alist(a + b), "foo") : invalid environment
 
@@ -7180,15 +7180,15 @@ Warning messages:
 2: In as.vector("foo", "raw") :
   out-of-range values treated as 0 in coercion to raw
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asvector.testAsVector#Output.IgnoreErrorContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asvector.testAsVector#
 #{ as.vector(42, NULL) }
 Error in as.vector(x, mode) : invalid 'mode' argument
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asvector.testAsVector#Output.IgnoreErrorContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asvector.testAsVector#
 #{ as.vector(42, c("character", "character")) }
 Error in as.vector(x, mode) : invalid 'mode' argument
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asvector.testAsVector#Output.IgnoreErrorContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asvector.testAsVector#
 #{ as.vector(42, character())  }
 Error in as.vector(x, mode) : invalid 'mode' argument
 
@@ -12188,7 +12188,7 @@ Traceback:
  2: cbind(v)
 An irrecoverable exception occurred. R is aborting now ...
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_cbind.testGenericDispatch#Ignored.WrongCaller#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_cbind.testGenericDispatch#Output.IgnoreErrorContext#
 #{ v <- 1; class(v) <- 'foo'; cbind.foo <- rawToBits; cbind(v) }
 Error in cbind(deparse.level, ...) : argument 'x' must be a raw vector
 
@@ -34312,11 +34312,11 @@ NULL
 [1] "some"
 [1] "test"
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testBinaryOperators#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testBooleanOperators#
 #as.symbol('*') == '*'
 [1] TRUE
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testBinaryOperators#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testBooleanOperators#
 #as.symbol('<-') == '<-'
 [1] TRUE
 
@@ -35451,7 +35451,7 @@ x
    0    1    2    3    4    5    6    7    8
 TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testoperators118#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testoperators118#
 #argv <- list(structure(c('white', 'aquamarine3', 'bisque2', 'blueviolet', 'burlywood4', 'chartreuse4', 'coral4', 'cyan3', 'darkgreen', 'darkorange1', 'aliceblue', 'white', 'white', 'white', 'white', 'chocolate', 'cornflowerblue', 'cyan4', 'darkgrey', 'darkorange2', 'antiquewhite', 'white', 'white', 'white', 'white', 'chocolate1', 'cornsilk', 'darkblue', 'darkkhaki', 'darkorange3', 'antiquewhite1', 'white', 'white', 'white', 'white', 'chocolate2', 'cornsilk1', 'darkcyan', 'darkmagenta', 'darkorange4', 'antiquewhite2', 'azure2', 'blanchedalmond', 'brown3', 'cadetblue3', 'chocolate3', 'cornsilk2', 'darkgoldenrod', 'darkolivegreen', 'darkorchid', 'antiquewhite3', 'azure3', 'blue', 'brown4', 'cadetblue4', 'chocolate4', 'cornsilk3', 'darkgoldenrod1', 'darkolivegreen1', 'darkorchid1', 'antiquewhite4', 'azure4', 'blue1', 'burlywood', 'chartreuse', 'coral', 'cornsilk4', 'darkgoldenrod2', 'darkolivegreen2', 'darkorchid2', 'aquamarine', 'beige', 'blue2', 'burlywood1', 'chartreuse1', 'coral1', 'cyan', 'darkgoldenrod3', 'darkolivegreen3', 'darkorchid3', 'aquamarine1', 'bisque', 'blue3', 'burlywood2', 'chartreuse2', 'coral2', 'cyan1', 'darkgoldenrod4', 'darkolivegreen4', 'darkorchid4', 'aquamarine2', 'bisque1', 'blue4', 'burlywood3', 'chartreuse3', 'coral3', 'cyan2', 'darkgray', 'darkorange', 'darkred'), .Dim = c(10L, 10L), class = 'raster'), 'white');`==`(argv[[1]],argv[[2]]);
        [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10]
  [1,]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
@@ -42671,7 +42671,7 @@ Traceback:
  2: rbind(v)
 An irrecoverable exception occurred. R is aborting now ...
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_rbind.testGenericDispatch#Ignored.WrongCaller#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_rbind.testGenericDispatch#Output.IgnoreErrorContext#
 #{ v <- 1; class(v) <- 'foo'; rbind.foo <- rawToBits; rbind(v) }
 Error in rbind(deparse.level, ...) : argument 'x' must be a raw vector
 
@@ -58143,7 +58143,7 @@ integer(0)
 [41] 26163.27 26367.35 26571.43 26775.51 26979.59 27183.67 27387.76 27591.84
 [49] 27795.92 28000.00
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_seq_along.testWithNonStandardLength#Ignored.Unimplemented#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_seq_along.testWithNonStandardLength#
 #{ assign('length.myclass', function(...) 42, envir=.__S3MethodsTable__.); x <- 1; class(x) <- 'myclass'; res <- seq_along(x); rm('length.myclass', envir=.__S3MethodsTable__.); res }
  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 [26] 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
@@ -61116,7 +61116,7 @@ character(0)
 #argv <- list('p,L,S = (%2d,%2d,%2d): ', TRUE, FALSE, NA); .Internal(sprintf(argv[[1]], argv[[2]], argv[[3]], argv[[4]]))
 [1] "p,L,S = ( 1, 0,NA): "
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_sprintf.testsprintf8#Ignored.Unknown#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_sprintf.testsprintf8#
 #argv <- list('plot_%02g', 1L); .Internal(sprintf(argv[[1]], argv[[2]]))
 [1] "plot_01"
 
@@ -73077,6 +73077,30 @@ f first 1
 #{f<-function(x){UseMethod("f")};f.logical<-function(x){print("logical")};f(TRUE)}
 [1] "logical"
 
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.runRSourceTests#
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/library/base/condition/R/withCallingHandlers0.R") }
+
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.runRSourceTests#Ignored.Unknown#
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/library/base/condition/R/withCallingHandlers1.R") }
+[1] "enter fun1 first"
+[1] "enter handle_cond1 cond1: signalfirst\n"
+[1] "after cond1 restart"
+[1] "enter handle_cond0 cond0: signalfirst\n"
+[1] "continue"
+[1] "exit fun1 first"
+[1] "enter fun1 second"
+[1] "enter handle_cond1 cond1: signalsecond\n"
+[1] "after cond1 restart"
+[1] "enter handle_cond0 cond0: signalsecond\n"
+[1] "continue"
+[1] "exit fun1 second"
+NULL
+[1] "exit fun0"
+
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.testTryCatch#
+#myCondition <- function(message, call=NULL)<<<NEWLINE>>> structure(list(message=message, call=call),<<<NEWLINE>>> class=c("myCondition", "condition"))<<<NEWLINE>>>tryCatch(signalCondition(myCondition("foo")),<<<NEWLINE>>> myCondition=function(cond) {cat("<my>");123L})
+<my>[1] 123
+
 ##com.oracle.truffle.r.test.library.base.TestConditionHandling.testTryCatch#
 #{ e <- simpleError("test error"); f <- function() { tryCatch(1, finally = print("Hello")); stop(e)}; f() }
 [1] "Hello"
@@ -73115,6 +73139,63 @@ Error in f() : fred
 Error in tryCatchList(expr, classes, parentenv, handlers) : fred
 [1] "Hello"
 
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.testTryCatch#
+#{ tryCatch(stop("xyz"), error=function(e) { cat("<error>");123L }, finally=function() { cat("<finally>")}) }
+<error>[1] 123
+
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithCallingHandlers#
+#withCallingHandlers({message("foo");123L},<<<NEWLINE>>> message=function(e) {<<<NEWLINE>>> cat("<msg>")<<<NEWLINE>>> invokeRestart("muffleMessage")<<<NEWLINE>>> })
+<msg>[1] 123
+
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithCallingHandlers#
+#withCallingHandlers({message("foo");123L},<<<NEWLINE>>> message=function(e) {cat("<msg>")})
+<msg>foo
+[1] 123
+
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithCallingHandlers#
+#withCallingHandlers({message("foo");packageStartupMessage("bar");123L},<<<NEWLINE>>> packageStartupMessage=function(e) {<<<NEWLINE>>> cat("<msg>")<<<NEWLINE>>> invokeRestart("muffleMessage")<<<NEWLINE>>> })
+foo
+<msg>[1] 123
+
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithCallingHandlers#Ignored.ImplementationError#
+#withCallingHandlers({warning("foo");123L},<<<NEWLINE>>> warning=function(e) {<<<NEWLINE>>> cat("<warn>")<<<NEWLINE>>> invokeRestart("muffleWarning")<<<NEWLINE>>> })
+<warn>[1] 123
+
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithCallingHandlers#Output.IgnoreWarningContext#
+#withCallingHandlers({warning("foo");123L},<<<NEWLINE>>> warning=function(e) {cat("<warn>")})
+<warn>[1] 123
+Warning message:
+In withCallingHandlers({ : foo
+
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithRestarts#
+#withRestarts(computeRestarts(),<<<NEWLINE>>> foo=function(a,b) c(a,b))
+[[1]]
+<restart: foo >
+
+[[2]]
+<restart: abort >
+
+
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithRestarts#
+#withRestarts(findRestart("foo"),<<<NEWLINE>>> foo=function(a,b) c(a,b))
+<restart: foo >
+
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithRestarts#
+#withRestarts(findRestart("noSuchRestart"),<<<NEWLINE>>> foo=function(a,b) c(a,b))
+NULL
+
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithRestarts#
+#withRestarts({cat("<start>");invokeRestart("foo", 123L, 456L);789L},<<<NEWLINE>>> foo=function(a,b) c(a,b))
+<start>[1] 123 456
+
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithRestarts#
+#withRestarts({cat("<start>");invokeRestart("foo", 123L, 456L);789L},<<<NEWLINE>>> foo=function(a,b) {cat("<first>");invokeRestart("foo", a+1, b+1)},<<<NEWLINE>>> foo=function(a,b) {cat("<second>");c(a,b)})
+<start><first><second>[1] 124 457
+
+##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithRestarts#
+#withRestarts({cat("<start>");invokeRestart("foo", 123L, 456L);789L},<<<NEWLINE>>> foo=list(description="my handler", handler=function(a,b) c(a,b)))
+<start>[1] 123 456
+
 ##com.oracle.truffle.r.test.library.base.TestConnections.testFileWriteReadBin#
 #{ readBin(file("tmptest/com.oracle.truffle.r.test.library.base.conn/wb1", "rb"), 3) }
 numeric(0)
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConditionHandling.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConditionHandling.java
index 2aff030fb231737e9ef235ccda7fe76c4f3a44f8..8d7b2dcf1abc33ede8b98aa6ddc300275d0c5df2 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConditionHandling.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConditionHandling.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -24,9 +24,14 @@ package com.oracle.truffle.r.test.library.base;
 
 import org.junit.Test;
 
-import com.oracle.truffle.r.test.TestBase;
+import com.oracle.truffle.r.test.TestRBase;
 
-public class TestConditionHandling extends TestBase {
+public class TestConditionHandling extends TestRBase {
+
+    @Override
+    public String getTestDir() {
+        return "library/base/condition";
+    }
 
     @Test
     public void testTryCatch() {
@@ -38,5 +43,25 @@ public class TestConditionHandling extends TestBase {
         assertEval(Ignored.Unknown, "{ tryCatch(stop(\"fred\"), error = function(e) e, finally = print(\"Hello\"))}");
         assertEval("{ f <- function() { tryCatch(1, error = function(e) print(\"Hello\")); stop(\"fred\")}; f() }");
         assertEval("{ f <- function() { tryCatch(stop(\"fred\"), error = function(e) print(\"Hello\"))}; f() }");
+        assertEval("{ tryCatch(stop(\"xyz\"), error=function(e) { cat(\"<error>\");123L }, finally=function() { cat(\"<finally>\")}) }");
+    }
+
+    @Test
+    public void testWithRestarts() {
+        assertEval("withRestarts({cat(\"<start>\");invokeRestart(\"foo\", 123L, 456L);789L},\n foo=function(a,b) c(a,b))");
+        assertEval("withRestarts({cat(\"<start>\");invokeRestart(\"foo\", 123L, 456L);789L},\n foo=list(description=\"my handler\", handler=function(a,b) c(a,b)))");
+        assertEval("withRestarts({cat(\"<start>\");invokeRestart(\"foo\", 123L, 456L);789L},\n foo=function(a,b) {cat(\"<first>\");invokeRestart(\"foo\", a+1, b+1)},\n foo=function(a,b) {cat(\"<second>\");c(a,b)})");
+        assertEval("withRestarts(findRestart(\"noSuchRestart\"),\n foo=function(a,b) c(a,b))");
+        assertEval("withRestarts(findRestart(\"foo\"),\n foo=function(a,b) c(a,b))");
+        assertEval("withRestarts(computeRestarts(),\n foo=function(a,b) c(a,b))");
+    }
+
+    @Test
+    public void testWithCallingHandlers() {
+        assertEval(Output.IgnoreWarningContext, "withCallingHandlers({warning(\"foo\");123L},\n warning=function(e) {cat(\"<warn>\")})");
+        assertEval(Ignored.ImplementationError, "withCallingHandlers({warning(\"foo\");123L},\n warning=function(e) {\n cat(\"<warn>\")\n invokeRestart(\"muffleWarning\")\n })");
+        assertEval("withCallingHandlers({message(\"foo\");123L},\n message=function(e) {cat(\"<msg>\")})");
+        assertEval("withCallingHandlers({message(\"foo\");123L},\n message=function(e) {\n cat(\"<msg>\")\n invokeRestart(\"muffleMessage\")\n })");
+        assertEval("withCallingHandlers({message(\"foo\");packageStartupMessage(\"bar\");123L},\n packageStartupMessage=function(e) {\n cat(\"<msg>\")\n invokeRestart(\"muffleMessage\")\n })");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/condition/R/withCallingHandlers0.R b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/condition/R/withCallingHandlers0.R
new file mode 100644
index 0000000000000000000000000000000000000000..85acd59a6af3d527c70000c57430fa4fdf38a0e7
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/condition/R/withCallingHandlers0.R
@@ -0,0 +1,33 @@
+# Ignored
+myCondition <- function(message) structure(list(message=message, call=NULL), class=c("myCondition", "condition"))
+
+handle_myCondition <- function(e) {
+  print(paste("enter handle_myCondition", e))
+  invokeRestart("continue_test")
+  print("after restart")
+}
+
+fun0 <- function(code) {
+      withCallingHandlers({
+      print(code)
+      eval(code)
+      },
+      myCondition = handle_myCondition
+    ); 
+    print("exit fun0") 
+}
+
+fun1 <- function(s) {
+	print(paste("enter fun1", s))
+	withRestarts(
+		{ signalCondition(myCondition(paste0("signal", s))); print("afterSignal") } ,
+		continue_test = function(e) print("continue")
+	)
+	print(paste("exit fun1", s))
+	NULL
+}
+
+fun0({
+	fun1("first")
+	fun1("second")
+})
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/condition/R/withCallingHandlers1.R b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/condition/R/withCallingHandlers1.R
new file mode 100644
index 0000000000000000000000000000000000000000..0345697134cae2a5c8b2e6513b4e799d20987530
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/condition/R/withCallingHandlers1.R
@@ -0,0 +1,45 @@
+# Ignored
+cond0 <- function(message)
+  structure(list(message=message, call=NULL), class=c("cond0", "condition"))
+
+cond1 <- function(message)
+  structure(list(message=message, call=NULL), class=c("cond1", "condition"))
+
+handle_cond0 <- function(e) {
+  print(paste("enter handle_cond0", e))
+  invokeRestart("continue_test")
+  print("after cond0 restart")
+}
+
+handle_cond1 <- function(e) {
+  print(paste("enter handle_cond1", e))
+  signalCondition(e)
+  print("after cond1 restart")
+}
+
+fun0 <- function(code) {
+      withCallingHandlers({
+      print(code)
+      eval(code)
+      },
+      cond0 = handle_cond0,
+      cond1 = handle_cond1
+    ); 
+    print("exit fun0") 
+}
+
+fun1 <- function(s) {
+	print(paste("enter fun1", s))
+	withRestarts(
+		{ signalCondition(cond1(paste0("signal", s)));signalCondition(cond0(paste0("signal", s))); print("afterSignal") } ,
+		continue_test = function(e) print("continue")
+	)
+	print(paste("exit fun1", s))
+	NULL
+}
+
+fun0({
+	fun1("first")
+	fun1("second")
+})
+