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 ed08560e6b131206d1d416026031cdf0a9c24215..7c242944350bfebdceda6e44619e119485e7d8c3 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
@@ -438,7 +438,7 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess {
         // This checks for the specific structure of replacements
         RLanguage replacement = ReplacementDispatchNode.getRLanguage(rl);
         RLanguage elem = replacement == null ? rl : replacement;
-        String string = RDeparse.deparse(elem, RDeparse.DEFAULT_Cutoff, true, RDeparse.KEEPINTEGER, -1);
+        String string = RDeparse.deparse(elem, RDeparse.DEFAULT_CUTOFF, true, RDeparse.KEEPINTEGER, -1);
         return string.split("\n")[0];
     }
 
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguage.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguage.java
index 7b91b6f22401363b844fb8316586e10d63202c20..321e133d8f18d7864f4caa78057a81c77231e6f1 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguage.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguage.java
@@ -146,7 +146,7 @@ public final class TruffleRLanguage extends TruffleLanguage<RContext> implements
             return (String) unwrapped;
         }
         if (unwrapped instanceof RTypedValue) {
-            return RDeparse.deparse(unwrapped);
+            return RDeparse.deparse(unwrapped, RDeparse.MAX_CUTOFF, true, RDeparse.KEEPINTEGER, -1, 1024 * 1024);
         }
         return RRuntime.toString(unwrapped);
     }
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/REmptyMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/REmptyMR.java
new file mode 100644
index 0000000000000000000000000000000000000000..99277bbbcfbee60a210c5d0eacf8c530faa4dae0
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/REmptyMR.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+import com.oracle.truffle.api.interop.CanResolve;
+import com.oracle.truffle.api.interop.MessageResolution;
+import com.oracle.truffle.api.interop.Resolve;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.engine.TruffleRLanguage;
+import com.oracle.truffle.r.runtime.data.REmpty;
+
+@MessageResolution(receiverType = REmpty.class, language = TruffleRLanguage.class)
+public class REmptyMR {
+
+    @Resolve(message = "IS_BOXED")
+    public abstract static class REmptyIsBoxedNode extends Node {
+        protected Object access(@SuppressWarnings("unused") REmpty receiver) {
+            return false;
+        }
+    }
+
+    @Resolve(message = "HAS_SIZE")
+    public abstract static class REmptyHasSizeNode extends Node {
+        protected Object access(@SuppressWarnings("unused") REmpty receiver) {
+            return false;
+        }
+    }
+
+    @Resolve(message = "IS_NULL")
+    public abstract static class REmptyIsNullNode extends Node {
+        protected Object access(@SuppressWarnings("unused") REmpty receiver) {
+            return false;
+        }
+    }
+
+    @CanResolve
+    public abstract static class REmptyCheck extends Node {
+
+        protected static boolean test(TruffleObject receiver) {
+            return receiver instanceof REmpty;
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java
index 53949ae75dfacdee0e86c8c99d7777dd4d1c1589..fa203c367ab06940717e8f66f02b92fb8910150b 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java
@@ -35,16 +35,18 @@ import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.context.RForeignAccessFactory;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RDouble;
+import com.oracle.truffle.r.runtime.data.REmpty;
 import com.oracle.truffle.r.runtime.data.RExternalPtr;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RInteger;
 import com.oracle.truffle.r.runtime.data.RInteropScalar;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RList;
+import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RPairList;
-import com.oracle.truffle.r.runtime.data.RS4Object;
 import com.oracle.truffle.r.runtime.data.RPromise;
+import com.oracle.truffle.r.runtime.data.RS4Object;
 import com.oracle.truffle.r.runtime.data.RSymbol;
 import com.oracle.truffle.r.runtime.data.RTruffleObject;
 import com.oracle.truffle.r.runtime.data.RUnboundValue;
@@ -127,6 +129,10 @@ public final class RForeignAccessFactoryImpl implements RForeignAccessFactory {
             return ActiveBindingMRForeign.ACCESS;
         } else if (obj instanceof RInteropScalar) {
             return RInteropScalarMRForeign.ACCESS;
+        } else if (obj instanceof RMissing) {
+            return RMissingMRForeign.ACCESS;
+        } else if (obj instanceof REmpty) {
+            return REmptyMRForeign.ACCESS;
 
         } else {
             if (obj instanceof RAbstractVector) {
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RMissingMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RMissingMR.java
new file mode 100644
index 0000000000000000000000000000000000000000..656843ed0c421fa4281d00467a90ca850a28203d
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RMissingMR.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+import com.oracle.truffle.api.interop.CanResolve;
+import com.oracle.truffle.api.interop.MessageResolution;
+import com.oracle.truffle.api.interop.Resolve;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.engine.TruffleRLanguage;
+import com.oracle.truffle.r.runtime.data.RMissing;
+
+@MessageResolution(receiverType = RMissing.class, language = TruffleRLanguage.class)
+public class RMissingMR {
+
+    @Resolve(message = "IS_BOXED")
+    public abstract static class RMissingIsBoxedNode extends Node {
+        protected Object access(@SuppressWarnings("unused") RMissing receiver) {
+            return false;
+        }
+    }
+
+    @Resolve(message = "HAS_SIZE")
+    public abstract static class RMissingHasSizeNode extends Node {
+        protected Object access(@SuppressWarnings("unused") RMissing receiver) {
+            return false;
+        }
+    }
+
+    @Resolve(message = "IS_NULL")
+    public abstract static class RMissingIsNullNode extends Node {
+        protected Object access(@SuppressWarnings("unused") RMissing receiver) {
+            return false;
+        }
+    }
+
+    @CanResolve
+    public abstract static class RMissingCheck extends Node {
+
+        protected static boolean test(TruffleObject receiver) {
+            return receiver instanceof RMissing;
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java
index f76be777345451de573b7888e29b873a5e3065d9..ece1e6e7b936fc80923e638d3442b69f5492dd5d 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java
@@ -74,7 +74,7 @@ public abstract class AsCharacter extends RBuiltinNode.Arg2 {
             } else if (elem instanceof RStringVector && ((RStringVector) elem).getLength() == 1) {
                 data[i] = ((RStringVector) elem).getDataAt(0);
             } else {
-                data[i] = RDeparse.deparse(elem, RDeparse.MAX_Cutoff, true, RDeparse.SIMPLEDEPARSE, -1);
+                data[i] = RDeparse.deparse(elem, RDeparse.MAX_CUTOFF, true, RDeparse.SIMPLEDEPARSE, -1);
             }
             if (RRuntime.isNA(data[i])) {
                 complete = RDataFactory.INCOMPLETE_VECTOR;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
index eb9ccf0a2de6fad41246661226886de25129841d..2030c3ecb77f0d70debd5bc68b326daa7d802d3c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
@@ -102,6 +102,8 @@ import com.oracle.truffle.r.nodes.builtin.fastr.FastRRefCountInfo;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRRefCountInfoNodeGen;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRSlotAssign;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRSlotAssignNodeGen;
+import com.oracle.truffle.r.nodes.builtin.fastr.FastRSourceInfo;
+import com.oracle.truffle.r.nodes.builtin.fastr.FastRSourceInfoNodeGen;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRStackTrace;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRStackTraceNodeGen;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRStats.FastRProfAttr;
@@ -387,6 +389,7 @@ public class BasePackage extends RBuiltinPackage {
         add(FastRInterop.ToShort.class, FastRInteropFactory.ToShortNodeGen::create);
         add(FastRRefCountInfo.class, FastRRefCountInfoNodeGen::create);
         add(FastRPkgSource.class, FastRPkgSourceNodeGen::create);
+        add(FastRSourceInfo.class, FastRSourceInfoNodeGen::create);
         add(FastRStackTrace.class, FastRStackTraceNodeGen::create);
         add(FastRProfAttr.class, FastRStatsFactory.FastRProfAttrNodeGen::create);
         add(FastRProfTypecounts.class, FastRStatsFactory.FastRProfTypecountsNodeGen::create);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DPut.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DPut.java
index d0361a493fd9fba3da09709a9e967e9334354574..13f43b742006fdade1fcc006389fc993d931ed34 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DPut.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DPut.java
@@ -52,7 +52,7 @@ public abstract class DPut extends RBuiltinNode.Arg3 {
     @Specialization
     @TruffleBoundary
     protected Object dput(Object x, int file, int opts) {
-        String string = RDeparse.deparse(x, RDeparse.DEFAULT_Cutoff, true, opts, -1);
+        String string = RDeparse.deparse(x, RDeparse.DEFAULT_CUTOFF, true, opts, -1);
         try (RConnection openConn = RConnection.fromIndex(file).forceOpen("wt")) {
             openConn.writeString(string, true);
         } catch (IOException ex) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Deparse.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Deparse.java
index fdd7a26615bc8c8b22a40276dca4f24dcdb20cc5..a258e75f8ed951e14f99225759e4f55a1e34de67 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Deparse.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Deparse.java
@@ -42,9 +42,9 @@ public abstract class Deparse extends RBuiltinNode.Arg5 {
     @TruffleBoundary
     protected RStringVector deparse(Object expr, int widthCutoffArg, boolean backtick, int control, int nlines) {
         int widthCutoff = widthCutoffArg;
-        if (widthCutoff == RRuntime.INT_NA || widthCutoff < RDeparse.MIN_Cutoff || widthCutoff > RDeparse.MAX_Cutoff) {
+        if (widthCutoff == RRuntime.INT_NA || widthCutoff < RDeparse.MIN_CUTOFF || widthCutoff > RDeparse.MAX_CUTOFF) {
             warning(RError.Message.DEPARSE_INVALID_CUTOFF);
-            widthCutoff = RDeparse.DEFAULT_Cutoff;
+            widthCutoff = RDeparse.DEFAULT_CUTOFF;
         }
 
         String[] data = RDeparse.deparse(expr, widthCutoff, backtick, control, nlines).split("\n");
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/LanguagePrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/LanguagePrinter.java
index 82ddd8f26ff0f5bda65d6705a7185f065090e358..bc050bed9d46661b295b32889e4b192304e8daa8 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/LanguagePrinter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/LanguagePrinter.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
@@ -39,6 +39,6 @@ final class LanguagePrinter extends AbstractValuePrinter<RLanguage> {
     @Override
     @TruffleBoundary
     protected void printValue(RLanguage language, PrintContext printCtx) throws IOException {
-        printCtx.output().print(RDeparse.deparse(language, RDeparse.DEFAULT_Cutoff, true, RDeparse.KEEPINTEGER, -1));
+        printCtx.output().print(RDeparse.deparse(language, RDeparse.DEFAULT_CUTOFF, true, RDeparse.KEEPINTEGER, -1));
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/SymbolPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/SymbolPrinter.java
index 19451dfcbf5e7dc936254d14ef4d57b7af44566e..0bf416f5573f48cfaec6cfc6e328d1531e4f90a1 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/SymbolPrinter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/SymbolPrinter.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
@@ -39,6 +39,6 @@ final class SymbolPrinter extends AbstractValuePrinter<RSymbol> {
     @Override
     @TruffleBoundary
     protected void printValue(RSymbol value, PrintContext printCtx) throws IOException {
-        printCtx.output().print(RDeparse.deparse(value, RDeparse.DEFAULT_Cutoff, true, RDeparse.SIMPLEDEPARSE, -1));
+        printCtx.output().print(RDeparse.deparse(value, RDeparse.DEFAULT_CUTOFF, true, RDeparse.SIMPLEDEPARSE, -1));
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSourceInfo.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSourceInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed3430a7b325f4ad1d1f6abd39ecc8fb61e57102
--- /dev/null
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSourceInfo.java
@@ -0,0 +1,64 @@
+/*
+ * 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
+ * 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.nodes.builtin.fastr;
+
+import static com.oracle.truffle.r.runtime.RVisibility.ON;
+import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
+
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.source.SourceSection;
+import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.runtime.builtins.RBehavior;
+import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.data.RFunction;
+import com.oracle.truffle.r.runtime.data.RNull;
+
+/**
+ * Allows to show the actual location of the source section of a provided function.
+ */
+@RBuiltin(name = ".fastr.srcinfo", visibility = ON, kind = PRIMITIVE, parameterNames = "fun", behavior = RBehavior.IO)
+public abstract class FastRSourceInfo extends RBuiltinNode.Arg1 {
+
+    static {
+        Casts.noCasts(FastRSourceInfo.class);
+    }
+
+    @Specialization
+    public Object srcInfo(@SuppressWarnings("unused") RNull fun) {
+        return RNull.instance;
+    }
+
+    @Specialization
+    public Object srcInfo(RFunction fun) {
+        SourceSection ss = fun.getRootNode().getSourceSection();
+        if (ss != null) {
+            String path = ss.getSource().getPath();
+            if (path != null) {
+                return path + "#" + ss.getStartLine();
+            } else {
+                return ss.getSource().getName();
+            }
+        }
+        return RNull.instance;
+    }
+}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java
index 1f317668577066be9db826c1ae0ee1dce1e65fa2..0a8d63ec7ed252318654e764ef1e79573fbcfcf3 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java
@@ -150,7 +150,7 @@ public abstract class BinaryBooleanNode extends RBuiltinNode.Arg2 {
     }
 
     private static RString deparseSymbolOrLang(Object val) {
-        return RString.valueOf(RDeparse.deparse(val, RDeparse.MAX_Cutoff, false, RDeparse.KEEPINTEGER, -1));
+        return RString.valueOf(RDeparse.deparse(val, RDeparse.MAX_CUTOFF, false, RDeparse.KEEPINTEGER, -1));
     }
 
     protected BinaryBooleanNode createRecursive() {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java
index 44d6c5ad366038c4e4388ca02728ea7d68941b77..272cc7314196453d4d6182ff083e8ee6f75bdb81 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java
@@ -86,9 +86,9 @@ public class RDeparse {
     public static final int SIMPLEDEPARSE = 0;
     public static final int DEFAULTDEPARSE = 65; /* KEEPINTEGER | KEEPNA, used for calls */
 
-    public static final int MIN_Cutoff = 20;
-    public static final int MAX_Cutoff = 500;
-    public static final int DEFAULT_Cutoff = 60;
+    public static final int MIN_CUTOFF = 20;
+    public static final int MAX_CUTOFF = 500;
+    public static final int DEFAULT_CUTOFF = 60;
     public static final char BACKTICK = '`';
     public static final char DQUOTE = '"';
 
@@ -264,22 +264,29 @@ public class RDeparse {
 
         private final ArrayList<SourceSectionElement> sources;
 
-        private final int cutoff;
+        private final int listCutoff;
+        private final int debugCutoff;
         private final boolean backtick;
         private int opts;
-        @SuppressWarnings("unused") private final int nlines;
+        private final int nlines;
 
         private int inCurly = 0;
         private int inList = 0;
         private int indent = 0;
         private int lastLineStart = 0;
+        private int curLine = 1;
 
         DeparseVisitor(boolean storeSource, int cutoff, boolean backtick, int opts, int nlines) {
-            this.cutoff = cutoff;
+            this(storeSource, cutoff, backtick, opts, nlines, -1);
+        }
+
+        DeparseVisitor(boolean storeSource, int cutoff, boolean backtick, int opts, int nlines, int debugCutoff) {
+            this.listCutoff = cutoff;
             this.backtick = backtick;
             this.opts = opts;
             this.nlines = nlines;
             this.sources = storeSource ? new ArrayList<>() : null;
+            this.debugCutoff = debugCutoff;
         }
 
         public String getContents() {
@@ -304,13 +311,22 @@ public class RDeparse {
             return (opts & QUOTEEXPRESSIONS) != 0;
         }
 
+        private void checkLength(int nchar) {
+            if (debugCutoff >= 0 && sb.length() + nchar > debugCutoff) {
+                throw new MaxLengthReachedException();
+            }
+        }
+
         private DeparseVisitor append(char ch) {
             assert ch != '\n';
+            checkLength(1);
             sb.append(ch);
             return this;
         }
 
         private DeparseVisitor append(String str) {
+            assert !str.contains("\n");
+            checkLength(str.length());
             sb.append(str);
             return this;
         }
@@ -357,6 +373,7 @@ public class RDeparse {
             if (!Files.exists(path)) {
                 try (BufferedWriter bw = Files.newBufferedWriter(path, CREATE_NEW, WRITE)) {
                     bw.write(sb.toString());
+                    bw.newLine();
                 }
             }
             return path;
@@ -408,13 +425,20 @@ public class RDeparse {
         public DeparseVisitor append(RSyntaxElement element) {
             try (C c = withContext(element)) {
                 visitor.accept(element);
+            } catch (AbortDeparsingException e) {
+                // stop deparsing; indicate that there is something missing
+                sb.append("...");
             }
             return this;
         }
 
         private void printline() {
             sb.append("\n");
+            curLine++;
             lastLineStart = sb.length();
+            if (nlines > 0 && curLine >= nlines) {
+                throw new MaxLinesReachedException();
+            }
             for (int i = 0; i < indent; i++) {
                 sb.append(i < 4 ? "    " : "  ");
             }
@@ -438,9 +462,9 @@ public class RDeparse {
             return null;
         }
 
-        private boolean linebreak(boolean lbreak) {
+        private boolean listLinebreak(boolean lbreak) {
             boolean result = lbreak;
-            if ((sb.length() - lastLineStart) > cutoff) {
+            if ((sb.length() - lastLineStart) > listCutoff) {
                 if (!lbreak) {
                     result = true;
                     indent++;
@@ -721,7 +745,7 @@ public class RDeparse {
                     if (i++ > 0) {
                         append(", ");
                     }
-                    lbreak = linebreak(lbreak);
+                    lbreak = listLinebreak(lbreak);
                     if (arglist.getTag() != RNull.instance) {
                         String argName = ((RSymbol) arglist.getTag()).getName();
                         if (!argName.isEmpty()) {
@@ -786,7 +810,7 @@ public class RDeparse {
                 if (i > start) {
                     append(", ");
                 }
-                lbreak = linebreak(lbreak);
+                lbreak = listLinebreak(lbreak);
                 RSyntaxElement argument = args[i];
                 String name = signature.getName(i);
 
@@ -823,22 +847,27 @@ public class RDeparse {
             Object value = RRuntime.asAbstractVector(v);
             assert value instanceof RTypedValue : v.getClass();
 
-            RSyntaxElement element;
-            if (value instanceof RSymbol) {
-                element = RSyntaxLookup.createDummyLookup(RSyntaxNode.INTERNAL, ((RSymbol) value).getName(), false);
-            } else if (value instanceof RLanguage) {
-                element = ((RLanguage) value).getRep().asRSyntaxNode();
-            } else if (value instanceof RMissing) {
-                element = RSyntaxLookup.createDummyLookup(null, "", false);
-            } else {
-                return appendConstant(value);
-            }
-            if (!quoteExpressions() || element instanceof RSyntaxConstant) {
-                append(element);
-            } else {
-                append("quote(");
-                append(element);
-                append(')');
+            try {
+                RSyntaxElement element;
+                if (value instanceof RSymbol) {
+                    element = RSyntaxLookup.createDummyLookup(RSyntaxNode.INTERNAL, ((RSymbol) value).getName(), false);
+                } else if (value instanceof RLanguage) {
+                    element = ((RLanguage) value).getRep().asRSyntaxNode();
+                } else if (value instanceof RMissing) {
+                    element = RSyntaxLookup.createDummyLookup(null, "", false);
+                } else {
+                    return appendConstant(value);
+                }
+                if (!quoteExpressions() || element instanceof RSyntaxConstant) {
+                    append(element);
+                } else {
+                    append("quote(");
+                    append(element);
+                    append(')');
+                }
+            } catch (AbortDeparsingException e) {
+                // stop deparsing; indicate that there is something missing
+                sb.append("...");
             }
             return this;
         }
@@ -964,7 +993,7 @@ public class RDeparse {
                 if (i > 0) {
                     append(", ");
                 }
-                lbreak = linebreak(lbreak);
+                lbreak = listLinebreak(lbreak);
                 if (snames != null) {
                     append(quotify(snames.getDataAt(i), '\"'));
                     append(" = ");
@@ -1044,12 +1073,12 @@ public class RDeparse {
 
     @TruffleBoundary
     public static String deparseSyntaxElement(RSyntaxElement element) {
-        return new DeparseVisitor(false, RDeparse.MAX_Cutoff, true, KEEPINTEGER, -1).append(element).getContents();
+        return new DeparseVisitor(false, RDeparse.MAX_CUTOFF, true, KEEPINTEGER, -1).append(element).getContents();
     }
 
     @TruffleBoundary
     public static String deparse(Object value) {
-        return new DeparseVisitor(false, RDeparse.MAX_Cutoff, true, KEEPINTEGER, -1).appendValue(value).getContents();
+        return new DeparseVisitor(false, RDeparse.MAX_CUTOFF, true, KEEPINTEGER, -1).appendValue(value).getContents();
     }
 
     @TruffleBoundary
@@ -1057,6 +1086,11 @@ public class RDeparse {
         return new DeparseVisitor(false, cutoff, backtick, opts, nlines).appendValue(expr).getContents();
     }
 
+    @TruffleBoundary
+    public static String deparse(Object expr, int cutoff, boolean backtick, int opts, int nlines, int debugCutoff) {
+        return new DeparseVisitor(false, cutoff, backtick, opts, nlines, debugCutoff).appendValue(expr).getContents();
+    }
+
     /**
      * Ensure that {@code node} has a {@link SourceSection} by deparsing if necessary.
      */
@@ -1072,11 +1106,11 @@ public class RDeparse {
                 }
             }
             // try to generate the source from the root node and hopefully it includes this node
-            new DeparseVisitor(true, RDeparse.MAX_Cutoff, false, -1, 0).append(nodeToFixup).fixupSources();
+            new DeparseVisitor(true, RDeparse.MAX_CUTOFF, false, -1, 0).append(nodeToFixup).fixupSources();
 
             // if not, we have to deparse the node in isolation
             if (node.getLazySourceSection() == RSyntaxNode.LAZY_DEPARSE) {
-                new DeparseVisitor(true, RDeparse.MAX_Cutoff, false, -1, 0).append(node).fixupSources();
+                new DeparseVisitor(true, RDeparse.MAX_CUTOFF, false, -1, 0).append(node).fixupSources();
             }
             assert node.getLazySourceSection() != RSyntaxNode.LAZY_DEPARSE;
         }
@@ -1136,4 +1170,16 @@ public class RDeparse {
             return 0;
         }
     }
+
+    @SuppressWarnings("serial")
+    private static class AbortDeparsingException extends RuntimeException {
+    }
+
+    @SuppressWarnings("serial")
+    private static final class MaxLinesReachedException extends AbortDeparsingException {
+    }
+
+    @SuppressWarnings("serial")
+    private static final class MaxLengthReachedException extends AbortDeparsingException {
+    }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/RScope.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/RScope.java
index d44fd73c8796a4725c679e55032c7030a1be91f6..f338a25c9ac534364d623a9b5a338e3256d0da13 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/RScope.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/RScope.java
@@ -31,6 +31,7 @@ import com.oracle.truffle.api.interop.Resolve;
 import com.oracle.truffle.api.interop.TruffleObject;
 import com.oracle.truffle.api.interop.UnknownIdentifierException;
 import com.oracle.truffle.api.interop.UnsupportedMessageException;
+import com.oracle.truffle.api.interop.UnsupportedTypeException;
 import com.oracle.truffle.api.metadata.ScopeProvider.AbstractScope;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
@@ -39,6 +40,7 @@ import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RStringVector;
+import com.oracle.truffle.r.runtime.data.RTypedValue;
 import com.oracle.truffle.r.runtime.env.REnvironment.PutException;
 
 /**
@@ -103,10 +105,9 @@ public final class RScope extends AbstractScope {
 
     @Override
     protected AbstractScope findParent() {
-        if (this.env == REnvironment.emptyEnv()) {
+        if (env == REnvironment.emptyEnv() || env.getParent() == REnvironment.emptyEnv()) {
             return null;
         }
-
         return new RScope(env.getParent());
     }
 
@@ -167,11 +168,13 @@ public final class RScope extends AbstractScope {
 
                 @TruffleBoundary
                 public Object access(VariablesMapObject varMap) {
+                    String[] names;
                     if (varMap.argumentsOnly) {
-                        return new ArgumentNamesObject(collectArgs(varMap.env));
+                        names = collectArgs(varMap.env);
                     } else {
-                        return new VariableNamesObject(varMap.env);
+                        names = ls(varMap.env);
                     }
+                    return new ArgumentNamesObject(names);
                 }
             }
 
@@ -223,6 +226,9 @@ public final class RScope extends AbstractScope {
                     if (varMap.env == null) {
                         throw UnsupportedMessageException.raise(Message.WRITE);
                     }
+                    if (!(value instanceof RTypedValue)) {
+                        throw UnsupportedTypeException.raise(new Object[]{value});
+                    }
                     try {
                         varMap.env.put(name, value);
                         return value;
@@ -235,60 +241,6 @@ public final class RScope extends AbstractScope {
         }
     }
 
-    static final class VariableNamesObject implements TruffleObject {
-
-        private final REnvironment env;
-
-        private VariableNamesObject(REnvironment env) {
-            this.env = env;
-        }
-
-        @Override
-        public ForeignAccess getForeignAccess() {
-            return VariableNamesMessageResolutionForeign.ACCESS;
-        }
-
-        public static boolean isInstance(TruffleObject obj) {
-            return obj instanceof VariableNamesObject;
-        }
-
-        @MessageResolution(receiverType = VariableNamesObject.class)
-        static final class VariableNamesMessageResolution {
-
-            @Resolve(message = "HAS_SIZE")
-            abstract static class VarNamesHasSizeNode extends Node {
-
-                @SuppressWarnings("unused")
-                public Object access(VariableNamesObject varNames) {
-                    return true;
-                }
-            }
-
-            @Resolve(message = "GET_SIZE")
-            abstract static class VarNamesGetSizeNode extends Node {
-
-                public Object access(VariableNamesObject varNames) {
-                    return ls(varNames.env).length;
-                }
-            }
-
-            @Resolve(message = "READ")
-            abstract static class VarNamesReadNode extends Node {
-
-                @TruffleBoundary
-                public Object access(VariableNamesObject varNames, int index) {
-                    String[] names = ls(varNames.env);
-                    if (index >= 0 && index < names.length) {
-                        return names[index];
-                    } else {
-                        throw UnknownIdentifierException.raise(Integer.toString(index));
-                    }
-                }
-            }
-
-        }
-    }
-
     static final class ArgumentNamesObject implements TruffleObject {
 
         private final String[] names;
@@ -331,8 +283,9 @@ public final class RScope extends AbstractScope {
 
                 @TruffleBoundary
                 public Object access(ArgumentNamesObject varNames, int index) {
-                    if (index >= 0 && index < varNames.names.length) {
-                        return varNames.names[index];
+                    String[] names = varNames.names;
+                    if (index >= 0 && index < names.length) {
+                        return names[index];
                     } else {
                         throw UnknownIdentifierException.raise(Integer.toString(index));
                     }