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 623538e2f409cb76e2c2d662cac50933662e7a27..9fbc99886e15a80afb408dab067cabdf1ea63e59 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
@@ -51,6 +51,7 @@ import com.oracle.truffle.r.library.graphics.RGraphics;
 import com.oracle.truffle.r.nodes.RASTBuilder;
 import com.oracle.truffle.r.nodes.RASTUtils;
 import com.oracle.truffle.r.nodes.access.ConstantNode;
+import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinPackages;
 import com.oracle.truffle.r.nodes.builtin.base.printer.ValuePrinterNode;
 import com.oracle.truffle.r.nodes.control.BreakException;
@@ -93,6 +94,7 @@ import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RShareable;
 import com.oracle.truffle.r.runtime.data.RStringVector;
+import com.oracle.truffle.r.runtime.data.RSymbol;
 import com.oracle.truffle.r.runtime.data.RTypedValue;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
@@ -365,8 +367,11 @@ final class REngine implements Engine, Engine.Timings {
     public Object eval(RExpression exprs, REnvironment envir, RCaller caller) {
         Object result = RNull.instance;
         for (int i = 0; i < exprs.getLength(); i++) {
-            Object obj = RASTUtils.checkForRSymbol(exprs.getDataAt(i));
-            if (obj instanceof RLanguage) {
+            Object obj = exprs.getDataAt(i);
+            if (obj instanceof RSymbol) {
+                result = ReadVariableNode.lookupAny(((RSymbol) obj).getName(), envir.getFrame(), false);
+                caller.setVisibility(true);
+            } else if (obj instanceof RLanguage) {
                 result = evalNode(((RLanguage) obj).getRep().asRSyntaxNode(), envir, caller);
             } else {
                 result = obj;
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java
index 288c55c5bfcdbb4e365694e95972cb22672750b9..74cf21b87fcb1104e4b3d67104eec9f6400a142c 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java
@@ -261,7 +261,9 @@ public abstract class Rbinom extends RExternalBuiltinNode.Arg3 {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.toDouble(0).toDouble(1).toDouble(2);
+        casts.arg(0).asDoubleVector();
+        casts.arg(1).asDoubleVector();
+        casts.arg(2).asDoubleVector();
     }
 
     @Specialization
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java
index 4e07b802a5632df442b9bed9d2693aa25ce2c332..d6c1c25102fd42f084fee09109a1f3e796c46b28 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java
@@ -33,8 +33,8 @@ public abstract class Rnorm extends RExternalBuiltinNode.Arg3 {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.toDouble(1);
-        casts.toDouble(2);
+        casts.arg(1).asDoubleVector();
+        casts.arg(2).asDoubleVector();
     }
 
     @Specialization
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java
index 98b03fb580a2ac7b74c84deaf1447b644bef0ec5..033d9398750787d201d91e3ba289c0ef4afaf9c7 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java
@@ -12,6 +12,8 @@
  */
 package com.oracle.truffle.r.library.stats;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
+
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.nodes.Node;
@@ -99,7 +101,11 @@ public final class StatsFunctions {
 
         @Override
         protected void createCasts(CastBuilder casts) {
-            casts.toDouble(0).toDouble(1).toDouble(2).firstBoolean(3).firstBoolean(4);
+            casts.arg(0).asDoubleVector();
+            casts.arg(1).asDoubleVector();
+            casts.arg(2).asDoubleVector();
+            casts.arg(3).asLogicalVector().findFirst().map(toBoolean());
+            casts.arg(4).asLogicalVector().findFirst().map(toBoolean());
         }
 
         @Specialization
@@ -121,7 +127,10 @@ public final class StatsFunctions {
 
         @Override
         protected void createCasts(CastBuilder casts) {
-            casts.toDouble(0).toDouble(1).toDouble(2).firstBoolean(3);
+            casts.arg(0).asDoubleVector();
+            casts.arg(1).asDoubleVector();
+            casts.arg(2).asDoubleVector();
+            casts.arg(3).asLogicalVector().findFirst().map(toBoolean());
         }
 
         @Specialization
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Args.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Args.java
index fbddf40edc89997b91ceba3ffd47500849c63733..12c5a5c6a3fd8aa93e02f1af5085dbdbdccad129 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Args.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Args.java
@@ -70,9 +70,8 @@ public abstract class Args extends RBuiltinNode {
             CompilerDirectives.transferToInterpreterAndInvalidate();
             getNode = insert(GetNodeGen.create(null));
             parentFrameNode = insert(ParentFrameNodeGen.create(null));
-
         }
-        return args((RFunction) getNode.execute(frame, funName, parentFrameNode.execute(frame, 1), RType.Function.getName(), true));
+        return args((RFunction) getNode.execute(frame, funName.getDataAt(0), parentFrameNode.execute(frame, 1), RType.Function.getName(), true));
     }
 
     @Specialization
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Assign.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Assign.java
index fb048c46517464087273140fea12d508979db649..9bf1e7f47e64ea1b3cedd2c1c98a218beeb572b1 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Assign.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Assign.java
@@ -39,7 +39,6 @@ import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RShareable;
-import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.env.REnvironment.PutException;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
@@ -57,8 +56,9 @@ import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 @RBuiltin(name = "assign", visibility = OFF, kind = INTERNAL, parameterNames = {"x", "value", "envir", "inherits"}, behavior = COMPLEX)
 public abstract class Assign extends RBuiltinNode {
 
+    public abstract Object execute(String x, Object value, REnvironment envir, byte inherits);
+
     private final BranchProfile errorProfile = BranchProfile.create();
-    private final BranchProfile warningProfile = BranchProfile.create();
     private final boolean direct;
 
     protected Assign() {
@@ -73,24 +73,6 @@ public abstract class Assign extends RBuiltinNode {
         return direct ? this : RError.SHOW_CALLER;
     }
 
-    /**
-     * TODO: This method becomes obsolete when Assign and AssignFastPaths are modified to have the
-     * (String, Object, REnvironment, boolean) signature.
-     */
-    private String checkVariable(RAbstractStringVector xVec) {
-        int len = xVec.getLength();
-        if (len == 1) {
-            return xVec.getDataAt(0);
-        } else if (len == 0) {
-            errorProfile.enter();
-            throw RError.error(errorContext(), RError.Message.INVALID_FIRST_ARGUMENT);
-        } else {
-            warningProfile.enter();
-            RError.warning(errorContext(), RError.Message.ONLY_FIRST_VARIABLE_NAME);
-            return xVec.getDataAt(0);
-        }
-    }
-
     @Override
     protected void createCasts(CastBuilder casts) {
         casts.arg("x").asStringVector().shouldBe(singleElement(), RError.Message.ONLY_FIRST_VARIABLE_NAME).findFirst(RError.Message.INVALID_FIRST_ARGUMENT);
@@ -106,11 +88,10 @@ public abstract class Assign extends RBuiltinNode {
      * The general case that requires searching the environment hierarchy.
      */
     @Specialization
-    protected Object assign(RAbstractStringVector xVec, Object value, REnvironment envir, byte inherits, //
+    protected Object assign(String x, Object value, REnvironment envir, byte inherits, //
                     @Cached("createBinaryProfile()") ConditionProfile inheritsProfile,
                     @Cached("createBinaryProfile()") ConditionProfile isShareableProfile,
                     @Cached("createBinaryProfile()") ConditionProfile isRefCountUpdateable) {
-        String x = checkVariable(xVec);
         REnvironment env = envir;
         if (inheritsProfile.profile(RRuntime.fromLogical(inherits))) {
             while (env != REnvironment.emptyEnv()) {
@@ -145,4 +126,5 @@ public abstract class Assign extends RBuiltinNode {
         }
         return value;
     }
+
 }
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 46def37dbc60490a3042b9f83b9a077f1b35d68d..d3431b187ae9a8d9d5d453ed2c25b5ef6665471f 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
@@ -30,8 +30,6 @@ import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.binary.BinaryArithmeticNodeGen;
 import com.oracle.truffle.r.nodes.binary.BinaryBooleanNodeGen;
 import com.oracle.truffle.r.nodes.binary.BinaryBooleanScalarNodeGen;
-import com.oracle.truffle.r.nodes.binary.ColonNode;
-import com.oracle.truffle.r.nodes.binary.ColonNodeGen;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinPackage;
 import com.oracle.truffle.r.nodes.builtin.base.fastpaths.AssignFastPathNodeGen;
 import com.oracle.truffle.r.nodes.builtin.base.fastpaths.ExistsFastPathNodeGen;
@@ -214,7 +212,7 @@ public class BasePackage extends RBuiltinPackage {
         add(Ceiling.class, CeilingNodeGen::create);
         add(CharMatch.class, CharMatchNodeGen::create);
         add(Col.class, ColNodeGen::create);
-        add(ColonNode.class, ColonNodeGen::create);
+        add(Colon.class, ColonNodeGen::create);
         add(ColMeans.class, ColMeansNodeGen::create);
         add(ColSums.class, ColSumsNodeGen::create);
         add(Combine.class, CombineNodeGen::create);
@@ -317,7 +315,7 @@ public class BasePackage extends RBuiltinPackage {
         add(EnvFunctions.Search.class, EnvFunctionsFactory.SearchNodeGen::create);
         add(EnvFunctions.SetParentEnv.class, EnvFunctionsFactory.SetParentEnvNodeGen::create);
         add(EnvFunctions.UnlockBinding.class, EnvFunctionsFactory.UnlockBindingNodeGen::create);
-        add(EvalFunctions.Eval.class, EvalFunctionsFactory.EvalNodeGen::create);
+        add(Eval.class, EvalNodeGen::create);
         add(WithVisible.class, WithVisibleNodeGen::create);
         add(Exists.class, ExistsNodeGen::create);
         add(Expression.class, ExpressionNodeGen::create);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BitwiseFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BitwiseFunctions.java
index af20b5ecb6dbe2a1a8a7aee7bb79023e92606933..91ae3bcef8477a3601a7730d84f3fb443f90213a 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BitwiseFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BitwiseFunctions.java
@@ -11,7 +11,14 @@
 
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.anyValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asIntegerVector;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asStringVector;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.chain;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.doubleValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.integerValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.shouldBe;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
@@ -22,8 +29,6 @@ import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.LoopConditionProfile;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.nodes.builtin.casts.Filter;
-import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep;
 import com.oracle.truffle.r.nodes.unary.TypeofNode;
 import com.oracle.truffle.r.nodes.unary.TypeofNodeGen;
 import com.oracle.truffle.r.runtime.RError;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/ColonNode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Colon.java
similarity index 57%
rename from com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/ColonNode.java
rename to com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Colon.java
index 25e43f2996a787a892539a7dbee7b0f90ff098a9..4616f2f1fd6cfc159c59178b0522d2e83a62ee52 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/ColonNode.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Colon.java
@@ -20,7 +20,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-package com.oracle.truffle.r.nodes.binary;
+package com.oracle.truffle.r.nodes.builtin.base;
 
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
@@ -28,11 +28,14 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.api.nodes.NodeCost;
+import com.oracle.truffle.api.nodes.NodeInfo;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
-import com.oracle.truffle.r.nodes.binary.ColonNodeGen.ColonCastNodeGen;
-import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.nodes.builtin.base.ColonNodeGen.ColonCastNodeGen;
+import com.oracle.truffle.r.nodes.builtin.base.ColonNodeGen.ColonInternalNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
@@ -41,91 +44,100 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RDoubleSequence;
 import com.oracle.truffle.r.runtime.data.RIntSequence;
+import com.oracle.truffle.r.runtime.data.RSequence;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 
 @RBuiltin(name = ":", kind = PRIMITIVE, parameterNames = {"", ""}, behavior = PURE)
-public abstract class ColonNode extends RBuiltinNode {
-
-    private final BranchProfile naCheckErrorProfile = BranchProfile.create();
-    private final NACheck leftNA = NACheck.create();
-    private final NACheck rightNA = NACheck.create();
-
-    @Override
-    protected void createCasts(CastBuilder casts) {
-        // These casts should not be custom, but they are very hard to get right in a generic way.
-        // Also, the proper warnings cannot be produced at the moment.
-        casts.arg(0).defaultError(this, Message.ARGUMENT_LENGTH_0).customNode(() -> ColonCastNodeGen.create());
-        casts.arg(1).defaultError(this, Message.ARGUMENT_LENGTH_0).customNode(() -> ColonCastNodeGen.create());
+public abstract class Colon extends RBuiltinNode {
+
+    @Child private ColonCastNode leftCast = ColonCastNodeGen.create();
+    @Child private ColonCastNode rightCast = ColonCastNodeGen.create();
+    @Child private ColonInternal internal = ColonInternalNodeGen.create();
+
+    @Specialization
+    protected RSequence colon(Object left, Object right) {
+        return internal.execute(leftCast.execute(left), rightCast.execute(right));
     }
 
-    private void naCheck(boolean na) {
-        if (na) {
-            naCheckErrorProfile.enter();
-            throw RError.error(this, RError.Message.NA_OR_NAN);
+    @NodeInfo(cost = NodeCost.NONE)
+    abstract static class ColonInternal extends Node {
+
+        private final NACheck leftNA = NACheck.create();
+        private final NACheck rightNA = NACheck.create();
+
+        private final BranchProfile naCheckErrorProfile = BranchProfile.create();
+
+        abstract RSequence execute(Object left, Object right);
+
+        private void naCheck(boolean na) {
+            if (na) {
+                naCheckErrorProfile.enter();
+                throw RError.error(this, RError.Message.NA_OR_NAN);
+            }
         }
-    }
 
-    @Specialization(guards = "left <= right")
-    protected RIntSequence colonAscending(int left, int right) {
-        leftNA.enable(left);
-        rightNA.enable(right);
-        naCheck(leftNA.check(left) || rightNA.check(right));
-        return RDataFactory.createAscendingRange(left, right);
-    }
+        protected static double asDouble(int intValue) {
+            return intValue;
+        }
 
-    @Specialization(guards = "left > right")
-    protected RIntSequence colonDescending(int left, int right) {
-        leftNA.enable(left);
-        rightNA.enable(right);
-        naCheck(leftNA.check(left) || rightNA.check(right));
-        return RDataFactory.createDescendingRange(left, right);
-    }
+        @Specialization(guards = "left <= right")
+        protected RIntSequence colonAscending(int left, int right) {
+            leftNA.enable(left);
+            rightNA.enable(right);
+            naCheck(leftNA.check(left) || rightNA.check(right));
+            return RDataFactory.createAscendingRange(left, right);
+        }
 
-    @Specialization(guards = "asDouble(left) <= right")
-    protected RIntSequence colonAscending(int left, double right) {
-        leftNA.enable(left);
-        naCheck(leftNA.check(left) || RRuntime.isNAorNaN(right));
-        return RDataFactory.createAscendingRange(left, (int) right);
-    }
+        @Specialization(guards = "left > right")
+        protected RIntSequence colonDescending(int left, int right) {
+            leftNA.enable(left);
+            rightNA.enable(right);
+            naCheck(leftNA.check(left) || rightNA.check(right));
+            return RDataFactory.createDescendingRange(left, right);
+        }
 
-    @Specialization(guards = "asDouble(left) > right")
-    protected RIntSequence colonDescending(int left, double right) {
-        leftNA.enable(left);
-        naCheck(leftNA.check(left) || RRuntime.isNAorNaN(right));
-        return RDataFactory.createDescendingRange(left, (int) right);
-    }
+        @Specialization(guards = "asDouble(left) <= right")
+        protected RIntSequence colonAscending(int left, double right) {
+            leftNA.enable(left);
+            naCheck(leftNA.check(left) || RRuntime.isNAorNaN(right));
+            return RDataFactory.createAscendingRange(left, (int) right);
+        }
 
-    @Specialization(guards = "left <= asDouble(right)")
-    protected RDoubleSequence colonAscending(double left, int right) {
-        rightNA.enable(right);
-        naCheck(RRuntime.isNAorNaN(left) || rightNA.check(right));
-        return RDataFactory.createAscendingRange(left, right);
-    }
+        @Specialization(guards = "asDouble(left) > right")
+        protected RIntSequence colonDescending(int left, double right) {
+            leftNA.enable(left);
+            naCheck(leftNA.check(left) || RRuntime.isNAorNaN(right));
+            return RDataFactory.createDescendingRange(left, (int) right);
+        }
 
-    @Specialization(guards = "left > asDouble(right)")
-    protected RDoubleSequence colonDescending(double left, int right) {
-        rightNA.enable(right);
-        naCheck(RRuntime.isNAorNaN(left) || rightNA.check(right));
-        return RDataFactory.createDescendingRange(left, right);
-    }
+        @Specialization(guards = "left <= asDouble(right)")
+        protected RDoubleSequence colonAscending(double left, int right) {
+            rightNA.enable(right);
+            naCheck(RRuntime.isNAorNaN(left) || rightNA.check(right));
+            return RDataFactory.createAscendingRange(left, right);
+        }
 
-    @Specialization(guards = "left <= right")
-    protected RDoubleSequence colonAscending(double left, double right) {
-        naCheck(RRuntime.isNAorNaN(left) || RRuntime.isNAorNaN(right));
-        return RDataFactory.createAscendingRange(left, right);
-    }
+        @Specialization(guards = "left > asDouble(right)")
+        protected RDoubleSequence colonDescending(double left, int right) {
+            rightNA.enable(right);
+            naCheck(RRuntime.isNAorNaN(left) || rightNA.check(right));
+            return RDataFactory.createDescendingRange(left, right);
+        }
 
-    @Specialization(guards = "left > right")
-    protected RDoubleSequence colonDescending(double left, double right) {
-        naCheck(RRuntime.isNAorNaN(left) || RRuntime.isNAorNaN(right));
-        return RDataFactory.createDescendingRange(left, right);
-    }
+        @Specialization(guards = "left <= right")
+        protected RDoubleSequence colonAscending(double left, double right) {
+            naCheck(RRuntime.isNAorNaN(left) || RRuntime.isNAorNaN(right));
+            return RDataFactory.createAscendingRange(left, right);
+        }
 
-    protected static double asDouble(int intValue) {
-        return intValue;
+        @Specialization(guards = "left > right")
+        protected RDoubleSequence colonDescending(double left, double right) {
+            naCheck(RRuntime.isNAorNaN(left) || RRuntime.isNAorNaN(right));
+            return RDataFactory.createDescendingRange(left, right);
+        }
     }
 
     abstract static class ColonCastNode extends CastNode {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java
index d1d40080d1f9b056a2bd6b11c8c87fbe41d85c44..c9a3e2826bcf8d325844e894e04922fb2c9f369a 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java
@@ -11,8 +11,8 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.emptyDoubleVector;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.emptyStringVector;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.notEmpty;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java
index 4e1a0c7eeefc1ee327deaa686fb1ba0e4cfe8723..5f90889a70d473ecd14239d083a9bcb7676cf3aa 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java
@@ -22,6 +22,10 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asIntegerVector;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import static com.oracle.truffle.r.runtime.RDispatch.INTERNAL_GENERIC;
 import static com.oracle.truffle.r.runtime.RVisibility.OFF;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
@@ -35,12 +39,13 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.RootCallTarget;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Fallback;
-import com.oracle.truffle.api.dsl.NodeChild;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.dsl.TypeSystemReference;
 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.frame.VirtualFrame;
+import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.RRootNode;
@@ -53,6 +58,7 @@ import com.oracle.truffle.r.nodes.function.PromiseHelperNode;
 import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseDeoptimizeFrameNode;
 import com.oracle.truffle.r.runtime.RArguments;
 import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.Utils;
@@ -70,16 +76,13 @@ import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RS4Object;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RSymbol;
+import com.oracle.truffle.r.runtime.data.RTypes;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
-import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
-import com.oracle.truffle.r.runtime.nodes.RBaseNode;
-import com.oracle.truffle.r.runtime.nodes.RNode;
 
 /**
  * Encapsulates all the builtins related to R environments as nested static classes.
@@ -93,6 +96,11 @@ public class EnvFunctions {
     @RBuiltin(name = "as.environment", kind = PRIMITIVE, parameterNames = {"fun"}, dispatch = INTERNAL_GENERIC, behavior = COMPLEX)
     public abstract static class AsEnvironment extends Adapter {
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("fun").mapIf(numericValue(), asIntegerVector());
+        }
+
         @Specialization
         protected REnvironment asEnvironment(@SuppressWarnings("unused") RNull rnull) {
             throw RError.error(this, RError.Message.AS_ENV_NULL_DEFUNCT);
@@ -104,39 +112,46 @@ public class EnvFunctions {
         }
 
         @Specialization
-        protected REnvironment asEnvironment(VirtualFrame frame, RAbstractDoubleVector posVec) {
-            return asEnvironmentInt(frame, (int) posVec.getDataAt(0));
-        }
-
-        @Specialization
-        protected REnvironment asEnvironmentInt(VirtualFrame frame, RAbstractIntVector posVec) {
-            return asEnvironmentInt(frame, posVec.getDataAt(0));
-        }
-
-        private REnvironment asEnvironmentInt(VirtualFrame frame, int pos) {
-            if (pos == -1) {
-                Frame callerFrame = Utils.getCallerFrame(frame, FrameAccess.MATERIALIZE);
-                if (callerFrame == null) {
-                    errorProfile.enter();
-                    throw RError.error(this, RError.Message.NO_ENCLOSING_ENVIRONMENT);
+        protected Object asEnvironmentInt(VirtualFrame frame, RAbstractIntVector pos) {
+            if (pos.getLength() == 0) {
+                CompilerDirectives.transferToInterpreter();
+                throw RError.error(this, Message.INVALID_ARGUMENT, "pos");
+            }
+            Object[] results = pos.getLength() == 1 ? null : new Object[pos.getLength()];
+            for (int i = 0; i < pos.getLength(); i++) {
+                REnvironment env;
+                int p = pos.getDataAt(i);
+                if (p == -1) {
+                    Frame callerFrame = Utils.getCallerFrame(frame, FrameAccess.MATERIALIZE);
+                    if (callerFrame == null) {
+                        errorProfile.enter();
+                        throw RError.error(this, RError.Message.NO_ENCLOSING_ENVIRONMENT);
+                    } else {
+                        env = REnvironment.frameToEnvironment(callerFrame.materialize());
+                    }
                 } else {
-                    return REnvironment.frameToEnvironment(callerFrame.materialize());
+                    String[] searchPath = REnvironment.searchPath();
+                    if (p == searchPath.length + 1) {
+                        // although the empty env does not appear in the result of "search", and it
+                        // is
+                        // not accessible by name, GnuR allows it to be accessible by index
+                        env = REnvironment.emptyEnv();
+                    } else if ((p <= 0) || (p > searchPath.length + 1)) {
+                        errorProfile.enter();
+                        throw RError.error(this, RError.Message.INVALID_ARGUMENT, "pos");
+                    } else {
+                        env = REnvironment.lookupOnSearchPath(searchPath[p - 1]);
+                    }
+                }
+                if (pos.getLength() == 1) {
+                    return env;
                 }
             }
-            String[] searchPath = REnvironment.searchPath();
-            if (pos == searchPath.length + 1) {
-                // although the empty env does not appear in the result of "search", and it is
-                // not accessible by name, GnuR allows it to be accessible by index
-                return REnvironment.emptyEnv();
-            } else if ((pos <= 0) || (pos > searchPath.length + 1)) {
-                errorProfile.enter();
-                throw RError.error(this, RError.Message.INVALID_ARGUMENT, "pos");
-            } else {
-                return REnvironment.lookupOnSearchPath(searchPath[pos - 1]);
-            }
+            return RDataFactory.createList(results);
         }
 
         @Specialization
+        @TruffleBoundary
         protected REnvironment asEnvironment(RAbstractStringVector nameVec) {
             String name = nameVec.getDataAt(0);
             String[] searchPath = REnvironment.searchPath();
@@ -225,9 +240,10 @@ public class EnvFunctions {
             REnvironment target;
             if (!(envir instanceof REnvironment)) {
                 if (parentFrameNode == null) {
+                    CompilerDirectives.transferToInterpreterAndInvalidate();
                     parentFrameNode = insert(FrameFunctionsFactory.ParentFrameNodeGen.create(null));
                 }
-                env = (REnvironment) parentFrameNode.execute(frame, 2);
+                env = parentFrameNode.execute(frame, 2);
             } else {
                 env = (REnvironment) envir;
             }
@@ -256,11 +272,16 @@ public class EnvFunctions {
     @RBuiltin(name = "parent.env", kind = INTERNAL, parameterNames = {"env"}, behavior = READS_FRAME)
     public abstract static class ParentEnv extends Adapter {
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("env").mustBe(instanceOf(REnvironment.class), RError.SHOW_CALLER, Message.ARGUMENT_NOT_ENVIRONMENT);
+        }
+
         @Specialization
         protected REnvironment parentenv(REnvironment env) {
             if (env == REnvironment.emptyEnv()) {
                 errorProfile.enter();
-                throw RError.error(this, RError.Message.EMPTY_NO_PARENT);
+                throw RError.error(RError.SHOW_CALLER, RError.Message.EMPTY_NO_PARENT);
             }
             return env.getParent();
         }
@@ -269,11 +290,17 @@ public class EnvFunctions {
     @RBuiltin(name = "parent.env<-", kind = INTERNAL, parameterNames = {"env", "value"}, behavior = COMPLEX)
     public abstract static class SetParentEnv extends Adapter {
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("env").mustBe(instanceOf(REnvironment.class), Message.NON_LANG_ASSIGNMENT_TARGET);
+            casts.arg("value").mustNotBeNull(Message.USE_NULL_ENV_DEFUNCT, "NULL").mustBe(instanceOf(REnvironment.class), Message.ARGUMENT_NAME_NOT_ENVIRONMENT, "parent");
+        }
+
         @Specialization
         @TruffleBoundary
         protected REnvironment setParentenv(REnvironment env, REnvironment parent) {
             if (env == REnvironment.emptyEnv()) {
-                throw RError.error(this, RError.Message.CANNOT_SET_PARENT);
+                throw RError.error(RError.SHOW_CALLER, RError.Message.CANNOT_SET_PARENT);
             }
             env.setParent(parent);
             return env;
@@ -296,8 +323,8 @@ public class EnvFunctions {
         private final ConditionProfile attributable = ConditionProfile.createBinaryProfile();
 
         @Specialization
-        protected Object environment(VirtualFrame frame, @SuppressWarnings("unused") RNull fun, //
-                        @Cached("new()") GetCallerFrameNode callerFrame, //
+        protected Object environment(VirtualFrame frame, @SuppressWarnings("unused") RNull fun,
+                        @Cached("new()") GetCallerFrameNode callerFrame,
                         @Cached("new()") PromiseDeoptimizeFrameNode deoptFrameNode) {
             MaterializedFrame matFrame = callerFrame.execute(frame);
 
@@ -310,8 +337,8 @@ public class EnvFunctions {
          * Returns the environment that {@code func} was created in.
          */
         @Specialization
-        protected Object environment(RFunction fun, //
-                        @Cached("createBinaryProfile()") ConditionProfile noEnvProfile, //
+        protected Object environment(RFunction fun,
+                        @Cached("createBinaryProfile()") ConditionProfile noEnvProfile,
                         @Cached("createBinaryProfile()") ConditionProfile createProfile) {
             Frame enclosing = fun.getEnclosingFrame();
             if (noEnvProfile.profile(enclosing == null)) {
@@ -325,7 +352,7 @@ public class EnvFunctions {
         }
 
         @Specialization(guards = "isRFormula(formula)")
-        protected Object environment(RLanguage formula, //
+        protected Object environment(RLanguage formula,
                         @Cached("create()") RAttributeProfiles attrProfiles) {
             Object result = formula.getAttr(attrProfiles, RRuntime.DOT_ENVIRONMENT);
             return result == null ? RNull.instance : result;
@@ -346,11 +373,19 @@ public class EnvFunctions {
     @RBuiltin(name = "environment<-", kind = PRIMITIVE, parameterNames = {"env", "value"}, behavior = COMPLEX)
     public abstract static class UpdateEnvironment extends RBuiltinNode {
 
-        private static RAttributeProfiles attributeProfile = RAttributeProfiles.create();
+        private final RAttributeProfiles attributeProfile = RAttributeProfiles.create();
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("value").allowNull().mustBe(REnvironment.class, Message.REPLACEMENT_NOT_ENVIRONMENT);
+        }
 
         @Specialization
         @TruffleBoundary
-        protected Object updateEnvironment(RFunction fun, REnvironment env) {
+        protected static Object updateEnvironment(RFunction fun, REnvironment env) {
+            if (env.getFrame() == fun.getEnclosingFrame()) {
+                return fun;
+            }
             MaterializedFrame enclosingFrame = env.getFrame();
             assert !(enclosingFrame instanceof VirtualEvalFrame);
 
@@ -360,43 +395,49 @@ public class EnvFunctions {
             return RDataFactory.createFunction(fun.getName(), target, null, enclosingFrame);
         }
 
-        @SuppressWarnings("unused")
         @Specialization
         @TruffleBoundary
-        protected Object updateEnvironment(RFunction fun, RNull env) {
+        protected Object updateEnvironment(@SuppressWarnings("unused") RFunction fun, @SuppressWarnings("unused") RNull env) {
             throw RError.error(this, RError.Message.USE_NULL_ENV_DEFUNCT);
         }
 
-        protected Object updateEnvironmentNonFunction(Object obj, Object env) {
-            if (env == RNull.instance || env instanceof REnvironment) {
-                if (obj instanceof RAttributable) {
-                    RAttributable attributable = (RAttributable) obj;
-                    if (env == RNull.instance) {
-                        attributable.removeAttr(attributeProfile, RRuntime.DOT_ENVIRONMENT);
-                    } else {
-                        attributable.setAttr(RRuntime.DOT_ENVIRONMENT, env);
-                    }
-                    return obj;
-                } else {
-                    throw RInternalError.shouldNotReachHere("environment<- called on non-attributable object");
-                }
-            } else {
-                throw RError.error(this, RError.Message.REPLACEMENT_NOT_ENVIRONMENT);
-            }
+        @Specialization
+        @TruffleBoundary
+        protected static Object updateEnvironment(RAbstractContainer obj, REnvironment env) {
+            return updateEnvironment((RAttributable) obj, env);
         }
 
         @Specialization
         @TruffleBoundary
-        protected Object updateEnvironment(RAbstractContainer obj, Object env) {
-            return updateEnvironmentNonFunction(obj, env);
+        protected static Object updateEnvironment(RAttributable obj, REnvironment env) {
+            obj.setAttr(RRuntime.DOT_ENVIRONMENT, env);
+            return obj;
         }
 
-        @Fallback
+        @Specialization
+        @TruffleBoundary
+        protected Object updateEnvironment(RAbstractContainer obj, RNull env) {
+            return updateEnvironment((RAttributable) obj, env);
+        }
+
+        @Specialization
+        @TruffleBoundary
+        protected Object updateEnvironment(RAttributable obj, @SuppressWarnings("unused") RNull env) {
+            obj.removeAttr(attributeProfile, RRuntime.DOT_ENVIRONMENT);
+            return obj;
+        }
+
+        @Specialization
         @TruffleBoundary
-        protected Object updateEnvironment(Object obj, Object env) {
-            return updateEnvironmentNonFunction(obj, env);
+        protected static Object updateEnvironment(RNull obj, @SuppressWarnings("unused") RNull env) {
+            return obj;
         }
 
+        @Specialization
+        @TruffleBoundary
+        protected Object updateEnvironment(@SuppressWarnings("unused") RNull obj, @SuppressWarnings("unused") REnvironment env) {
+            throw RError.error(this, Message.SET_ATTRIBUTES_ON_NULL);
+        }
     }
 
     @RBuiltin(name = "environmentName", kind = INTERNAL, parameterNames = {"fun"}, behavior = PURE)
@@ -419,13 +460,15 @@ public class EnvFunctions {
 
         @Override
         protected void createCasts(CastBuilder casts) {
-            casts.toInteger(2);
+            casts.arg("hash").mustNotBeNull().asLogicalVector().findFirst(RRuntime.LOGICAL_FALSE).map(toBoolean());
+            casts.arg("parent").mustNotBeNull().mustBe(REnvironment.class, Message.MUST_BE_ENVIRON);
+            casts.arg("size").mustNotBeNull().asIntegerVector().findFirst(0);
         }
 
         @Specialization
         @TruffleBoundary
-        protected REnvironment newEnv(byte hash, REnvironment parent, int size) {
-            REnvironment env = RDataFactory.createNewEnv(null, RRuntime.fromLogical(hash), size);
+        protected REnvironment newEnv(boolean hash, REnvironment parent, int size) {
+            REnvironment env = RDataFactory.createNewEnv(null, hash, size);
             RArguments.initializeEnclosingFrame(env.getFrame(), parent.getFrame());
             return env;
         }
@@ -442,73 +485,91 @@ public class EnvFunctions {
     @RBuiltin(name = "lockEnvironment", visibility = OFF, kind = INTERNAL, parameterNames = {"env", "bindings"}, behavior = COMPLEX)
     public abstract static class LockEnvironment extends RBuiltinNode {
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("env").mustNotBeNull().mustBe(REnvironment.class, RError.SHOW_CALLER, Message.NOT_AN_ENVIRONMENT);
+            // TODO: the actual interpretation of this parameter remains dubious
+            casts.arg("bindings").mustNotBeNull().asLogicalVector().findFirst(RRuntime.LOGICAL_FALSE).map(toBoolean());
+        }
+
         @Specialization
-        protected Object lockEnvironment(REnvironment env, byte bindings) {
-            env.lock(bindings == RRuntime.LOGICAL_TRUE);
+        protected Object lockEnvironment(REnvironment env, boolean bindings) {
+            env.lock(bindings);
             return RNull.instance;
         }
     }
 
     @RBuiltin(name = "environmentIsLocked", kind = INTERNAL, parameterNames = {"env"}, behavior = PURE)
     public abstract static class EnvironmentIsLocked extends RBuiltinNode {
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("env").mustNotBeNull().mustBe(REnvironment.class, RError.SHOW_CALLER, Message.NOT_AN_ENVIRONMENT);
+        }
+
         @Specialization
         protected Object lockEnvironment(REnvironment env) {
             return RDataFactory.createLogicalVectorFromScalar(env.isLocked());
         }
     }
 
-    private static RuntimeException typeError(RBaseNode invokingNode, Object sym, Object env) {
-        if (!(sym instanceof RSymbol)) {
-            throw RError.error(invokingNode, RError.Message.NOT_A_SYMBOL);
-        } else {
-            assert !(env instanceof REnvironment);
-            throw RError.error(invokingNode, RError.Message.NOT_AN_ENVIRONMENT);
-        }
-    }
-
     @RBuiltin(name = "lockBinding", visibility = OFF, kind = INTERNAL, parameterNames = {"sym", "env"}, behavior = COMPLEX)
     public abstract static class LockBinding extends RBuiltinNode {
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("sym").mustNotBeNull().mustBe(RSymbol.class, RError.SHOW_CALLER, Message.NOT_A_SYMBOL);
+            casts.arg("env").mustNotBeNull().mustBe(REnvironment.class, RError.SHOW_CALLER, Message.NOT_AN_ENVIRONMENT);
+        }
+
         @Specialization
         protected Object lockBinding(RSymbol sym, REnvironment env) {
             env.lockBinding(sym.getName());
             return RNull.instance;
         }
-
-        @Fallback
-        protected Object lockBinding(Object sym, Object env) {
-            throw typeError(this, sym, env);
-        }
     }
 
     @RBuiltin(name = "unlockBinding", visibility = OFF, kind = INTERNAL, parameterNames = {"sym", "env"}, behavior = COMPLEX)
     public abstract static class UnlockBinding extends RBuiltinNode {
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("sym").mustNotBeNull().mustBe(RSymbol.class, RError.SHOW_CALLER, Message.NOT_A_SYMBOL);
+            casts.arg("env").mustNotBeNull().mustBe(REnvironment.class, RError.SHOW_CALLER, Message.NOT_AN_ENVIRONMENT);
+        }
+
         @Specialization
         protected RNull unlockBinding(RSymbol sym, REnvironment env) {
             env.unlockBinding(sym.getName());
             return RNull.instance;
         }
-
-        @Fallback
-        protected Object unlockBindings(Object sym, Object env) {
-            throw typeError(this, sym, env);
-        }
     }
 
     @RBuiltin(name = "bindingIsLocked", kind = INTERNAL, parameterNames = {"sym", "env"}, behavior = PURE)
     public abstract static class BindingIsLocked extends RBuiltinNode {
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("sym").mustNotBeNull().mustBe(RSymbol.class, RError.SHOW_CALLER, Message.NOT_A_SYMBOL);
+            casts.arg("env").mustNotBeNull().mustBe(REnvironment.class, RError.SHOW_CALLER, Message.NOT_AN_ENVIRONMENT);
+        }
+
         @Specialization
         protected Object bindingIsLocked(RSymbol sym, REnvironment env) {
             return RDataFactory.createLogicalVectorFromScalar(env.bindingIsLocked(sym.getName()));
         }
-
-        @Fallback
-        protected Object bindingIsLocked(Object sym, Object env) {
-            throw typeError(this, sym, env);
-        }
     }
 
     @RBuiltin(name = "makeActiveBinding", visibility = OFF, kind = INTERNAL, parameterNames = {"sym", "fun", "env"}, behavior = COMPLEX)
     public abstract static class MakeActiveBinding extends RBuiltinNode {
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("sym").mustNotBeNull().mustBe(RSymbol.class, RError.SHOW_CALLER, Message.NOT_A_SYMBOL);
+            casts.arg("fun").mustNotBeNull().mustBe(RFunction.class, RError.SHOW_CALLER, Message.NOT_A_FUNCTION);
+            casts.arg("env").mustNotBeNull().mustBe(REnvironment.class, RError.SHOW_CALLER, Message.NOT_AN_ENVIRONMENT);
+        }
+
         @SuppressWarnings("unused")
         @Specialization
         protected Object makeActiveBinding(Object sym, Object fun, Object env) {
@@ -519,9 +580,16 @@ public class EnvFunctions {
 
     @RBuiltin(name = "bindingIsActive", kind = INTERNAL, parameterNames = {"sym", "env"}, behavior = PURE)
     public abstract static class BindingIsActive extends RBuiltinNode {
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("sym").mustNotBeNull().mustBe(RSymbol.class, RError.SHOW_CALLER, Message.NOT_A_SYMBOL);
+            casts.arg("env").mustNotBeNull().mustBe(REnvironment.class, RError.SHOW_CALLER, Message.NOT_AN_ENVIRONMENT);
+        }
+
         @SuppressWarnings("unused")
         @Specialization
-        protected Object bindingIsActive(Object sym, Object fun, Object env) {
+        protected Object bindingIsActive(Object sym, Object env) {
             // TODO implement
             throw RError.nyi(this, "bindingIsActive");
         }
@@ -532,20 +600,25 @@ public class EnvFunctions {
 
         @Child private CopyNode copy;
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("x").mustNotBeNull().mustBe(REnvironment.class, RError.SHOW_CALLER, Message.NOT_AN_ENVIRONMENT);
+            casts.arg("all.names").mustNotBeNull().asLogicalVector().findFirst(RRuntime.LOGICAL_FALSE).map(toBoolean());
+            casts.arg("sorted").mustNotBeNull().asLogicalVector().findFirst(RRuntime.LOGICAL_FALSE).map(toBoolean());
+        }
+
         private Object copy(VirtualFrame frame, Object operand) {
             if (copy == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                copy = insert(CopyNodeGen.create(null));
+                copy = insert(CopyNodeGen.create());
             }
             return copy.execute(frame, operand);
         }
 
         @Specialization
-        protected RList envToListAllNames(VirtualFrame frame, REnvironment env, RAbstractLogicalVector allNamesVec, RAbstractLogicalVector sortedVec) {
+        protected RList envToListAllNames(VirtualFrame frame, REnvironment env, boolean allNames, boolean sorted) {
             // according to the docs it is expected to be slow as it creates a copy of environment
             // objects
-            boolean allNames = allNamesVec.getLength() == 0 || allNamesVec.getDataAt(0) == RRuntime.LOGICAL_FALSE ? false : true;
-            boolean sorted = sortedVec.getLength() == 0 || sortedVec.getDataAt(0) == RRuntime.LOGICAL_FALSE ? false : true;
             RStringVector keys = envls(env, allNames, sorted);
             Object[] data = new Object[keys.getLength()];
             for (int i = 0; i < data.length; i++) {
@@ -563,8 +636,8 @@ public class EnvFunctions {
         }
     }
 
-    @NodeChild("operand")
-    protected abstract static class CopyNode extends RNode {
+    @TypeSystemReference(RTypes.class)
+    protected abstract static class CopyNode extends Node {
 
         protected abstract Object execute(VirtualFrame frame, Object o);
 
@@ -574,7 +647,7 @@ public class EnvFunctions {
         private Object recursiveCopy(VirtualFrame frame, Object operand) {
             if (recursiveCopy == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                recursiveCopy = insert(CopyNodeGen.create(null));
+                recursiveCopy = insert(CopyNodeGen.create());
             }
             return recursiveCopy.execute(frame, operand);
         }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java
similarity index 63%
rename from com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java
rename to com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java
index 2c3f263917181042a3064870a7327750627bba43..150c07c5653314a9ed369999c6b72ba5b96805d4 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java
@@ -22,21 +22,23 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf;
 import static com.oracle.truffle.r.runtime.RVisibility.CUSTOM;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
-import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.VirtualFrame;
-import com.oracle.truffle.r.nodes.RASTUtils;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.nodes.builtin.base.EvalFunctionsFactory.EvalEnvCastNodeGen;
+import com.oracle.truffle.r.nodes.builtin.base.EvalNodeGen.EvalEnvCastNodeGen;
+import com.oracle.truffle.r.nodes.builtin.base.GetFunctions.Get;
+import com.oracle.truffle.r.nodes.builtin.base.GetFunctionsFactory.GetNodeGen;
 import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode;
 import com.oracle.truffle.r.runtime.RCaller;
-import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
@@ -45,13 +47,15 @@ import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RPairList;
+import com.oracle.truffle.r.runtime.data.RSymbol;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 
 /**
  * Contains the {@code eval} {@code .Internal} implementation.
  */
-public class EvalFunctions {
+@RBuiltin(name = "eval", visibility = CUSTOM, kind = INTERNAL, parameterNames = {"expr", "envir", "enclos"}, behavior = COMPLEX)
+public abstract class Eval extends RBuiltinNode {
 
     /**
      * Eval takes two arguments that specify the environment where the expression should be
@@ -60,7 +64,7 @@ public class EvalFunctions {
      * values that may make it into the internal code. This node handles these. See the
      * documentation of eval for more details.
      */
-    public abstract static class EvalEnvCast extends RBaseNode {
+    abstract static class EvalEnvCast extends RBaseNode {
 
         public abstract REnvironment execute(Object env, Object enclos);
 
@@ -109,48 +113,61 @@ public class EvalFunctions {
             // This can happen when envir is a pairlist and enclos is explicitly set to NULL
             return REnvironment.createFromList(attributeProfiles, list.toRList(), REnvironment.baseEnv());
         }
+    }
+
+    @Child private EvalEnvCast envCast = EvalEnvCastNodeGen.create();
+    @Child private SetVisibilityNode visibility = SetVisibilityNode.create();
+
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("envir").allowNull().mustBe(instanceOf(REnvironment.class).or(instanceOf(RList.class)).or(instanceOf(RPairList.class)));
+        casts.arg("enclos").allowNull().mustBe(REnvironment.class);
+    }
 
-        @Fallback
-        @TruffleBoundary
-        protected REnvironment doEval(@SuppressWarnings("unused") Object env, @SuppressWarnings("unused") Object enclos) {
-            throw RError.error(this, RError.Message.INVALID_OR_UNIMPLEMENTED_ARGUMENTS);
+    @Specialization
+    protected Object doEval(VirtualFrame frame, RLanguage expr, Object envir, Object enclos) {
+        RCaller rCaller = RCaller.create(frame, getOriginalCall());
+        REnvironment environment = envCast.execute(envir, enclos);
+        try {
+            return RContext.getEngine().eval(expr, environment, rCaller);
+        } finally {
+            visibility.executeAfterCall(frame, rCaller);
         }
     }
 
-    @RBuiltin(name = "eval", visibility = CUSTOM, kind = INTERNAL, parameterNames = {"expr", "envir", "enclos"}, behavior = COMPLEX)
-    public abstract static class Eval extends RBuiltinNode {
+    @Specialization
+    protected Object doEval(VirtualFrame frame, RExpression expr, Object envir, Object enclos) {
+        RCaller rCaller = RCaller.create(frame, getOriginalCall());
+        REnvironment environment = envCast.execute(envir, enclos);
+        try {
+            return RContext.getEngine().eval(expr, environment, rCaller);
+        } finally {
+            visibility.executeAfterCall(frame, rCaller);
+        }
+    }
 
-        @Child private SetVisibilityNode visibility = SetVisibilityNode.create();
+    protected static Get createGet() {
+        return GetNodeGen.create(null);
+    }
 
-        @Specialization
-        protected Object doEval(VirtualFrame frame, Object expr, Object envir, Object enclos, //
-                        @Cached("createCast()") EvalEnvCast envCast) {
-            // Note: fallback for invalid combinations of envir and enclos is in EvalEnvCastNode
-            RCaller rCaller = RCaller.create(frame, getOriginalCall());
-            REnvironment envir1 = envCast.execute(envir, enclos);
-            Object expr1 = RASTUtils.checkForRSymbol(expr);
-
-            if (expr1 instanceof RExpression) {
-                try {
-                    return RContext.getEngine().eval((RExpression) expr1, envir1, rCaller);
-                } finally {
-                    visibility.executeAfterCall(frame, rCaller);
-                }
-            } else if (expr1 instanceof RLanguage) {
-                try {
-                    return RContext.getEngine().eval((RLanguage) expr1, envir1, rCaller);
-                } finally {
-                    visibility.executeAfterCall(frame, rCaller);
-                }
-            } else {
-                // just return value
-                visibility.execute(frame, true);
-                return expr1;
-            }
-        }
+    @Specialization
+    protected Object doEval(VirtualFrame frame, RSymbol expr, Object envir, Object enclos,
+                    @Cached("createGet()") Get get) {
+        REnvironment environment = envCast.execute(envir, enclos);
 
-        protected EvalEnvCast createCast() {
-            return EvalEnvCastNodeGen.create();
+        try {
+            // no need to do the full eval for symbols: just do the lookup
+            return get.execute(frame, expr.getName(), environment, RType.Any.getName(), true);
+        } finally {
+            visibility.execute(frame, true);
         }
     }
+
+    @Fallback
+    protected Object doEval(VirtualFrame frame, Object expr, Object envir, Object enclos) {
+        // just return value
+        envCast.execute(envir, enclos);
+        visibility.execute(frame, true);
+        return expr;
+    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java
index 5f185fed46198208a9ea5e0f37c60f83276e33d0..6e46110cda9b9842d1ae032e91ccc6d405da6152 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java
@@ -11,7 +11,15 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.constant;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.gte;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.intNA;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.logicalNA;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.lte;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.size;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import static com.oracle.truffle.r.runtime.RVisibility.OFF;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.IO;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
@@ -253,7 +261,7 @@ public class FileFunctions {
 
         @Override
         protected void createCasts(CastBuilder casts) {
-            casts.firstBoolean(1, "extra_cols");
+            casts.arg("extra_cols").asLogicalVector().findFirst().map(toBoolean());
         }
 
         @Specialization
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Format.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Format.java
index 6dc88cb3f108b16ea82b5ea676892c58b8344e03..5c9e5594e3badf9d2621198dcece5729469fb97e 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Format.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Format.java
@@ -11,6 +11,10 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.gte;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.intNA;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.lte;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
@@ -24,15 +28,10 @@ import com.oracle.truffle.r.nodes.builtin.base.printer.AnyVectorToStringVectorWr
 import com.oracle.truffle.r.nodes.builtin.base.printer.ValuePrinterNode;
 import com.oracle.truffle.r.nodes.unary.CastIntegerNode;
 import com.oracle.truffle.r.nodes.unary.CastIntegerNodeGen;
-import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.context.RContext;
-import com.oracle.truffle.r.runtime.data.RDouble;
-import com.oracle.truffle.r.runtime.data.RIntVector;
-import com.oracle.truffle.r.runtime.data.RInteger;
 import com.oracle.truffle.r.runtime.data.RLogical;
-import com.oracle.truffle.r.runtime.data.RLogicalVector;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
@@ -41,6 +40,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 
+@SuppressWarnings("unused")
 @RBuiltin(name = "format", kind = INTERNAL, parameterNames = {"x", "trim", "digits", "nsmall", "width", "justify", "na.encode", "scientific", "decimal.mark"}, behavior = PURE)
 public abstract class Format extends RBuiltinNode {
 
@@ -88,26 +88,26 @@ public abstract class Format extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.toVector(1).toLogical(1);
-        casts.toVector(2).toInteger(2);
-        casts.toVector(3).toInteger(3);
-        casts.toVector(4).toInteger(4);
-        casts.toVector(5).toInteger(5);
-        casts.toVector(6).toLogical(6);
-        casts.toVector(7);
+        casts.arg("x");
+        casts.arg("trim").asLogicalVector().findFirst(RRuntime.LOGICAL_FALSE).notNA().map(toBoolean());
+        casts.arg("digits").asIntegerVector().findFirst(RRuntime.INT_NA).mustBe(intNA().or(gte(R_MIN_DIGITS_OPT).and(lte(R_MAX_DIGITS_OPT))));
+        casts.arg("nsmall").asIntegerVector().findFirst(RRuntime.INT_NA).mustBe(intNA().or(gte(0).and(lte(20))));
+        casts.arg("width").asIntegerVector().findFirst(0).notNA();
+        casts.arg("justify").asIntegerVector().findFirst(RRuntime.INT_NA).mustBe(intNA().or(gte(0).and(lte(3))));
+        casts.arg("na.encode").asLogicalVector().findFirst(RRuntime.LOGICAL_FALSE).notNA().map(toBoolean());
+        casts.arg("scientific").asIntegerVector().findFirst();
+        casts.arg("decimal.mark").asStringVector().findFirst();
     }
 
     @Specialization
-    protected RStringVector format(VirtualFrame frame, RAbstractLogicalVector value, RLogicalVector trimVec, RIntVector digitsVec, RIntVector nsmallVec, RIntVector widthVec, RIntVector justifyVec,
-                    RLogicalVector naEncodeVec, RAbstractVector sciVec, RAbstractStringVector decimalMark) {
-        checkArgs(trimVec, digitsVec, nsmallVec, widthVec, justifyVec, naEncodeVec, sciVec, decimalMark);
+    protected RStringVector format(VirtualFrame frame, RAbstractLogicalVector value, boolean trim, int digits, int nsmall, int width, int justify, boolean naEncode, int scientific,
+                    String decimalMark) {
         return (RStringVector) valuePrinter.prettyPrint(frame, value, AnyVectorToStringVectorWriter::new);
     }
 
     @Specialization
-    protected RStringVector format(VirtualFrame frame, RAbstractIntVector value, RLogicalVector trimVec, RIntVector digitsVec, RIntVector nsmallVec, RIntVector widthVec, RIntVector justifyVec,
-                    RLogicalVector naEncodeVec, RAbstractVector sciVec, RAbstractStringVector decimalMark) {
-        checkArgs(trimVec, digitsVec, nsmallVec, widthVec, justifyVec, naEncodeVec, sciVec, decimalMark);
+    protected RStringVector format(VirtualFrame frame, RAbstractIntVector value, boolean trim, int digits, int nsmall, int width, int justify, boolean naEncode, int scientific,
+                    String decimalMark) {
         return (RStringVector) valuePrinter.prettyPrint(frame, value, AnyVectorToStringVectorWriter::new);
     }
 
@@ -134,82 +134,23 @@ public abstract class Format extends RBuiltinNode {
     }
 
     @Specialization
-    protected RStringVector format(VirtualFrame frame, RAbstractDoubleVector value, RLogicalVector trimVec, RIntVector digitsVec, RIntVector nsmallVec, RIntVector widthVec, RIntVector justifyVec,
-                    RLogicalVector naEncodeVec, RAbstractVector sciVec, RAbstractStringVector decimalMark) {
-        checkArgs(trimVec, digitsVec, nsmallVec, widthVec, justifyVec, naEncodeVec, sciVec, decimalMark);
+    protected RStringVector format(VirtualFrame frame, RAbstractDoubleVector value, boolean trim, int digits, int nsmall, int width, int justify, boolean naEncode, int scientific,
+                    String decimalMark) {
         return (RStringVector) valuePrinter.prettyPrint(frame, value, AnyVectorToStringVectorWriter::new);
     }
 
     @Specialization
-    protected RStringVector format(VirtualFrame frame, RAbstractComplexVector value, RLogicalVector trimVec, RIntVector digitsVec, RIntVector nsmallVec, RIntVector widthVec, RIntVector justifyVec,
-                    RLogicalVector naEncodeVec, RAbstractVector sciVec, RAbstractStringVector decimalMark) {
-        checkArgs(trimVec, digitsVec, nsmallVec, widthVec, justifyVec, naEncodeVec, sciVec, decimalMark);
+    protected RStringVector format(VirtualFrame frame, RAbstractComplexVector value, boolean trim, int digits, int nsmall, int width, int justify, boolean naEncode, int scientific,
+                    String decimalMark) {
         return (RStringVector) valuePrinter.prettyPrint(frame, value, AnyVectorToStringVectorWriter::new);
     }
 
-    @SuppressWarnings("unused")
-    private void processArguments(RLogicalVector trimVec, RIntVector digitsVec, RIntVector nsmallVec, RIntVector widthVec, RIntVector justifyVec, RLogicalVector naEncodeVec, RAbstractVector sciVec,
-                    RAbstractStringVector decimalMark) {
-        byte trim = trimVec.getLength() > 0 ? trimVec.getDataAt(0) : RRuntime.LOGICAL_NA;
-        int digits = digitsVec.getLength() > 0 ? digitsVec.getDataAt(0) : RRuntime.INT_NA;
-        getConfig().digits = digits;
-        int nsmall = nsmallVec.getLength() > 0 ? nsmallVec.getDataAt(0) : RRuntime.INT_NA;
-        int width = widthVec.getLength() > 0 ? widthVec.getDataAt(0) : 0;
-        int justify = justifyVec.getLength() > 0 ? justifyVec.getDataAt(0) : RRuntime.INT_NA;
-        byte naEncode = naEncodeVec.getLength() > 0 ? naEncodeVec.getDataAt(0) : RRuntime.LOGICAL_NA;
-        int sci = computeSciArg(sciVec);
-        String myOutDec = decimalMark.getDataAt(0);
-        if (RRuntime.isNA(myOutDec)) {
-            myOutDec = ".";
-        }
-    }
-
     @Specialization
-    protected RStringVector format(RAbstractStringVector value, RLogicalVector trimVec, RIntVector digitsVec, RIntVector nsmallVec, RIntVector widthVec, RIntVector justifyVec,
-                    RLogicalVector naEncodeVec, RAbstractVector sciVec, RAbstractStringVector decimalMark) {
-        checkArgs(trimVec, digitsVec, nsmallVec, widthVec, justifyVec, naEncodeVec, sciVec, decimalMark);
+    protected RStringVector format(RAbstractStringVector value, boolean trim, int digits, int nsmall, int width, int justify, boolean naEncode, int scientific, String decimalMark) {
         // TODO: implement full semantics
         return value.materialize();
     }
 
-    // TruffleDSL bug - should not need multiple guards here
-    protected void checkArgs(RLogicalVector trimVec, RIntVector digitsVec, RIntVector nsmallVec, RIntVector widthVec, RIntVector justifyVec, RLogicalVector naEncodeVec, RAbstractVector sciVec,
-                    RAbstractStringVector decimalMark) {
-        if (trimVec.getLength() > 0 && RRuntime.isNA(trimVec.getDataAt(0))) {
-            errorProfile.enter();
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "trim");
-        }
-        if (digitsVec.getLength() > 0 && (RRuntime.isNA(digitsVec.getDataAt(0)) || digitsVec.getDataAt(0) < R_MIN_DIGITS_OPT || digitsVec.getDataAt(0) > R_MAX_DIGITS_OPT)) {
-            errorProfile.enter();
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "digits");
-        }
-        if (nsmallVec.getLength() > 0 && (RRuntime.isNA(nsmallVec.getDataAt(0)) || nsmallVec.getDataAt(0) < 0 || nsmallVec.getDataAt(0) > 20)) {
-            errorProfile.enter();
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "nsmall");
-        }
-        if (widthVec.getLength() > 0 && RRuntime.isNA(widthVec.getDataAt(0))) {
-            errorProfile.enter();
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "width");
-        }
-        if (justifyVec.getLength() > 0 && (RRuntime.isNA(justifyVec.getDataAt(0)) || justifyVec.getDataAt(0) < 0 || nsmallVec.getDataAt(0) > 3)) {
-            errorProfile.enter();
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "justify");
-        }
-        if (naEncodeVec.getLength() > 0 && RRuntime.isNA(naEncodeVec.getDataAt(0))) {
-            errorProfile.enter();
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "na.encode");
-        }
-        if (sciVec.getLength() != 1 || (sciVec.getElementClass() != RLogical.class && sciVec.getElementClass() != RInteger.class && sciVec.getElementClass() != RDouble.class)) {
-            errorProfile.enter();
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "scientific");
-        }
-        if (decimalMark.getLength() != 1) {
-            errorProfile.enter();
-            throw RError.error(this, RError.Message.INVALID_ARGUMENT, "decmial.mark");
-        }
-    }
-
-    @SuppressWarnings("unused")
     private static class Config {
         public int width;
         public int naWidth;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FormatC.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FormatC.java
index fa762a0a2f9e0fa7a67d30cc5a43595aaac4c592..0ff9871785cb6fb0523d27ae4bae2b6f98f303e7 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FormatC.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FormatC.java
@@ -24,10 +24,8 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RAttributable;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
-import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 
-@RBuiltin(name = "formatC", kind = INTERNAL, parameterNames = {"x", "mode", "width", "digits", "format", "flat", "i.strlen"}, behavior = PURE)
+@RBuiltin(name = "formatC", kind = INTERNAL, parameterNames = {"x", "mode", "width", "digits", "format", "flag", "i.strlen"}, behavior = PURE)
 public abstract class FormatC extends RBuiltinNode {
 
     @Child private CastStringNode castStringNode;
@@ -42,13 +40,18 @@ public abstract class FormatC extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.toInteger(2).toInteger(3).toInteger(6);
+        casts.arg("x");
+        casts.arg("mode").asStringVector().findFirst();
+        casts.arg("width").asIntegerVector().findFirst();
+        casts.arg("digits").asIntegerVector().findFirst();
+        casts.arg("format").asStringVector().findFirst();
+        casts.arg("flag").asStringVector().findFirst();
+        casts.arg("i.strlen").asIntegerVector().findFirst();
     }
 
     @SuppressWarnings("unused")
     @Specialization
-    RAttributable formatC(RAbstractContainer x, RAbstractStringVector modeVec, RAbstractIntVector widthVec, RAbstractIntVector digitsVec, RAbstractStringVector formatVec,
-                    RAbstractStringVector flagVec, RAbstractIntVector iStrlen) {
+    RAttributable formatC(RAbstractContainer x, String mode, int width, int digits, String format, String flag, int iStrlen) {
         RStringVector res = castStringVector(x);
         return res.setClassAttr(null);
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java
index babd9d29b4aa7da41a451f38fe8ccfbf20557341..9737c5b1ff9af48b09cf46788191afdfdd2ec7ac 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java
@@ -59,10 +59,10 @@ import com.oracle.truffle.r.runtime.HasSignature;
 import com.oracle.truffle.r.runtime.RArguments;
 import com.oracle.truffle.r.runtime.RCaller;
 import com.oracle.truffle.r.runtime.RError;
-import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.Utils;
+import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
@@ -158,7 +158,7 @@ public class FrameFunctions {
 
         @Override
         protected void createCasts(CastBuilder casts) {
-            casts.firstIntegerWithError(0, Message.INVALID_ARGUMENT, "which");
+            casts.arg("which").asIntegerVector().findFirst();
         }
 
         @Override
@@ -175,8 +175,7 @@ public class FrameFunctions {
             if (RArguments.getFunction(cframe) == null) {
                 return RNull.instance;
             }
-            RLanguage createCall = createCall(RArguments.getCall(cframe));
-            return createCall;
+            return createCall(RArguments.getCall(cframe));
         }
 
         @TruffleBoundary
@@ -208,6 +207,14 @@ public class FrameFunctions {
             return FrameAccess.READ_ONLY;
         }
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("definition").mustBe(RFunction.class);
+            casts.arg("call").mustBe(RLanguage.class);
+            casts.arg("expand.dots").asLogicalVector().findFirst();
+            casts.arg("envir").mustBe(REnvironment.class, Message.MUST_BE_ENVIRON);
+        }
+
         @Specialization
         protected RLanguage matchCall(RFunction definition, Object callObj, byte expandDotsL, REnvironment env) {
             /*
@@ -404,6 +411,11 @@ public class FrameFunctions {
             return FrameAccess.MATERIALIZE;
         }
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("which").asIntegerVector().findFirst();
+        }
+
         @Specialization
         protected REnvironment sysFrame(VirtualFrame frame, int which) {
             REnvironment result;
@@ -419,11 +431,6 @@ public class FrameFunctions {
 
             return result;
         }
-
-        @Specialization
-        protected REnvironment sysFrame(VirtualFrame frame, double which) {
-            return sysFrame(frame, (int) which);
-        }
     }
 
     @RBuiltin(name = "sys.frames", kind = INTERNAL, parameterNames = {}, behavior = COMPLEX)
@@ -508,7 +515,7 @@ public class FrameFunctions {
 
         @Override
         protected void createCasts(CastBuilder casts) {
-            casts.firstIntegerWithError(0, Message.INVALID_ARGUMENT, "n");
+            casts.arg("n").asIntegerVector().findFirst();
         }
 
         @Specialization
@@ -540,6 +547,11 @@ public class FrameFunctions {
             return FrameAccess.READ_ONLY;
         }
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("which").asIntegerVector().findFirst();
+        }
+
         @Specialization
         protected Object sysFunction(VirtualFrame frame, int which) {
             // N.B. Despite the spec, n==0 is treated as the current function
@@ -552,11 +564,6 @@ public class FrameFunctions {
                 return func;
             }
         }
-
-        @Specialization
-        protected Object sysFunction(VirtualFrame frame, double which) {
-            return sysFunction(frame, (int) which);
-        }
     }
 
     @RBuiltin(name = "sys.parents", kind = INTERNAL, parameterNames = {}, behavior = COMPLEX)
@@ -610,11 +617,11 @@ public class FrameFunctions {
         private final BranchProfile promiseProfile = BranchProfile.create();
         private final BranchProfile nonNullCallerProfile = BranchProfile.create();
 
-        public abstract Object execute(VirtualFrame frame, int n);
+        public abstract REnvironment execute(VirtualFrame frame, int n);
 
         @Override
         protected void createCasts(CastBuilder casts) {
-            casts.firstIntegerWithError(0, Message.INVALID_VALUE, "n");
+            casts.arg("n").asIntegerVector().findFirst();
         }
 
         @Override
@@ -666,10 +673,5 @@ public class FrameFunctions {
             // }
             return REnvironment.frameToEnvironment(getNumberedFrame(frame, call.getDepth()).materialize());
         }
-
-        @Specialization
-        protected REnvironment parentFrame(VirtualFrame frame, double n) {
-            return parentFrame(frame, (int) n);
-        }
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetFunctions.java
index 5e1b045eb2cf06598304cae3d5f8db4fc2f4846a..5e425c311184a247df5571b212574eb7980f1cc3 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetFunctions.java
@@ -22,6 +22,13 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asIntegerVector;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.chain;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.doubleValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.findFirst;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.integerValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
@@ -32,7 +39,6 @@ import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.frame.VirtualFrame;
-import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
@@ -49,10 +55,12 @@ import com.oracle.truffle.r.nodes.function.call.CallRFunctionCachedNode;
 import com.oracle.truffle.r.nodes.function.call.CallRFunctionCachedNodeGen;
 import com.oracle.truffle.r.nodes.objects.GetS4DataSlot;
 import com.oracle.truffle.r.nodes.objects.GetS4DataSlotNodeGen;
+import com.oracle.truffle.r.nodes.unary.CastNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.RCaller;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RError.Message;
+import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
@@ -63,6 +71,7 @@ import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RS4Object;
+import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 
@@ -73,14 +82,12 @@ public class GetFunctions {
     public abstract static class Adapter extends RBuiltinNode {
         private final BranchProfile unknownObjectErrorProfile = BranchProfile.create();
         protected final ValueProfile modeProfile = ValueProfile.createIdentityProfile();
-        protected final BranchProfile inheritsProfile = BranchProfile.create();
+        protected final BranchProfile recursiveProfile = BranchProfile.create();
         @Child private PromiseHelperNode promiseHelper = new PromiseHelperNode();
         @Child protected TypeFromModeNode typeFromMode = TypeFromModeNodeGen.create();
 
         @CompilationFinal private boolean firstExecution = true;
 
-        public abstract Object execute(VirtualFrame frame, Object name, REnvironment envir, String mode, byte inherits);
-
         protected void unknownObject(String x, RType modeType, String modeString) throws RError {
             unknownObjectErrorProfile.enter();
             if (modeType == RType.Any) {
@@ -103,29 +110,22 @@ public class GetFunctions {
             }
         }
 
-        protected static boolean isInherits(byte inherits) {
-            return inherits == RRuntime.LOGICAL_TRUE;
-        }
-
-        protected Object getAndCheck(VirtualFrame frame, RAbstractStringVector xv, REnvironment env, RType modeType, boolean fail) throws RError {
-            String x = xv.getDataAt(0);
+        protected Object getAndCheck(VirtualFrame frame, String x, REnvironment env, RType modeType, String modeString, boolean fail) throws RError {
             Object obj = checkPromise(frame, env.get(x), x);
             if (obj != null && RRuntime.checkType(obj, modeType)) {
                 return obj;
             } else {
                 if (fail) {
-                    unknownObject(x, modeType, modeType.getName());
+                    unknownObject(x, modeType, modeString);
                 }
                 return null;
             }
         }
 
-        protected Object getInherits(VirtualFrame frame, RAbstractStringVector xv, REnvironment envir, String mode, boolean fail) {
-            RType modeType = typeFromMode.execute(mode);
-            Object r = getAndCheck(frame, xv, envir, modeType, false);
+        protected Object getInherits(VirtualFrame frame, String x, REnvironment envir, RType modeType, String modeString, boolean fail) {
+            Object r = getAndCheck(frame, x, envir, modeType, modeString, false);
             if (r == null) {
-                inheritsProfile.enter();
-                String x = xv.getDataAt(0);
+                recursiveProfile.enter();
                 REnvironment env = envir;
                 while (env != REnvironment.emptyEnv()) {
                     env = env.getParent();
@@ -137,25 +137,27 @@ public class GetFunctions {
                     }
                 }
                 if (r == null && fail) {
-                    unknownObject(x, modeType, mode);
+                    unknownObject(x, modeType, modeString);
                 }
             }
             return r;
         }
     }
 
-    public static final class S4ToEnvNode extends Node {
+    public static final class S4ToEnvNode extends CastNode {
 
         @Child private GetS4DataSlot getS4Data = GetS4DataSlotNodeGen.create(RType.Environment);
 
-        public REnvironment execute(RS4Object obj) {
-            assert obj.isS4() : "unexpected non-S4 RS4Object";
-            Object value = getS4Data.executeObject(obj);
+        @Override
+        public Object execute(Object obj) {
+            RS4Object s4Obj = (RS4Object) obj;
+            assert s4Obj.isS4() : "unexpected non-S4 RS4Object";
+            Object value = getS4Data.executeObject(s4Obj);
             if (value == RNull.instance) {
                 CompilerDirectives.transferToInterpreter();
                 throw RError.error(RError.SHOW_CALLER, Message.USE_NULL_ENV_DEFUNCT);
             }
-            return (REnvironment) value;
+            return value;
         }
     }
 
@@ -164,25 +166,37 @@ public class GetFunctions {
 
         private final ConditionProfile inheritsProfile = ConditionProfile.createBinaryProfile();
 
+        public abstract Object execute(VirtualFrame frame, String x, REnvironment environment, String mode, boolean inherits);
+
         @Override
         protected void createCasts(CastBuilder casts) {
+            casts.arg("x").mustBe(stringValue()).asStringVector().findFirst();
+            casts.arg("envir").mustBe(instanceOf(REnvironment.class).or(integerValue()).or(doubleValue()).or(instanceOf(RS4Object.class))).mapIf(integerValue().or(doubleValue()),
+                            chain(asIntegerVector()).with(findFirst().integerElement()).end());
+            casts.arg("mode").mustBe(stringValue()).asStringVector().findFirst();
             casts.arg("inherits").allowNull().asLogicalVector().findFirst().map(toBoolean());
         }
 
         @Specialization
-        protected Object get(VirtualFrame frame, RAbstractStringVector xv, REnvironment envir, String mode, boolean inherits) {
+        public Object get(VirtualFrame frame, String x, REnvironment envir, String mode, boolean inherits) {
+            RType modeType = typeFromMode.execute(mode);
             if (inheritsProfile.profile(inherits)) {
-                return getInherits(frame, xv, envir, mode, true);
+                return getInherits(frame, x, envir, modeType, mode, true);
             } else {
-                RType modeType = typeFromMode.execute(mode);
-                return getAndCheck(frame, xv, envir, modeType, true);
+                return getAndCheck(frame, x, envir, modeType, mode, true);
             }
         }
 
         @Specialization
-        protected Object get(VirtualFrame frame, RAbstractStringVector xv, RS4Object envir, String mode, boolean inherits, //
+        public Object get(VirtualFrame frame, String x, RS4Object s4Envir, String mode, boolean inherits,
                         @Cached("new()") S4ToEnvNode s4ToEnv) {
-            return get(frame, xv, s4ToEnv.execute(envir), mode, inherits);
+            return get(frame, x, (REnvironment) s4ToEnv.execute(s4Envir), mode, inherits);
+        }
+
+        @SuppressWarnings("unused")
+        @Specialization
+        protected Object get(VirtualFrame frame, String x, int envir, String mode, boolean inherits) {
+            throw RInternalError.unimplemented();
         }
     }
 
@@ -193,17 +207,21 @@ public class GetFunctions {
 
         @Override
         protected void createCasts(CastBuilder casts) {
+            casts.arg("x").mustBe(stringValue()).asStringVector().findFirst();
+            casts.arg("envir").mustBe(instanceOf(REnvironment.class).or(integerValue()).or(doubleValue()).or(instanceOf(RS4Object.class))).mapIf(integerValue().or(doubleValue()),
+                            chain(asIntegerVector()).with(findFirst().integerElement()).end());
+            casts.arg("mode").mustBe(stringValue()).asStringVector().findFirst();
             casts.arg("inherits").allowNull().asLogicalVector().findFirst().map(toBoolean());
         }
 
         @Specialization
-        protected Object get0(VirtualFrame frame, RAbstractStringVector xv, REnvironment envir, String mode, boolean inherits, Object ifnotfound) {
+        protected Object get0(VirtualFrame frame, String x, REnvironment envir, String mode, boolean inherits, Object ifnotfound) {
             Object result;
+            RType modeType = typeFromMode.execute(mode);
             if (inheritsProfile.profile(inherits)) {
-                result = getInherits(frame, xv, envir, mode, false);
+                result = getInherits(frame, x, envir, modeType, mode, false);
             } else {
-                RType modeType = typeFromMode.execute(mode);
-                result = getAndCheck(frame, xv, envir, modeType, false);
+                result = getAndCheck(frame, x, envir, modeType, mode, false);
             }
             if (result == null) {
                 result = ifnotfound;
@@ -212,9 +230,15 @@ public class GetFunctions {
         }
 
         @Specialization
-        protected Object get0(VirtualFrame frame, RAbstractStringVector xv, RS4Object envir, String mode, boolean inherits, Object ifnotfound, //
+        protected Object get0(VirtualFrame frame, String x, RS4Object s4Envir, String mode, boolean inherits, Object ifnotfound,
                         @Cached("new()") S4ToEnvNode s4ToEnv) {
-            return get0(frame, xv, s4ToEnv.execute(envir), mode, inherits, ifnotfound);
+            return get0(frame, x, (REnvironment) s4ToEnv.execute(s4Envir), mode, inherits, ifnotfound);
+        }
+
+        @SuppressWarnings("unused")
+        @Specialization
+        protected Object get(VirtualFrame frame, String x, int envir, String mode, boolean inherits, Object ifnotfound) {
+            throw RInternalError.unimplemented();
         }
     }
 
@@ -228,6 +252,16 @@ public class GetFunctions {
 
         @CompilationFinal private boolean needsCallerFrame;
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("x").mustBe(stringValue()).asStringVector();
+            casts.arg("envir").mustBe(instanceOf(REnvironment.class).or(integerValue()).or(doubleValue()).or(instanceOf(RS4Object.class))).mapIf(integerValue().or(doubleValue()),
+                            chain(asIntegerVector()).with(findFirst().integerElement()).end());
+            casts.arg("mode").mustBe(stringValue()).asStringVector();
+            casts.arg("ifnotfound").mustBe(RAbstractListVector.class);
+            casts.arg("inherits").asLogicalVector().findFirst().map(toBoolean());
+        }
+
         private static class State {
             final int svLength;
             final int modeLength;
@@ -273,56 +307,55 @@ public class GetFunctions {
                 throw RError.error(this, RError.Message.WRONG_LENGTH_ARG, "ifnotfound");
             }
             return state;
-
         }
 
-        @Specialization(guards = "!isInherits(inherits)")
-        protected RList mgetNonInherit(VirtualFrame frame, RAbstractStringVector xv, REnvironment env, RAbstractStringVector mode, RList ifNotFound, @SuppressWarnings("unused") byte inherits) {
-            State state = checkArgs(xv, mode, ifNotFound);
-            for (int i = 0; i < state.svLength; i++) {
-                String x = state.checkNA(xv.getDataAt(i));
-                state.names[i] = x;
-                RType modeType = typeFromMode.execute(mode.getDataAt(state.modeLength == 1 ? 0 : i));
-                Object r = checkPromise(frame, env.get(x), x);
-                if (r != null && RRuntime.checkType(r, modeType)) {
-                    state.data[i] = r;
-                } else {
-                    doIfNotFound(frame, state, i, x, ifNotFound);
-                }
-            }
-            return state.getResult();
-        }
-
-        @Specialization(guards = "isInherits(inherits)")
-        protected RList mgetInherit(VirtualFrame frame, RAbstractStringVector xv, REnvironment envir, RAbstractStringVector mode, RList ifNotFound, @SuppressWarnings("unused") byte inherits) {
+        @Specialization
+        protected RList mget(VirtualFrame frame, RAbstractStringVector xv, REnvironment envir, RAbstractStringVector mode, RList ifNotFound, boolean inherits,
+                        @Cached("createBinaryProfile()") ConditionProfile inheritsProfile) {
             State state = checkArgs(xv, mode, ifNotFound);
             for (int i = 0; i < state.svLength; i++) {
                 String x = state.checkNA(xv.getDataAt(i));
                 state.names[i] = x;
                 RType modeType = typeFromMode.execute(mode.getDataAt(state.modeLength == 1 ? 0 : i));
-                Object r = envir.get(x);
-                if (r == null || !RRuntime.checkType(r, modeType)) {
-                    inheritsProfile.enter();
-                    REnvironment env = envir;
-                    while (env != REnvironment.emptyEnv()) {
-                        env = env.getParent();
-                        if (env != REnvironment.emptyEnv()) {
-                            r = checkPromise(frame, env.get(x), x);
-                            if (r != null && RRuntime.checkType(r, modeType)) {
-                                break;
+                if (inheritsProfile.profile(inherits)) {
+                    Object r = envir.get(x);
+                    if (r == null || !RRuntime.checkType(r, modeType)) {
+                        recursiveProfile.enter();
+                        REnvironment env = envir;
+                        while (env != REnvironment.emptyEnv()) {
+                            env = env.getParent();
+                            if (env != REnvironment.emptyEnv()) {
+                                r = checkPromise(frame, env.get(x), x);
+                                if (r != null && RRuntime.checkType(r, modeType)) {
+                                    break;
+                                }
                             }
                         }
                     }
-                }
-                if (r == null) {
-                    doIfNotFound(frame, state, i, x, ifNotFound);
+                    if (r == null) {
+                        doIfNotFound(frame, state, i, x, ifNotFound);
+                    } else {
+                        state.data[i] = r;
+                    }
                 } else {
-                    state.data[i] = r;
+                    Object r = checkPromise(frame, envir.get(x), x);
+                    if (r != null && RRuntime.checkType(r, modeType)) {
+                        state.data[i] = r;
+                    } else {
+                        doIfNotFound(frame, state, i, x, ifNotFound);
+                    }
                 }
             }
             return state.getResult();
         }
 
+        @Specialization
+        protected RList mget(VirtualFrame frame, RAbstractStringVector xv, RS4Object s4Envir, RAbstractStringVector mode, RList ifNotFound, boolean inherits,
+                        @Cached("createBinaryProfile()") ConditionProfile inheritsProfile,
+                        @Cached("new()") S4ToEnvNode s4ToEnv) {
+            return mget(frame, xv, (REnvironment) s4ToEnv.execute(s4Envir), mode, ifNotFound, inherits, inheritsProfile);
+        }
+
         private void doIfNotFound(VirtualFrame frame, State state, int i, String x, RList ifNotFound) {
             if (state.ifnFunc != null) {
                 state.data[i] = call(frame, state.ifnFunc, x);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
index 2f923ca2d45aa15ebd99ff28b0ce090932cceb9c..8745ed95dfc3fc2ab44fc5b18bbf7d75b318b088 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
@@ -37,7 +37,6 @@ import com.oracle.truffle.r.nodes.access.ConstantNode;
 import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.nodes.builtin.base.EvalFunctions.Eval;
 import com.oracle.truffle.r.nodes.function.PromiseHelperNode;
 import com.oracle.truffle.r.nodes.function.RCallNode;
 import com.oracle.truffle.r.nodes.function.call.CallRFunctionCachedNode;
@@ -85,7 +84,7 @@ public class HiddenInternalFunctions {
         private void initEval() {
             if (eval == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                eval = insert(EvalFunctionsFactory.EvalNodeGen.create(null));
+                eval = insert(EvalNodeGen.create(null));
             }
         }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsFiniteFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsFiniteFunctions.java
index 600bd243f8c58edbf75aea4ee69c0de38f84427d..32634f340058a8195c16d16ee6dea96c987d8017 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsFiniteFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsFiniteFunctions.java
@@ -29,6 +29,7 @@ import java.util.Arrays;
 import java.util.function.DoublePredicate;
 import java.util.function.IntPredicate;
 
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
@@ -82,6 +83,7 @@ public class IsFiniteFunctions {
         @Fallback
         protected Object doIsFiniteOther(Object x) {
             if (typeofNode == null) {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
                 typeofNode = insert(TypeofNodeGen.create());
             }
             String type = typeofNode.execute(x).getName();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/List2Env.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/List2Env.java
index bae6feead23e36ad0a1c3a7ba166c502db08338c..e87f6b36855705860fc21fba64a5dc51b231f37f 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/List2Env.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/List2Env.java
@@ -27,17 +27,24 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.RList2EnvNode;
+import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RList;
+import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 
 @RBuiltin(name = "list2env", kind = INTERNAL, parameterNames = {"x", "envir"}, behavior = PURE)
 public abstract class List2Env extends RBuiltinNode {
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("x").mustBe(RAbstractListVector.class, Message.FIRST_ARGUMENT_NOT_NAMED_LIST);
+        casts.arg("envir").mustBe(REnvironment.class, Message.MUST_BE_ENVIRON, "envir");
+    }
 
     @Specialization
-    protected REnvironment doList2Env(RList list, REnvironment env,
+    protected REnvironment doList2Env(RAbstractListVector list, REnvironment env,
                     @Cached("new()") RList2EnvNode list2Env) {
         return list2Env.execute(list, env);
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java
index 7dd1b5f52bbc46796964aedb536d6f5a3d916177..b7665cc04d28b7a03c4120e7ca7cc79ea2fe5f0f 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java
@@ -153,7 +153,7 @@ public abstract class Mapply extends RBuiltinNode {
             } else {
                 indexArg = new RArgsValuesAndNames(new Object[]{adjIndex + 1}, I_INDEX);
             }
-            return indexedLoadNode.execute(frame, vec, indexArg, EXACT, DROP);
+            return indexedLoadNode.executeBuiltin(frame, vec, indexArg, EXACT, DROP);
 
         }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Missing.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Missing.java
index 4bb9e38c5e451f4c803729a3eafbb5ef264c16c3..309dd7e602a088ada74d640fa8d4e48a1608fffe 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Missing.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Missing.java
@@ -186,7 +186,7 @@ public final class Missing extends RBuiltinNode {
     }
 
     @Override
-    public Object execute(VirtualFrame frame, Object... args) {
+    public Object executeBuiltin(VirtualFrame frame, Object... args) {
         throw RInternalError.shouldNotReachHere();
     }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java
index 562f6b4ac4bf2a8f79bd85255959d01508412b70..8278cc60981a9f8cf7b03093de861ca479e18696 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java
@@ -24,6 +24,7 @@ package com.oracle.truffle.r.nodes.builtin.base;
 
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asIntegerVector;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asStringVector;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.integerValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
@@ -32,7 +33,6 @@ import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.LoopConditionProfile;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
-import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
@@ -49,7 +49,7 @@ public abstract class NChar extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.arg("x").allowNull().mapIf(Predef.integerValue(), asIntegerVector(), asStringVector(true, false, false));
+        casts.arg("x").allowNull().mapIf(integerValue(), asIntegerVector(), asStringVector(true, false, false));
         casts.arg("type").asStringVector().findFirst();
         casts.arg("allowNA").asLogicalVector().findFirst(RRuntime.LOGICAL_TRUE).map(toBoolean());
         casts.arg("keepNA").asLogicalVector().findFirst(RRuntime.LOGICAL_FALSE).map(toBoolean());
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java
index 75c4bed4a5d184fe83c074f995f54222b061f6a2..adf8a6a356681940a902d1eb260b5b205319c18f 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java
@@ -22,7 +22,6 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.constant;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
 import static com.oracle.truffle.r.runtime.RError.Message.MUST_BE_STRING_OR_CONNECTION;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.IO;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java
index 829bd7e1a5aa375e78ca4daa79314859d5eaa9b1..cdb0a92d5d643a58da3ac301a17377e81323104e 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java
@@ -22,7 +22,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.abstractVectorValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
@@ -33,7 +33,6 @@ import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.PrimitiveValueProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
-import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.unary.CastStringNode;
 import com.oracle.truffle.r.nodes.unary.CastStringNodeGen;
@@ -43,6 +42,7 @@ import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RStringVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 
 @RBuiltin(name = "paste", kind = INTERNAL, parameterNames = {"", "sep", "collapse"}, behavior = PURE)
 public abstract class Paste extends RBuiltinNode {
@@ -64,9 +64,9 @@ public abstract class Paste extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.arg(0).mustBe(abstractVectorValue());
+        casts.arg(0).mustBe(RAbstractListVector.class);
         casts.arg("sep").asStringVector().findFirst(Message.INVALID_SEPARATOR);
-        casts.arg("collapse").allowNull().mustBe(Predef.stringValue()).asStringVector().findFirst();
+        casts.arg("collapse").allowNull().mustBe(stringValue()).asStringVector().findFirst();
     }
 
     /**
@@ -90,7 +90,7 @@ public abstract class Paste extends RBuiltinNode {
     }
 
     @Specialization
-    protected RStringVector pasteList(RList values, String sep, @SuppressWarnings("unused") RNull collapse) {
+    protected RStringVector pasteList(RAbstractListVector values, String sep, @SuppressWarnings("unused") RNull collapse) {
         int length = lengthProfile.profile(values.getLength());
         if (hasNonNullElements(values, length)) {
             String[] result = pasteListElements(values, sep, length);
@@ -101,7 +101,7 @@ public abstract class Paste extends RBuiltinNode {
     }
 
     @Specialization
-    protected String pasteList(RList values, String sep, String collapse) {
+    protected String pasteList(RAbstractListVector values, String sep, String collapse) {
         int length = lengthProfile.profile(values.getLength());
         if (hasNonNullElements(values, length)) {
             String[] result = pasteListElements(values, sep, length);
@@ -111,7 +111,7 @@ public abstract class Paste extends RBuiltinNode {
         }
     }
 
-    private boolean hasNonNullElements(RList values, int length) {
+    private boolean hasNonNullElements(RAbstractListVector values, int length) {
         for (int i = 0; i < length; i++) {
             if (values.getDataAt(i) != RNull.instance) {
                 nonNullElementsProfile.enter();
@@ -122,7 +122,7 @@ public abstract class Paste extends RBuiltinNode {
         return false;
     }
 
-    private String[] pasteListElements(RList values, String sep, int length) {
+    private String[] pasteListElements(RAbstractListVector values, String sep, int length) {
         String[][] converted = new String[length][];
         int maxLength = 1;
         for (int i = 0; i < length; i++) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste0.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste0.java
index e3a56703d4d7d0d651c958482eaf9520d6a762e0..18369a4686c8a6ee3b195d21aa536a32b4de6931 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste0.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste0.java
@@ -22,11 +22,12 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
-import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RList;
@@ -38,18 +39,16 @@ import com.oracle.truffle.r.runtime.data.RList;
 @RBuiltin(name = "paste0", kind = INTERNAL, parameterNames = {"list", "collapse"}, behavior = PURE)
 public abstract class Paste0 extends RBuiltinNode {
 
-    @Child private Paste pasteNode;
+    @Child private Paste pasteNode = PasteNodeGen.create(null);
 
-    private Object paste(RList values, Object collapse) {
-        if (pasteNode == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            pasteNode = insert(PasteNodeGen.create(null));
-        }
-        return pasteNode.executeList(values, "", collapse);
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("list").mustBe(RList.class);
+        casts.arg("collapse").allowNull().mustBe(stringValue()).asStringVector().findFirst();
     }
 
     @Specialization
     protected Object paste0(RList values, Object collapse) {
-        return paste(values, collapse);
+        return pasteNode.executeList(values, "", collapse);
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Range.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Range.java
index 951ffd64bc07fc5f182600ff09a7c26a1b3b00c5..8176fec9cefbc7e714de3fe4a58a821c20841f55 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Range.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Range.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import static com.oracle.truffle.r.runtime.RDispatch.SUMMARY_GROUP_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
@@ -54,7 +55,8 @@ public abstract class Range extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.firstBoolean(1).firstBoolean(2);
+        casts.arg("na.rm").asLogicalVector().findFirst().map(toBoolean());
+        casts.arg("finite").asLogicalVector().findFirst().map(toBoolean());
     }
 
     @Override
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rank.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rank.java
index 94e23564e1b0ea5cec69774f9e699b2914ebf79d..f855a8a7742784c2890d0ca6347425d535591664 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rank.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rank.java
@@ -31,13 +31,13 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
 import java.util.function.Function;
 
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.base.OrderNodeGen.CmpNodeGen;
 import com.oracle.truffle.r.nodes.builtin.base.OrderNodeGen.OrderVector1NodeGen;
-import com.oracle.truffle.r.nodes.builtin.casts.Filter;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -79,6 +79,7 @@ public abstract class Rank extends RBuiltinNode {
 
     private Order.OrderVector1Node initOrderVector1() {
         if (orderVector1Node == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
             orderVector1Node = insert(OrderVector1NodeGen.create(false));
         }
         return orderVector1Node;
@@ -86,6 +87,7 @@ public abstract class Rank extends RBuiltinNode {
 
     private Order.CmpNode initOrderCmp() {
         if (orderCmpNode == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
             orderCmpNode = insert(CmpNodeGen.create());
         }
         return orderCmpNode;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java
index 710cbe3459714bfc027d32b5dd835abc0695ddd7..9a9ead6cb2c3264d69a5e079290717534559e4ac 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java
@@ -62,7 +62,8 @@ public abstract class Round extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.toInteger(1);
+        // TODO: this should also accept vectors:
+        casts.arg("digits").asIntegerVector().findFirst();
     }
 
     @Specialization
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/StandardGeneric.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/StandardGeneric.java
index 1566030a477b880a0e45656fb3dd86916634e3be..fb44ec8b4184b8d33ff20cb10def54fade00a160 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/StandardGeneric.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/StandardGeneric.java
@@ -84,6 +84,7 @@ public abstract class StandardGeneric extends RBuiltinNode {
 
     private String argClass(Object arg) {
         if (classNode == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
             classNode = insert(ClassHierarchyScalarNodeGen.create());
         }
         return classNode.executeString(arg);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtrim.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtrim.java
index f5a41c88783a78f6aecb812890b104185daf94b2..fa27e232c3ef00046c3744d4419b77e1c5e39332 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtrim.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtrim.java
@@ -12,6 +12,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
@@ -23,7 +24,6 @@ import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
-import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.base.ToLowerOrUpper.StringMapNode;
 import com.oracle.truffle.r.runtime.RError;
@@ -39,7 +39,7 @@ public abstract class Strtrim extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.arg("x").defaultError(Message.REQUIRES_CHAR_VECTOR, "strtrim()").mustBe(Predef.stringValue()).asStringVector(true, true, true);
+        casts.arg("x").defaultError(Message.REQUIRES_CHAR_VECTOR, "strtrim()").mustBe(stringValue()).asStringVector(true, true, true);
         casts.arg("width").asIntegerVector();
     }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TrigExpFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TrigExpFunctions.java
index 29c188584fc914f9394d6bb7a8daea9740f83fbb..f570ce8ddd0f819a69ca099b84a4c55456a40c1a 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TrigExpFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TrigExpFunctions.java
@@ -496,7 +496,8 @@ public class TrigExpFunctions {
 
         @Override
         protected void createCasts(CastBuilder casts) {
-            casts.toDouble(0).toDouble(1);
+            casts.arg(0).asDoubleVector();
+            casts.arg(1).asDoubleVector();
         }
 
         private double doFunDouble(double y, double x) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/VApply.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/VApply.java
index f39ed52a9069a9cb1ed2c38f3b301f0e3c58b0b0..2fdba2452bbd296c15841f87e7aead60fb576a88 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/VApply.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/VApply.java
@@ -22,7 +22,9 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.abstractVectorValue;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
@@ -30,7 +32,6 @@ import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.profiles.ConditionProfile;
-import com.oracle.truffle.r.nodes.builtin.ArgumentFilter;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.builtin.base.Lapply.LapplyInternalNode;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/fastpaths/AssignFastPath.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/fastpaths/AssignFastPath.java
index 4796242d0fdfba27505a0f57f9c80bbf33e20dd8..5bf2e7213d6f199894f8b941010e09345a69c826 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/fastpaths/AssignFastPath.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/fastpaths/AssignFastPath.java
@@ -24,12 +24,10 @@ package com.oracle.truffle.r.nodes.builtin.base.fastpaths;
 
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
-import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.r.nodes.builtin.base.Assign;
 import com.oracle.truffle.r.nodes.builtin.base.AssignNodeGen;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.data.RMissing;
-import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.nodes.RFastPathNode;
 
@@ -39,26 +37,26 @@ public abstract class AssignFastPath extends RFastPathNode {
 
     @Specialization
     @SuppressWarnings("unused")
-    protected Object assign(VirtualFrame frame, RAbstractStringVector x, Object value, RMissing pos, REnvironment envir, byte inherits, Object immediate) {
-        return assign.execute(frame, x, value, envir, inherits);
+    protected Object assign(String x, Object value, RMissing pos, REnvironment envir, byte inherits, Object immediate) {
+        return assign.execute(x, value, envir, inherits);
     }
 
     @Specialization
     @SuppressWarnings("unused")
-    protected Object assign(VirtualFrame frame, RAbstractStringVector x, Object value, RMissing pos, REnvironment envir, RMissing inherits, Object immediate) {
-        return assign.execute(frame, x, value, envir, RRuntime.LOGICAL_FALSE);
+    protected Object assign(String x, Object value, RMissing pos, REnvironment envir, RMissing inherits, Object immediate) {
+        return assign.execute(x, value, envir, RRuntime.LOGICAL_FALSE);
     }
 
     @Specialization
     @SuppressWarnings("unused")
-    protected Object assign(VirtualFrame frame, RAbstractStringVector x, Object value, REnvironment pos, RMissing envir, byte inherits, Object immediate) {
-        return assign.execute(frame, x, value, pos, inherits);
+    protected Object assign(String x, Object value, REnvironment pos, RMissing envir, byte inherits, Object immediate) {
+        return assign.execute(x, value, pos, inherits);
     }
 
     @Specialization
     @SuppressWarnings("unused")
-    protected Object assign(VirtualFrame frame, RAbstractStringVector x, Object value, REnvironment pos, RMissing envir, RMissing inherits, Object immediate) {
-        return assign.execute(frame, x, value, pos, RRuntime.LOGICAL_FALSE);
+    protected Object assign(String x, Object value, REnvironment pos, RMissing envir, RMissing inherits, Object immediate) {
+        return assign.execute(x, value, pos, RRuntime.LOGICAL_FALSE);
     }
 
     @Fallback
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/fastpaths/GetFastPath.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/fastpaths/GetFastPath.java
index ae4330e44f577657e8a15197c759ed8f82ce7a5e..f8cd26d7715f22c50d2979a7f28e77dd63443893 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/fastpaths/GetFastPath.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/fastpaths/GetFastPath.java
@@ -29,7 +29,6 @@ import com.oracle.truffle.r.nodes.builtin.base.GetFunctions.Get;
 import com.oracle.truffle.r.nodes.builtin.base.GetFunctionsFactory.GetNodeGen;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.data.RMissing;
-import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.nodes.RFastPathNode;
 
@@ -39,13 +38,13 @@ public abstract class GetFastPath extends RFastPathNode {
 
     @Specialization
     @SuppressWarnings("unused")
-    protected Object getNonInherit(VirtualFrame frame, RAbstractStringVector x, RMissing pos, REnvironment envir, RMissing mode, byte inherits) {
+    protected Object getNonInherit(VirtualFrame frame, String x, RMissing pos, REnvironment envir, RMissing mode, byte inherits) {
         return get.execute(frame, x, envir, "any", RRuntime.fromLogical(inherits));
     }
 
     @Specialization
     @SuppressWarnings("unused")
-    protected Object getNonInherit(VirtualFrame frame, RAbstractStringVector x, RMissing pos, REnvironment envir, RMissing mode, RMissing inherits) {
+    protected Object getNonInherit(VirtualFrame frame, String x, RMissing pos, REnvironment envir, RMissing mode, RMissing inherits) {
         return get.execute(frame, x, envir, "any", true);
     }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java
index d38e586b7a6b94fcf98a6d530c5cf64cc5b3c776..dde5d3040364d947b6fa1487dc1a9f929aeadd35 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java
@@ -22,20 +22,21 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base.infix;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
 import static com.oracle.truffle.r.runtime.RDispatch.INTERNAL_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
-import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode;
 import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
@@ -49,6 +50,11 @@ public abstract class AccessField extends RBuiltinNode {
     private final ConditionProfile invalidAtomicVector = ConditionProfile.createBinaryProfile();
     private final BranchProfile error = BranchProfile.create();
 
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg(1).defaultError(Message.INVALID_SUBSCRIPT_TYPE, RType.Language.getName()).mustBe(stringValue()).asStringVector().findFirst();
+    }
+
     @Specialization
     protected Object access(VirtualFrame frame, Object container, String field) {
         if (!invalidAtomicVector.profile(container instanceof RAbstractListVector) && container instanceof RAbstractVector) {
@@ -57,10 +63,4 @@ public abstract class AccessField extends RBuiltinNode {
         }
         return extract.applyAccessField(frame, container, field);
     }
-
-    @Fallback
-    @TruffleBoundary
-    protected Object fallbackError(@SuppressWarnings("unused") Object container, @SuppressWarnings("unused") Object field) {
-        throw RError.error(this, RError.Message.INVALID_SUBSCRIPT_TYPE, RType.Language.getName());
-    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subset.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subset.java
index 9878b4433371e49d5903cc263508a2563386cada..1c7fe1be7b5263c7609f5b7d6fd295f6b3fb7bcc 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subset.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subset.java
@@ -142,7 +142,7 @@ public abstract class Subset extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.toLogical(2);
+        casts.arg("drop").asLogicalVector();
     }
 
     @SuppressWarnings("unused")
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java
index fd4796410cebd8a2190091ecd20c614312a5ae79..771bc4bd590e1e2d170aacb2159ceca8c77d16c5 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java
@@ -34,12 +34,9 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RMissing;
-import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
-import com.oracle.truffle.r.runtime.nodes.RNode;
-import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 
 /**
  * This a rather strange function. It is where, in GnuR, that the "formula" class is set and the
@@ -58,16 +55,7 @@ public abstract class Tilde extends RBuiltinNode {
     }
 
     @Specialization
-    protected RLanguage tilde(VirtualFrame frame, RPromise response, @SuppressWarnings("unused") RMissing model) {
-        return doTilde(frame, null, ((RNode) response.getRep()).asRSyntaxNode());
-    }
-
-    @Specialization
-    protected RLanguage tilde(VirtualFrame frame, RPromise response, RPromise model) {
-        return doTilde(frame, ((RNode) response.getRep()).asRSyntaxNode(), ((RNode) model.getRep()).asRSyntaxNode());
-    }
-
-    private RLanguage doTilde(VirtualFrame frame, @SuppressWarnings("unused") RSyntaxNode response, @SuppressWarnings("unused") RSyntaxNode model) {
+    protected RLanguage tilde(VirtualFrame frame, @SuppressWarnings("unused") Object response, @SuppressWarnings("unused") Object model) {
         RCallNode call = (RCallNode) ((RBaseNode) getParent()).asRSyntaxNode();
         RLanguage lang = RDataFactory.createLanguage(call);
         lang.setClassAttr(FORMULA_CLASS);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateField.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateField.java
index e6ee8c4e25fd4673dd797db0f808f1632c0453fc..11f19dfcf2da4bd81ed1799481b40c71c48341ef 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateField.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateField.java
@@ -22,23 +22,23 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base.infix;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
 import static com.oracle.truffle.r.runtime.RDispatch.INTERNAL_GENERIC;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
 import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode;
 import com.oracle.truffle.r.nodes.access.vector.ReplaceVectorNode;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.unary.CastListNode;
 import com.oracle.truffle.r.nodes.unary.CastListNodeGen;
 import com.oracle.truffle.r.runtime.RError;
-import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
@@ -51,33 +51,26 @@ public abstract class UpdateField extends RBuiltinNode {
 
     private final ConditionProfile coerceList = ConditionProfile.createBinaryProfile();
 
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg(1).defaultError(Message.INVALID_SUBSCRIPT).mustBe(stringValue()).asStringVector().findFirst();
+    }
+
     @Specialization
     protected Object update(VirtualFrame frame, Object container, String field, Object value) {
-        Object updatedObject = container;
-        if (!coerceList.profile(container instanceof RAbstractListVector)) {
-            updatedObject = coerceList(container, updatedObject);
-        }
-        return extract.apply(frame, updatedObject, new Object[]{field}, value);
+        Object list = coerceList.profile(container instanceof RAbstractListVector) ? container : coerceList(container);
+        return extract.apply(frame, list, new Object[]{field}, value);
     }
 
-    private Object coerceList(Object object, Object vector) {
-        Object updatedVector = vector;
-        if (object instanceof RAbstractVector) {
+    private Object coerceList(Object vector) {
+        if (vector instanceof RAbstractVector) {
             if (castList == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
                 castList = insert(CastListNodeGen.create(true, true, false));
             }
             RError.warning(this, RError.Message.COERCING_LHS_TO_LIST);
-            updatedVector = castList.executeList(vector);
+            return castList.executeList(vector);
         }
-        return updatedVector;
-    }
-
-    @Fallback
-    @TruffleBoundary
-    protected Object fallbackError(@SuppressWarnings("unused") Object container, Object field, @SuppressWarnings("unused") Object value) {
-        // TODO: the error message is not quite correct for all types;
-        // for example: x<-list(a=7); `$<-`(x, c("a"), 42);)
-        throw RError.error(this, RError.Message.INVALID_SUBSCRIPT_TYPE, RRuntime.classToString(field.getClass()));
+        return vector;
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/system/ContextSystemFunctionFactory.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/system/ContextSystemFunctionFactory.java
index bb2196e018015531839d8256d22ee4ba41e29df7..3df01c1c7d7d1a48ba36c5cff1156462a0c79fcb 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/system/ContextSystemFunctionFactory.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/system/ContextSystemFunctionFactory.java
@@ -60,7 +60,7 @@ public class ContextSystemFunctionFactory extends SystemFunctionFactory {
         @Specialization
         protected Object systemFunction(VirtualFrame frame, RAbstractStringVector args, RAbstractStringVector env, boolean intern) {
             initContextRNode();
-            Object result = contextRNode.execute(frame, args, env, intern);
+            Object result = contextRNode.executeBuiltin(frame, args, env, intern);
             return result;
         }
     }
@@ -79,7 +79,7 @@ public class ContextSystemFunctionFactory extends SystemFunctionFactory {
         @Specialization
         protected Object systemFunction(VirtualFrame frame, RAbstractStringVector args, RAbstractStringVector env, boolean intern) {
             initContextRscriptNode();
-            Object result = contextRscriptNode.execute(frame, args, env, intern);
+            Object result = contextRscriptNode.executeBuiltin(frame, args, env, intern);
             return result;
         }
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java
index 1cab94e1d91f37633935e68c42b0d75b5adf4428..ce5c3dae4dc188754d89052895ff69e884dd5d6c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java
@@ -105,7 +105,7 @@ public class FastRInterop {
         @Override
         protected void createCasts(CastBuilder casts) {
             casts.arg("name").mustBe(stringValue()).asStringVector().mustBe(singleElement()).findFirst();
-            casts.boxPrimitive(1);
+            casts.arg("value").boxPrimitive();
         }
 
         @Specialization(guards = "!isRMissing(value)")
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTrace.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTrace.java
index 09ce4a2d89bc135a7f791928fabeda2656693483..c756f3e196471d6c18c114e36d60e044874117e3 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTrace.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTrace.java
@@ -77,7 +77,7 @@ public class FastRTrace {
                 topEnv = insert(TopEnvNodeGen.create(null));
                 parentFrame = insert(ParentFrameNodeGen.create(null));
             }
-            return topEnv.execute(frame, parentFrame.execute(frame, 1), RNull.instance);
+            return topEnv.executeBuiltin(frame, parentFrame.execute(frame, 1), RNull.instance);
         }
 
         protected Object getFunction(VirtualFrame frame, Object what, Object where) {
@@ -85,7 +85,7 @@ public class FastRTrace {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
                 getNode = insert(GetNodeGen.create(null));
             }
-            return getNode.execute(frame, what, where, RType.Function.getName(), true);
+            return getNode.executeBuiltin(frame, what, where, RType.Function.getName(), true);
         }
 
         protected void checkWhat(Object what) {
@@ -137,7 +137,7 @@ public class FastRTrace {
                     primTrace = insert(PrimTraceNodeGen.create(null));
                 }
 
-                Object result = primTrace.execute(frame, func);
+                Object result = primTrace.executeBuiltin(frame, func);
                 visibility.execute(frame, false);
                 return result;
             }
@@ -198,7 +198,7 @@ public class FastRTrace {
                     CompilerDirectives.transferToInterpreterAndInvalidate();
                     primUnTrace = insert(PrimUnTraceNodeGen.create(null));
                 }
-                primUnTrace.execute(frame, func);
+                primUnTrace.executeBuiltin(frame, func);
             } else {
                 throw RError.nyi(this, "method tracing");
             }
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java
index 239abd341fdeff7cca9fec66d432bc0806772fec..e5261bd109bb11571b37481454a1b7fe477a7aaf 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java
@@ -627,7 +627,7 @@ public class CastBuilderTest {
         assertEquals(value, cast(value));
     }
 
-    private void assertVectorEquals(RAbstractVector expected, Object actualObj) {
+    private static void assertVectorEquals(RAbstractVector expected, Object actualObj) {
         RAbstractVector actual = (RAbstractVector) actualObj;
         assertEquals("vectors differ in size", expected.getLength(), actual.getLength());
         for (int i = 0; i < expected.getLength(); i++) {
@@ -635,10 +635,6 @@ public class CastBuilderTest {
         }
     }
 
-    private void assertCastWarning(Object value, Object expectedValue) {
-        assertCastWarning(value, expectedValue, String.format(RError.Message.INVALID_ARGUMENT.message, "x"));
-    }
-
     private void assertCastWarning(Object value, Object expectedValue, String expectedMessage) {
         assertEquals(expectedValue, cast(value));
         assertEquals("Expected warning message", expectedMessage, CastNode.getLastWarning());
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/FilterSamplerFactory.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/FilterSamplerFactory.java
index cac9bd6aa33d4975a36064290e6de9782f89a520..bc27e20cff7fa53c0d6879e514addaf5f39b55bd 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/FilterSamplerFactory.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/FilterSamplerFactory.java
@@ -135,7 +135,7 @@ public final class FilterSamplerFactory
                 return leftFilter.trueBranchType().and(rightFilter.trueBranchType());
             }
 
-            @SuppressWarnings({"unchecked", "cast"})
+            @SuppressWarnings({"unchecked"})
             @Override
             public Samples<Object> collectSamples(TypeExpr inputType) {
                 Samples thisSamples = rightFilter.collectSamples(inputType);
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/TestCasts.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/TestCasts.java
index 31ca85080b2b0c9acc268ea463576fea2ec0becd..61a372bc9e838373c29cbbb31452048e4a6ef0ad 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/TestCasts.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/TestCasts.java
@@ -38,8 +38,6 @@ import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.lengthLte;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.logicalValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.lt;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue;
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.scalarIntegerValue;
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.scalarLogicalValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.singleElement;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
 
@@ -146,7 +144,7 @@ public class TestCasts extends TestBase {
         class Root extends TestRootNode<CastNode> {
 
             protected Root(String name) {
-                super(name, setupAndGetCast(b -> b.firstIntegerWithError(0, Message.INVALID_ARGUMENT, "foo")));
+                super(name, setupAndGetCast(b -> b.arg(0, "foo").asIntegerVector().findFirst()));
             }
 
             @Override
@@ -167,7 +165,7 @@ public class TestCasts extends TestBase {
             private final Object constant;
 
             protected Root(String name, Object constant) {
-                super(name, setupAndGetCast(b -> b.firstIntegerWithError(0, Message.INVALID_ARGUMENT, "foo")));
+                super(name, setupAndGetCast(b -> b.arg(0, "foo").asIntegerVector().findFirst()));
                 this.constant = constant;
             }
 
@@ -205,7 +203,6 @@ public class TestCasts extends TestBase {
     public void testMapDefaultValue() {
         class Root extends TestRootNode<CastNode> {
 
-            @SuppressWarnings("deprecation")
             protected Root(String name) {
                 super(name, setupAndGetCast(b -> b.arg(0).mapNull(constant("X"))));
             }
@@ -244,9 +241,8 @@ public class TestCasts extends TestBase {
 
             final boolean mustBeResultCompilationConstant;
 
-            @SuppressWarnings("deprecation")
             protected Root(String name, boolean mustBeResultCompilationConstant) {
-                super(name, setupAndGetCast(b -> b.arg(0).mapIf(scalarIntegerValue(), constant(10))));
+                super(name, setupAndGetCast(b -> b.arg(0).mapIf(instanceOf(Integer.class), constant(10))));
                 this.mustBeResultCompilationConstant = mustBeResultCompilationConstant;
             }
 
@@ -411,9 +407,8 @@ public class TestCasts extends TestBase {
     public void testFilterAndExpression() {
         class Root extends TestRootNode<CastNode> {
 
-            @SuppressWarnings("deprecation")
             protected Root(String name) {
-                super(name, setupAndGetCast(b -> b.arg(0).mustBe(scalarIntegerValue()).shouldBe(gt0().and(lt(10)))));
+                super(name, setupAndGetCast(b -> b.arg(0).mustBe(instanceOf(Integer.class)).shouldBe(gt0().and(lt(10)))));
             }
 
             @Override
@@ -430,9 +425,8 @@ public class TestCasts extends TestBase {
     public void testFilterNotAndExpression() {
         class Root extends TestRootNode<CastNode> {
 
-            @SuppressWarnings("deprecation")
             protected Root(String name) {
-                super(name, setupAndGetCast(b -> b.arg(0).mustBe(scalarIntegerValue()).shouldBe(gt0().and(lt(10)).not())));
+                super(name, setupAndGetCast(b -> b.arg(0).mustBe(instanceOf(Integer.class)).shouldBe(gt0().and(lt(10)).not())));
             }
 
             @Override
@@ -449,10 +443,9 @@ public class TestCasts extends TestBase {
     public void testComplexPipeline3() {
         class Root extends TestRootNode<CastNode> {
 
-            @SuppressWarnings("deprecation")
             protected Root(String name) {
                 super(name, setupAndGetCast(b -> b.arg(0).mustBe(numericValue()).asVector().mustBe(singleElement()).findFirst().shouldBe(
-                                instanceOf(Byte.class).or(instanceOf(Integer.class).and(gt0())), Message.NON_POSITIVE_FILL).mapIf(scalarLogicalValue(), asBoolean(),
+                                instanceOf(Byte.class).or(instanceOf(Integer.class).and(gt0())), Message.NON_POSITIVE_FILL).mapIf(instanceOf(Byte.class), asBoolean(),
                                                 asInteger())));
             }
 
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java
index 0c92ea9cede464583612935435e0608bfd3fb3e1..d1c7b7d074ed0c80bb58f19d9f4c25ff6ac39496 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java
@@ -387,6 +387,6 @@ public class BinaryArithmeticNodeTest extends BinaryVectorTest {
 
     private static NodeHandle<BinaryArithmeticNode> create(BinaryArithmeticFactory factory) {
         return createHandle(BinaryArithmeticNode.create(factory, null), //
-                        (node, args) -> node.execute(null, args[0], args[1]));
+                        (node, args) -> node.executeBuiltin(null, args[0], args[1]));
     }
 }
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/ChimneySweeping.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/ChimneySweeping.java
index a305b4e2d6d0285b8a57fc697e69503a62961802..0caff997158ece3fa6b2eca40a8e449d5047de54 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/ChimneySweeping.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/ChimneySweeping.java
@@ -36,12 +36,8 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.SortedMap;
-import java.util.function.Consumer;
-import java.util.function.Function;
 import java.util.stream.Collectors;
 
-import javax.swing.SwingWorker;
-
 import org.junit.Assert;
 
 import com.oracle.truffle.api.dsl.UnsupportedSpecializationException;
@@ -59,7 +55,6 @@ import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RSource;
 import com.oracle.truffle.r.runtime.ResourceHandlerFactory;
 import com.oracle.truffle.r.runtime.builtins.RBuiltinKind;
-import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RNull;
@@ -75,7 +70,7 @@ import com.oracle.truffle.r.test.generate.TestOutputManager.TestInfo;
  * <pre>
  * mx rbdiag --sweep --mnonly --matchLevel=error --maxSweeps=30 --outMaxLev=0
  * </pre>
- * 
+ *
  * .
  *
  */
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/DefaultArgsExtractor.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/DefaultArgsExtractor.java
index a4551f6255b03b4f6b3a67ab8bb5cbfed1cda025..1330c6f54b2556920131be33fd8a92ba425367df 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/DefaultArgsExtractor.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/DefaultArgsExtractor.java
@@ -27,7 +27,6 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.function.Consumer;
-import java.util.function.Function;
 
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.vm.PolyglotEngine;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java
index 09a98a59ec9c6b55b525879e4e747c7271451d4e..1aa9f1f5a0b4923bd158366b2aa3310bc913c8f3 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java
@@ -58,6 +58,7 @@ import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.FastPathFactory;
 import com.oracle.truffle.r.runtime.data.REmpty;
+import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
 import com.oracle.truffle.r.runtime.nodes.EvaluatedArgumentsVisitor;
 import com.oracle.truffle.r.runtime.nodes.RCodeBuilder;
@@ -224,8 +225,7 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> {
             String symbol = lookupLHS.getIdentifier();
             if ("slot".equals(symbol) || "@".equals(symbol)) {
                 // this is pretty gross, but at this point seems like the only way to get setClass
-                // to
-                // work properly
+                // to work properly
                 argNodes[0] = GetNonSharedNodeGen.create(argNodes[0].asRNode());
             }
             newSyntaxLHS = lookup(lookupLHS.getSourceSection(), symbol + "<-", true);
@@ -288,15 +288,18 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> {
         RSyntaxElement current = lhs;
         while (!(current instanceof RSyntaxLookup)) {
             if (!(current instanceof RSyntaxCall)) {
-                throw RError.error(RError.NO_CALLER, RError.Message.NON_LANG_ASSIGNMENT_TARGET);
+                if (current instanceof RSyntaxConstant && ((RSyntaxConstant) current).getValue() == RNull.instance) {
+                    throw RError.error(RError.NO_CALLER, RError.Message.INVALID_LHS, "NULL");
+                } else {
+                    throw RError.error(RError.NO_CALLER, RError.Message.NON_LANG_ASSIGNMENT_TARGET);
+                }
             }
             RSyntaxCall call = (RSyntaxCall) current;
             calls.add(call);
 
             RSyntaxElement syntaxLHS = call.getSyntaxLHS();
             if (call.getSyntaxArguments().length == 0 || !(syntaxLHS instanceof RSyntaxLookup || isNamespaceLookupCall(syntaxLHS))) {
-                // TODO: this should only be signaled when run, not when parsed
-                throw RInternalError.unimplemented("proper error message for RError.INVALID_LHS");
+                return new ReplacementNode.LHSError(source, operator, new RSyntaxElement[]{lhs, rhs});
             }
             current = call.getSyntaxArguments()[0];
         }
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 d7e2da0a852435a78f75eca1e7d2d03ebec02e0e..3a07678234bf7670ccbad5709933ce23b5b8d0e7 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
@@ -166,20 +166,6 @@ public class RASTUtils {
         }
     }
 
-    /**
-     * Checks whether {@code expr instanceof RSymbol} and, if so, wraps in an {@link RLanguage}
-     * instance.
-     */
-    @TruffleBoundary
-    public static Object checkForRSymbol(Object expr) {
-        if (expr instanceof RSymbol) {
-            String symbolName = ((RSymbol) expr).getName();
-            return RDataFactory.createLanguage(ReadVariableNode.create(symbolName));
-        } else {
-            return expr;
-        }
-    }
-
     /**
      * Create an {@link RNode} from a runtime value.
      */
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java
index 615037cea562961a9c176a2d1cf2d851246cd71b..2a0cdac93ccdead042e5d958b99db3abf241aee1 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java
@@ -69,7 +69,8 @@ public abstract class BinaryArithmeticNode extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.boxPrimitive(0).boxPrimitive(1);
+        casts.arg(0).boxPrimitive();
+        casts.arg(1).boxPrimitive();
     }
 
     public static BinaryArithmeticNode create(BinaryArithmeticFactory binary, UnaryArithmeticFactory unary) {
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 35a3e16ad6cc4b751b3fbbe51fd779a81ee919b9..baf03bf896a421ab3777708a6337204cd560bcb2 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
@@ -69,7 +69,8 @@ public abstract class BinaryBooleanNode extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.boxPrimitive(0).boxPrimitive(1);
+        casts.arg(0).boxPrimitive();
+        casts.arg(1).boxPrimitive();
     }
 
     private static boolean isLogicOp(BooleanOperation op) {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/AbstractPredicateArgumentFilter.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/AbstractPredicateArgumentFilter.java
index d9e0a2d349da2d1c6f3e24abcaf0a00fd64fcc82..2dcc0afe90feec17d81b01fef0ab60b791cbd3b1 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/AbstractPredicateArgumentFilter.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/AbstractPredicateArgumentFilter.java
@@ -24,9 +24,7 @@ package com.oracle.truffle.r.nodes.builtin;
 
 import java.util.function.Predicate;
 
-import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.builtin.ArgumentFilter.NarrowingArgumentFilter;
-import com.oracle.truffle.r.runtime.data.RNull;
 
 public abstract class AbstractPredicateArgumentFilter<T, R extends T> implements NarrowingArgumentFilter<T, R> {
 
@@ -40,5 +38,4 @@ public abstract class AbstractPredicateArgumentFilter<T, R extends T> implements
     public boolean test(T arg) {
         return valuePredicate.test(arg);
     }
-
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java
index 2e13d1247171c3cf00d3683c7060a68311b4124e..c7f6bc6ef0902217fbd27c9c934c964dba756359 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java
@@ -22,8 +22,6 @@
  */
 package com.oracle.truffle.r.nodes.builtin;
 
-import static com.oracle.truffle.r.runtime.RError.SHOW_CALLER;
-
 import java.util.Arrays;
 import java.util.function.Consumer;
 
@@ -44,7 +42,6 @@ import com.oracle.truffle.r.nodes.builtin.casts.Mapper.MapToCharAt;
 import com.oracle.truffle.r.nodes.builtin.casts.Mapper.MapToValue;
 import com.oracle.truffle.r.nodes.builtin.casts.MessageData;
 import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep;
-import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.BoxPrimitiveStep;
 import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.CoercionStep;
 import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.FilterStep;
 import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.MapIfStep;
@@ -58,8 +55,6 @@ import com.oracle.truffle.r.nodes.builtin.casts.fluent.PipelineBuilder;
 import com.oracle.truffle.r.nodes.builtin.casts.fluent.PipelineConfigBuilder;
 import com.oracle.truffle.r.nodes.builtin.casts.fluent.PreinitialPhaseBuilder;
 import com.oracle.truffle.r.nodes.unary.CastNode;
-import com.oracle.truffle.r.nodes.unary.CastToVectorNode;
-import com.oracle.truffle.r.nodes.unary.FindFirstNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
@@ -138,105 +133,6 @@ public final class CastBuilder {
         return castsCache;
     }
 
-    // ---------------
-    // Deprecated API:
-    // Converted to the new API preserving original semantics as much as possible
-
-    private PipelineBuilder getBuilderForDeprecated(int index) {
-        PipelineBuilder builder = getBuilder(index, "");
-        builder.getPipelineConfig().allowNull();
-        return builder;
-    }
-
-    public CastBuilder toVector(int index) {
-        PipelineBuilder builder = getBuilderForDeprecated(index);
-        // TODO: asVector with preserveNonVector transforms RNull, this is not compatible with the
-        // semantics of RNull being forwarded by all cast nodes. Because of this we need to map null
-        // for legacy API calls
-        builder.getPipelineConfig().setWasLegacyAsVectorCall();
-        builder.getPipelineConfig().mapNull(new MapToValue<>(RDataFactory.createList()));
-        builder.appendAsVector(false, false, false, false);
-        return this;
-    }
-
-    public CastBuilder toInteger(int index) {
-        PipelineBuilder builder = getBuilderForDeprecated(index);
-        if (builder.getPipelineConfig().wasLegacyAsVectorCall()) {
-            mapNullAndMissing(builder, RDataFactory.createIntVector(0));
-        } else {
-            builder.getPipelineConfig().mapNull(new MapToValue<>(RNull.instance));
-        }
-        builder.appendAsIntegerVector(false, false, false);
-        return this;
-    }
-
-    public CastBuilder toDouble(int index) {
-        PipelineBuilder builder = getBuilderForDeprecated(index);
-        if (builder.getPipelineConfig().wasLegacyAsVectorCall()) {
-            builder.getPipelineConfig().mapNull(new MapToValue<>(RDataFactory.createDoubleVector(0)));
-            // CastDoubleBaseNode does not handle RMissing it seems...
-        } else {
-            allowNullAndMissing(builder);
-        }
-        builder.appendAsDoubleVector(false, false, false);
-        return this;
-    }
-
-    public CastBuilder toLogical(int index) {
-        PipelineBuilder builder = getBuilderForDeprecated(index);
-        if (builder.getPipelineConfig().wasLegacyAsVectorCall()) {
-            mapNullAndMissing(builder, RDataFactory.createLogicalVector(0));
-        } else {
-            allowNullAndMissing(builder);
-        }
-        builder.appendAsLogicalVector(false, false, false);
-        return this;
-    }
-
-    public CastBuilder boxPrimitive(int index) {
-        PipelineBuilder builder = getBuilderForDeprecated(index);
-        allowNullAndMissing(builder);
-        builder.append(new BoxPrimitiveStep<>());
-        return this;
-    }
-
-    public CastBuilder firstIntegerWithError(int index, RError.Message error, String name) {
-        // TODO: check if we can remove FirstIntNode when this is removed...
-        getBuilderForDeprecated(index).appendAsIntegerVector(false, false, false);
-        getBuilderForDeprecated(index).appendFindFirst(null, Integer.class, SHOW_CALLER, error, new Object[]{name});
-        return this;
-    }
-
-    public CastBuilder firstBoolean(int index) {
-        PipelineBuilder builder = getBuilderForDeprecated(index);
-        builder.appendAsLogicalVector(false, false, false);
-        builder.appendFindFirst(null, Byte.class, SHOW_CALLER, RError.Message.ARGUMENT_NOT_INTERPRETABLE_LOGICAL, new Object[0]);
-        builder.appendMap(MapByteToBoolean.INSTANCE);
-        return this;
-    }
-
-    public CastBuilder firstBoolean(int index, String invalidValueName) {
-        if (invalidValueName == null) {
-            return firstBoolean(index);
-        }
-        PipelineBuilder builder = getBuilderForDeprecated(index);
-        builder.appendAsLogicalVector(false, false, false);
-        builder.appendFindFirst(null, Byte.class, SHOW_CALLER, RError.Message.INVALID_VALUE, new Object[]{invalidValueName});
-        builder.appendMap(MapByteToBoolean.INSTANCE);
-        return this;
-    }
-
-    private void allowNullAndMissing(PipelineBuilder builder) {
-        builder.getPipelineConfig().mapNull(new MapToValue<>(RNull.instance));
-        builder.getPipelineConfig().mapMissing(new MapToValue<>(RMissing.instance));
-    }
-
-    private void mapNullAndMissing(PipelineBuilder builder, Object value) {
-        builder.getPipelineConfig().mapNull(new MapToValue<>(value));
-        builder.getPipelineConfig().mapMissing(new MapToValue<>(value));
-    }
-
-    // end of deprecated API:
     // ---------------------
     // The cast-pipelines API starts here
 
@@ -785,46 +681,14 @@ public final class CastBuilder {
             return (Filter<Object, RAbstractVector>) f;
         }
 
-        /**
-         * @deprecated tests for scalar types are dangerous
-         */
-        @Deprecated
-        public static Filter<Object, Integer> scalarIntegerValue() {
-            return new TypeFilter<>(x -> x instanceof String, String.class);
-        }
-
         public static Filter<Object, Integer> atomicIntegerValue() {
             return new TypeFilter<>(x -> x instanceof String, String.class);
         }
 
-        /**
-         * @deprecated tests for scalar types are dangerous
-         */
-        @Deprecated
-        public static Filter<Object, Double> scalarDoubleValue() {
-            return new TypeFilter<>(x -> x instanceof Double, Double.class);
-        }
-
-        /**
-         * @deprecated tests for scalar types are dangerous
-         */
-        @Deprecated
-        public static Filter<Object, Byte> scalarLogicalValue() {
-            return new TypeFilter<>(x -> x instanceof Byte, Byte.class);
-        }
-
         public static Filter<Object, Byte> atomicLogicalValue() {
             return new TypeFilter<>(x -> x instanceof Byte, Byte.class);
         }
 
-        /**
-         * @deprecated tests for scalar types are dangerous
-         */
-        @Deprecated
-        public static Filter<Object, RComplex> scalarComplexValue() {
-            return new TypeFilter<>(x -> x instanceof RComplex, RComplex.class);
-        }
-
         public static MapByteToBoolean toBoolean() {
             return MapByteToBoolean.INSTANCE;
         }
@@ -884,6 +748,5 @@ public final class CastBuilder {
         public static <T> MapToValue<T, RList> emptyList() {
             return new MapToValue<>(RDataFactory.createList());
         }
-
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinNode.java
index c7baa04648c333a50c3de612fa5077a1d9aeb45e..1e9a808b1fc69fb21424eaf07615291ad937f0c8 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinNode.java
@@ -51,7 +51,7 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 @NodeChild(value = "arguments", type = RNode[].class)
 public abstract class RBuiltinNode extends RNode {
 
-    public abstract Object execute(VirtualFrame frame, Object... args);
+    public abstract Object executeBuiltin(VirtualFrame frame, Object... args);
 
     protected void createCasts(@SuppressWarnings("unused") CastBuilder casts) {
         // nothing to do
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineStep.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineStep.java
index 288dde89c583cba87639b1a3f032adf5c6e79a3c..a13c29fc1cad2114fe791f136ffc9d55f9f91550 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineStep.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineStep.java
@@ -22,9 +22,6 @@
  */
 package com.oracle.truffle.r.nodes.builtin.casts;
 
-import java.util.function.Supplier;
-
-import com.oracle.truffle.r.nodes.unary.CastNode;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.data.RAttributable;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
@@ -71,8 +68,6 @@ public abstract class PipelineStep<T, R> {
 
         T visit(BoxPrimitiveStep<?> step);
 
-        T visit(CustomNodeStep<?> step);
-
         T visit(AttributableCoercionStep<?> step);
     }
 
@@ -339,26 +334,4 @@ public abstract class PipelineStep<T, R> {
             return visitor.visit(this);
         }
     }
-
-    /**
-     * Allows to insert arbitrary node into the cast pipeline. Should be avoided as much as
-     * possible, because it hinders inference of any semantics from the pipeline intermediate
-     * representation. This step is here for legacy reasons and will be removed in the future.
-     */
-    public static final class CustomNodeStep<T> extends PipelineStep<T, Object> {
-        private final Supplier<CastNode> factory;
-
-        public CustomNodeStep(Supplier<CastNode> factory) {
-            this.factory = factory;
-        }
-
-        public Supplier<CastNode> getFactory() {
-            return factory;
-        }
-
-        @Override
-        public <D> D accept(PipelineStepVisitor<D> visitor) {
-            return visitor.visit(this);
-        }
-    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineToCastNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineToCastNode.java
index 3b1104be7927f27ffd1b50d7ef3755e212ea6241..62a36d3fe0dbd00861a40a3e90e59a382b70cbcd 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineToCastNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineToCastNode.java
@@ -50,7 +50,6 @@ import com.oracle.truffle.r.nodes.builtin.casts.Mapper.MapperVisitor;
 import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.AttributableCoercionStep;
 import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.BoxPrimitiveStep;
 import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.CoercionStep;
-import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.CustomNodeStep;
 import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.DefaultErrorStep;
 import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.DefaultWarningStep;
 import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.FilterStep;
@@ -243,12 +242,6 @@ public final class PipelineToCastNode {
             return inner.visit(step);
         }
 
-        @Override
-        public CastNode visit(CustomNodeStep<?> step) {
-            cannotBeOptimizedBeforeFindFirst();
-            return inner.visit(step);
-        }
-
         @Override
         public CastNode visit(AttributableCoercionStep<?> step) {
             cannotBeOptimizedBeforeFindFirst();
@@ -275,7 +268,7 @@ public final class PipelineToCastNode {
          */
         private RType checkFilter(Filter<?, ?> filter) {
             if (filter instanceof RTypeFilter) {
-                RType type = ((RTypeFilter) filter).getType();
+                RType type = ((RTypeFilter<?>) filter).getType();
                 if (targetType == null) {
                     return type;
                 }
@@ -308,7 +301,7 @@ public final class PipelineToCastNode {
 
         private static boolean isNextMapToBoolean(FindFirstStep<?, ?> findFirst) {
             PipelineStep<?, ?> next = findFirst.getNext();
-            return next != null && next instanceof MapStep && ((MapStep) next).getMapper() instanceof MapByteToBoolean;
+            return next != null && next instanceof MapStep && ((MapStep<?, ?>) next).getMapper() instanceof MapByteToBoolean;
         }
     }
 
@@ -354,11 +347,6 @@ public final class PipelineToCastNode {
             return BoxPrimitiveNode.create();
         }
 
-        @Override
-        public CastNode visit(CustomNodeStep<?> step) {
-            return step.getFactory().get();
-        }
-
         @Override
         public CastNode visit(FindFirstStep<?, ?> step) {
             boxPrimitives = false;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/ArgCastBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/ArgCastBuilder.java
index bb0a694e8244a7217b01b5095c4bad8ab3e778b0..3811fe65a1a8c14bd7f061d0f9b35a05eded4909 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/ArgCastBuilder.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/ArgCastBuilder.java
@@ -23,11 +23,8 @@
 package com.oracle.truffle.r.nodes.builtin.casts.fluent;
 
 import java.util.function.Function;
-import java.util.function.Supplier;
 
 import com.oracle.truffle.r.nodes.builtin.casts.Filter;
-import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.CustomNodeStep;
-import com.oracle.truffle.r.nodes.unary.CastNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 
@@ -78,14 +75,6 @@ public class ArgCastBuilder<T, THIS> {
         return (THIS) this;
     }
 
-    /**
-     * Custom nodes in cast pipeline block optimisations and analysis, use them sparsely.
-     */
-    public THIS customNode(Supplier<CastNode> castNodeFactory) {
-        pipelineBuilder().append(new CustomNodeStep<>(castNodeFactory));
-        return (THIS) this;
-    }
-
     public <R, THAT extends ArgCastBuilder<R, THAT>> THAT alias(Function<THIS, THAT> aliaser) {
         return aliaser.apply((THIS) this);
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/InitialPhaseBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/InitialPhaseBuilder.java
index fea8b77156fe7c972bc4672043896d44eb260aa8..bec9e0943e38390c5ec2f598f6edd3255ecc0949 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/InitialPhaseBuilder.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/InitialPhaseBuilder.java
@@ -142,6 +142,11 @@ public class InitialPhaseBuilder<T> extends ArgCastBuilder<T, InitialPhaseBuilde
         return this;
     }
 
+    public InitialPhaseBuilder<T> boxPrimitive() {
+        pipelineBuilder().appendBoxPrimitive();
+        return this;
+    }
+
     public CoercedPhaseBuilder<RAbstractIntVector, Integer> asIntegerVector(boolean preserveNames, boolean dimensionsPreservation, boolean attrPreservation) {
         pipelineBuilder().appendAsIntegerVector(preserveNames, dimensionsPreservation, attrPreservation);
         return new CoercedPhaseBuilder<>(pipelineBuilder(), Integer.class);
@@ -200,7 +205,7 @@ public class InitialPhaseBuilder<T> extends ArgCastBuilder<T, InitialPhaseBuilde
     }
 
     public CoercedPhaseBuilder<RAbstractVector, Object> asVectorPreserveAttrs(boolean preserveNonVector) {
-        pipelineBuilder().appendAsVector(false, false, true, false);
+        pipelineBuilder().appendAsVector(false, false, true, preserveNonVector);
         return new CoercedPhaseBuilder<>(pipelineBuilder(), Object.class);
     }
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PipelineBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PipelineBuilder.java
index 251c4d5244242c4d09396068f9027543ee3e0af2..d94cda9d6252bd54f651fa854de6e91ea3be13ad 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PipelineBuilder.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PipelineBuilder.java
@@ -70,6 +70,10 @@ public final class PipelineBuilder {
         return chainBuilder != null ? chainBuilder.getFirstStep() : null;
     }
 
+    public void appendBoxPrimitive() {
+        append(new PipelineStep.BoxPrimitiveStep<>());
+    }
+
     public void appendFindFirst(Object defaultValue, Class<?> elementClass, RBaseNode callObj, Message message, Object[] messageArgs) {
         append(new FindFirstStep<>(defaultValue, elementClass, createMessage(callObj, message, messageArgs)));
     }
@@ -158,7 +162,7 @@ public final class PipelineBuilder {
         append(new DefaultErrorStep<>(createMessage(callObj, message, args)));
     }
 
-    private MessageData createMessage(RBaseNode callObj, Message message, Object[] messageArgs) {
+    private static MessageData createMessage(RBaseNode callObj, Message message, Object[] messageArgs) {
         return message == null ? null : new MessageData(callObj, message, messageArgs);
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java
index 8d38dc3f1f5d4d63b64a6e779bbdacae4ed40829..4efcf6edff934be9b8391b74132ab867f4ada397 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java
@@ -24,6 +24,7 @@ package com.oracle.truffle.r.nodes.control;
 
 import java.util.List;
 
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.ExplodeLoop;
 import com.oracle.truffle.api.source.SourceSection;
@@ -31,6 +32,8 @@ import com.oracle.truffle.r.nodes.access.RemoveAndAnswerNode;
 import com.oracle.truffle.r.nodes.access.WriteVariableNode;
 import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
+import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.Message;
 import com.oracle.truffle.r.runtime.nodes.RNode;
 import com.oracle.truffle.r.runtime.nodes.RSourceSectionNode;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxCall;
@@ -119,4 +122,41 @@ public final class ReplacementNode extends RSourceSectionNode implements RSyntax
     public ArgumentsSignature getSyntaxSignature() {
         return ArgumentsSignature.empty(2);
     }
+
+    /**
+     * Used by the parser for assignments that miss a left hand side. This node will raise an error
+     * once executed.
+     */
+    public static final class LHSError extends RSourceSectionNode implements RSyntaxNode, RSyntaxCall {
+
+        private final String operator;
+        private final RSyntaxElement[] arguments;
+
+        public LHSError(SourceSection sourceSection, String operator, RSyntaxElement[] arguments) {
+            super(sourceSection);
+            this.operator = operator;
+            this.arguments = arguments;
+        }
+
+        @Override
+        public Object execute(VirtualFrame frame) {
+            CompilerDirectives.transferToInterpreter();
+            throw RError.error(this, Message.INVALID_LHS, "NULL");
+        }
+
+        @Override
+        public RSyntaxElement getSyntaxLHS() {
+            return RSyntaxLookup.createDummyLookup(null, operator, true);
+        }
+
+        @Override
+        public RSyntaxElement[] getSyntaxArguments() {
+            return arguments;
+        }
+
+        @Override
+        public ArgumentsSignature getSyntaxSignature() {
+            return ArgumentsSignature.empty(2);
+        }
+    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java
index 6cb1c9e2fa8b3bccf305ebb595da5f462c688b14..6cf27926a04a0aac6d089a00f9214985248a7642 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java
@@ -259,7 +259,7 @@ public abstract class CallMatcherNode extends RBaseNode {
                     }
                 } else {
                     applyCasts(reorderedArgs);
-                    Object result = builtin.execute(frame, reorderedArgs);
+                    Object result = builtin.executeBuiltin(frame, reorderedArgs);
                     visibility.execute(frame, builtinDescriptor.getVisibility());
                     return result;
                 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java
index 42db3db48c7f20aea67b49aa1756c263504c4dc0..de186c6978388c344d79f020d5073c109c1e6028 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java
@@ -985,7 +985,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS
 
         @Override
         public Object execute(VirtualFrame frame, RFunction currentFunction, RArgsValuesAndNames orderedArguments, S3Args s3Args) {
-            Object result = builtin.execute(frame, castArguments(frame, orderedArguments.getArguments()));
+            Object result = builtin.executeBuiltin(frame, castArguments(frame, orderedArguments.getArguments()));
             visibility.execute(frame, builtinDescriptor.getVisibility());
             return result;
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/GetNonSharedNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/GetNonSharedNode.java
index 82702afdceeb9813bf4b089a3b33e0e5422ee455..b15d5556ee76210cfdb87d4af6be208289ea8fcb 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/GetNonSharedNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/GetNonSharedNode.java
@@ -22,7 +22,6 @@
  */
 package com.oracle.truffle.r.nodes.unary;
 
-import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.NodeChild;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.ValueProfile;
@@ -39,12 +38,23 @@ public abstract class GetNonSharedNode extends RNode implements RSyntaxNode {
 
     private final ValueProfile shareableTypeProfile = ValueProfile.createClassProfile();
 
+    protected abstract RNode getN();
+
+    @Override
+    protected RSyntaxNode getRSyntaxNode() {
+        return getN().asRSyntaxNode();
+    }
+
     @Specialization
     protected RTypedValue getNonShared(RShareable shareable) {
         return shareableTypeProfile.profile(shareable).getNonShared();
     }
 
-    @Fallback
+    protected static boolean isRShareable(Object o) {
+        return o instanceof RShareable;
+    }
+
+    @Specialization(guards = "!isRShareable(o)")
     protected Object getNonShared(Object o) {
         return o;
     }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
index 28672fad9a3a8e996b98d01cba4c6568c9933521..b40ea24d42fed02822279ed54fc5ea7a56390faf 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
@@ -283,6 +283,7 @@ public final class RError extends RuntimeException {
         TRACEMEM_NOT_NULL("cannot trace NULL"),
         // below: GNU R gives also expression for the argument
         NOT_FUNCTION("'%s' is not a function, character or symbol"),
+        NOT_A_FUNCTION("'%s' is not a function"),
         NON_CHARACTER("non-character argument"),
         NON_CHARACTER_NAMES("non-character names"),
         NON_NUMERIC_MATH("non-numeric argument to mathematical function"),
@@ -346,8 +347,11 @@ public final class RError extends RuntimeException {
         AS_ENV_NULL_DEFUNCT("using 'as.environment(NULL)' is defunct"),
         REPLACEMENT_NOT_ENVIRONMENT("replacement object is not an environment"),
         ARGUMENT_NOT_MATRIX("argument is not a matrix"),
+        ARGUMENT_NOT_ENVIRONMENT("argument is not an environment"),
+        ARGUMENT_NAME_NOT_ENVIRONMENT("'%s' is not an environment"),
         DOLLAR_ATOMIC_VECTORS("$ operator is invalid for atomic vectors"),
         COERCING_LHS_TO_LIST("Coercing LHS to a list"),
+        INVALID_LHS("invalid (%s) left side of assignment"),
         ARGUMENT_NOT_LIST("argument not a list"),
         FIRST_ARGUMENT_NOT_NAMED_LIST("first argument must be a named list"),
         FIRST_ARGUMENT_NOT_CHARVEC("first argument must be a character vector"),
@@ -363,6 +367,7 @@ public final class RError extends RuntimeException {
         DIMS_CONTAIN_NA("the dims contain missing values"),
         LENGTH_ZERO_DIM_INVALID("length-0 dimension vector is invalid"),
         ATTRIBUTES_LIST_OR_NULL("attributes must be a list or NULL"),
+        SET_ATTRIBUTES_ON_NULL("attempt to set an attribute on NULL"),
         RECALL_CALLED_OUTSIDE_CLOSURE("'Recall' called from outside a closure"),
         MATCH_CALL_CALLED_OUTSIDE_FUNCTION("match.call() was called from outside a function"),
         NOT_NUMERIC_VECTOR("argument is not a numeric vector"),
@@ -425,9 +430,10 @@ public final class RError extends RuntimeException {
         UNKNOWN_FUNCTION_USE_METHOD("no applicable method for '%s' applied to an object of class '%s'"),
         UNKNOWN_OBJECT("object '%s' not found"),
         INVALID_ARGUMENT("invalid '%s' argument"),
-        INVALID_POS_ARGUMENT("invalid 'pos' argument"),
+        INVALID_ARGUMENT_OF_TYPE("invalid '%s' argument of type '%s'"),
         INVALID_VALUE("invalid '%s' value"),
         INVALID_ARGUMENTS_NO_QUOTE("invalid %s arguments"),
+        INVALID_SUBSCRIPT("invalid subscript"),
         INVALID_SUBSCRIPT_TYPE("invalid subscript type '%s'"),
         ARGUMENT_NOT_VECTOR("argument %d is not a vector"),
         CANNOT_COERCE("cannot coerce type '%s' to vector of type '%s'"),
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 c2de79e332b9ce4d19173369b1b3cea5b0d26fdf..781156ff27b2b2ae3d7d66fc72940b0d0c19f42a 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
@@ -24,7 +24,6 @@ package com.oracle.truffle.r.runtime.context;
 
 import java.util.TimeZone;
 import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Function;
 
 import com.oracle.truffle.api.interop.ForeignAccess;
 import com.oracle.truffle.api.interop.TruffleObject;
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java
index a20bd4105cb831c357e7d22f6a32afbb9bf588e7..6621d6063dffb62b98380ae2a559dd604e519d77 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java
@@ -46,7 +46,7 @@ import com.oracle.truffle.r.runtime.nodes.RBaseNode;
  *
  */
 @ValueType
-public class RLanguage extends RSharingAttributeStorage implements RAbstractContainer, RAttributable {
+public class RLanguage extends RSharingAttributeStorage implements RAbstractContainer {
 
     /*
      * Used for RLanguage construction from separate AST components.
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java
index 14ea9d792a67f1d41a999b07344e982b5017d96e..f8f7aad81987779a9cfa1dd2d42043a38e11d070 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java
@@ -606,7 +606,7 @@ public abstract class REnvironment extends RAttributeStorage {
             detachException(RError.Message.ENV_DETACH_BASE);
         }
         if (pos <= 0 || pos >= searchPath.size()) {
-            detachException(RError.Message.INVALID_POS_ARGUMENT);
+            detachException(RError.Message.INVALID_ARGUMENT, "pos");
         }
         assert pos != 1; // explicitly checked in caller
         // N.B. pos is 1-based
@@ -620,8 +620,8 @@ public abstract class REnvironment extends RAttributeStorage {
     }
 
     @TruffleBoundary
-    private static void detachException(RError.Message message) throws DetachException {
-        throw new DetachException(message);
+    private static void detachException(RError.Message message, Object... args) throws DetachException {
+        throw new DetachException(message, args);
     }
 
     /**
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 799d2daf6d67bb465aca9013fd883a6ad3b743c9..f2d2e23fb007f43449bc76abe0091e3837d0ef14 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
@@ -18816,6 +18816,16 @@ NULL
 #argv <- list(structure(numeric(0), .Dim = c(0L, 0L))); .Internal(environmentName(argv[[1]]))
 [1] ""
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_environmentassign.testenvironmentassign1
+#{ e1 <- 1; e2 <- new.env(); environment(e1) <- e2 }
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_environmentassign.testenvironmentassign1
+#{ e1 <- 1; environment(e1) <- 3 }
+Error in environment(e1) <- 3 : replacement object is not an environment
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_environmentassign.testenvironmentassign1
+#{ e1 <- 1; environment(e1) <- NULL }
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_environmentassign.testenvironmentassign1
 #{ e1 <- new.env(); e2 <- new.env(); environment(e1) <- e2 }
 
@@ -18826,6 +18836,11 @@ Error in environment(e1) <- 3 : replacement object is not an environment
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_environmentassign.testenvironmentassign1
 #{ e1 <- new.env(); environment(e1) <- NULL }
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_environmentassign.testenvironmentassign1
+#{ f <- NULL; environment(f) <- new.env() }
+Error in environment(f) <- new.env() :
+  attempt to set an attribute on NULL
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_environmentassign.testenvironmentassign1
 #{ f <- function() x; f2 <- f; e <- new.env(); assign('x', 2, envir=e); x <- 1; environment(f) <- e; c(f(), f2())}
 [1] 2 1
@@ -18833,6 +18848,22 @@ Error in environment(e1) <- 3 : replacement object is not an environment
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_environmentassign.testenvironmentassign1
 #{ f <- function() {}; e1 <- new.env(); environment(f) <- e1 }
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_environmentassign.testenvironmentassign1
+#{ f <- function() {}; environment(f) <- NULL }
+Error in environment(f) <- NULL : use of NULL environment is defunct
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_eval.testEval
+#eval('foo')
+[1] "foo"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_eval.testEval
+#eval(as.symbol('baseenv'))
+function ()  .Primitive("baseenv")
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_eval.testEval
+#eval(as.symbol('foo'))
+Error in eval(expr, envir, enclos) : object 'foo' not found
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_eval.testEval
 #eval({ xx <- pi; xx^2}) ; xx
 [1] 9.869604
@@ -28323,6 +28354,33 @@ Coefficients:
 #require(stats); lm(formula = y ~ x)
 Error in eval(expr, envir, enclos) : object 'y' not found
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lockEnvironment.testlockEnvironment
+#e <- new.env(); e$a <- 'foo'; lockEnvironment(e, 'a'); e$a <- 123
+Error in e$a <- 123 : cannot change value of locked binding for 'a'
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lockEnvironment.testlockEnvironment
+#e <- new.env(); e$a <- 'foo'; lockEnvironment(e, 'a'); e$b <- 123
+Error in e$b <- 123 : cannot add bindings to a locked environment
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lockEnvironment.testlockEnvironment
+#e <- new.env(); e$a <- 'foo'; lockEnvironment(e, FALSE); e$a <- 123
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lockEnvironment.testlockEnvironment
+#e <- new.env(); e$a <- 'foo'; lockEnvironment(e, FALSE); e$b <- 123
+Error in e$b <- 123 : cannot add bindings to a locked environment
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lockEnvironment.testlockEnvironment
+#e <- new.env(); e$a <- 'foo'; lockEnvironment(e, logical()); e$a <- 123
+Error in e$a <- 123 : cannot change value of locked binding for 'a'
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lockEnvironment.testlockEnvironment
+#e <- new.env(); e$a <- 'foo'; lockEnvironment(e, logical()); e$b <- 123
+Error in e$b <- 123 : cannot add bindings to a locked environment
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_lockEnvironment.testlockEnvironment
+#lockEnvironment('foo', TRUE)
+Error in lockEnvironment("foo", TRUE) : not an environment
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_log.testLog
 #{ log(0) }
 [1] -Inf
@@ -32208,6 +32266,27 @@ Error in argv[[4]] : subscript out of bounds
 #argv <- structure(list(x = structure(list(pop15 = c(29.35, 23.32,     23.8, 41.89, 42.19, 31.72, 39.74, 44.75, 46.64, 47.64, 24.42,     46.31, 27.84, 25.06, 23.31, 25.62, 46.05, 47.32, 34.03, 41.31,     31.16, 24.52, 27.01, 41.74, 21.8, 32.54, 25.95, 24.71, 32.61,     45.04, 43.56, 41.18, 44.19, 46.26, 28.96, 31.94, 31.92, 27.74,     21.44, 23.49, 43.42, 46.12, 23.27, 29.81, 46.4, 45.25, 41.12,     28.13, 43.69, 47.2), pop75 = c(2.87, 4.41, 4.43, 1.67, 0.83,     2.85, 1.34, 0.67, 1.06, 1.14, 3.93, 1.19, 2.37, 4.7, 3.35,     3.1, 0.87, 0.58, 3.08, 0.96, 4.19, 3.48, 1.91, 0.91, 3.73,     2.47, 3.67, 3.25, 3.17, 1.21, 1.2, 1.05, 1.28, 1.12, 2.85,     2.28, 1.52, 2.87, 4.54, 3.73, 1.08, 1.21, 4.46, 3.43, 0.9,     0.56, 1.73, 2.72, 2.07, 0.66), dpi = c(2329.68, 1507.99,     2108.47, 189.13, 728.47, 2982.88, 662.86, 289.52, 276.65,     471.24, 2496.53, 287.77, 1681.25, 2213.82, 2457.12, 870.85,     289.71, 232.44, 1900.1, 88.94, 1139.95, 1390, 1257.28, 207.68,     2449.39, 601.05, 2231.03, 1740.7, 1487.52, 325.54, 568.56,     220.56, 400.06, 152.01, 579.51, 651.11, 250.96, 768.79, 3299.49,     2630.96, 389.66, 249.87, 1813.93, 4001.89, 813.39, 138.33,     380.47, 766.54, 123.58, 242.69), ddpi = c(2.87, 3.93, 3.82,     0.22, 4.56, 2.43, 2.67, 6.51, 3.08, 2.8, 3.99, 2.19, 4.32,     4.52, 3.44, 6.28, 1.48, 3.19, 1.12, 1.54, 2.99, 3.54, 8.21,     5.81, 1.57, 8.12, 3.62, 7.66, 1.76, 2.48, 3.61, 1.03, 0.67,     2, 7.48, 2.19, 2, 4.35, 3.01, 2.7, 2.96, 1.13, 2.01, 2.45,     0.53, 5.14, 10.23, 1.88, 16.71, 5.08)), .Names = c('pop15',     'pop75', 'dpi', 'ddpi'), class = 'data.frame', row.names = c('Australia',     'Austria', 'Belgium', 'Bolivia', 'Brazil', 'Canada', 'Chile',     'China', 'Colombia', 'Costa Rica', 'Denmark', 'Ecuador',     'Finland', 'France', 'Germany', 'Greece', 'Guatamala', 'Honduras',     'Iceland', 'India', 'Ireland', 'Italy', 'Japan', 'Korea',     'Luxembourg', 'Malta', 'Norway', 'Netherlands', 'New Zealand',     'Nicaragua', 'Panama', 'Paraguay', 'Peru', 'Philippines',     'Portugal', 'South Africa', 'South Rhodesia', 'Spain', 'Sweden',     'Switzerland', 'Turkey', 'Tunisia', 'United Kingdom', 'United States',     'Venezuela', 'Zambia', 'Jamaica', 'Uruguay', 'Libya', 'Malaysia'))),     .Names = 'x');do.call('ncol', argv)
 [1] 4
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_newenv.testnewenv
+#e <- new.env(); e; parent.env(new.env(TRUE, e))
+<environment: 0x7ff8e986ea08>
+<environment: 0x7ff8e986ea08>
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_newenv.testnewenv
+#new.env()
+<environment: 0x7fd14b800e98>
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_newenv.testnewenv
+#new.env(1,,2)
+<environment: 0x7ff87086ebc8>
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_newenv.testnewenv
+#new.env(logical(),new.env(),1000)
+<environment: 0x7ff11406d518>
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_newenv.testnewenv
+#parent.env(new.env())
+<environment: R_GlobalEnv>
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_ngettext.testNgettext
 #{ ngettext(-1, "a", "b") }
 Error in ngettext(-1, "a", "b") : invalid 'n' argument
@@ -37547,6 +37626,74 @@ foo
 #argv <- list();do.call('pairlist', argv)
 NULL
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_parentenv.testParentEnv
+#e <- new.env(); parent.env(e)
+<environment: R_GlobalEnv>
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_parentenv.testParentEnv
+#parent.env()
+Error in parent.env() : argument "env" is missing, with no default
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_parentenv.testParentEnv
+#parent.env(1)
+Error in parent.env(1) : argument is not an environment
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_parentenv.testParentEnv
+#parent.env(NULL)
+Error in parent.env(NULL) : argument is not an environment
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_parentenv.testParentEnv
+#parent.env(c(1,2,3))
+Error in parent.env(c(1, 2, 3)) : argument is not an environment
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_parentenvassign.testParentEnv
+#e <- new.env(); e2 <- new.env(); parent.env(e) <- e2; parent.env(e)
+<environment: 0x7fd30086dbc8>
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_parentenvassign.testParentEnv
+#e <- new.env(); parent.env(e) <- 44
+Error in `parent.env<-`(`*tmp*`, value = 44) :
+  'parent' is not an environment
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_parentenvassign.testParentEnv
+#e <- new.env(); parent.env(e) <- NULL
+Error in `parent.env<-`(`*tmp*`, value = NULL) :
+  use of NULL environment is defunct
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_parentenvassign.testParentEnv
+#e <- new.env(); parent.env(e) <- c(1,2,3)
+Error in `parent.env<-`(`*tmp*`, value = c(1, 2, 3)) :
+  'parent' is not an environment
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_parentenvassign.testParentEnv
+#e <- new.env(); parent.env(e) <- emptyenv(); parent.env(e)
+<environment: R_EmptyEnv>
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_parentenvassign.testParentEnv
+#parent.env() <- new.env()
+Error in parent.env() <- new.env() :
+  invalid (NULL) left side of assignment
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_parentenvassign.testParentEnv
+#parent.env(1) <- new.env()
+Error in parent.env(1) <- new.env() :
+  target of assignment expands to non-language object
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_parentenvassign.testParentEnv
+#parent.env(NULL) <- new.env()
+Error in parent.env(NULL) <- new.env() :
+  invalid (NULL) left side of assignment
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_parentenvassign.testParentEnv
+#parent.env(c(1,2,3)) <- new.env()
+Error in parent.env(c(1, 2, 3)) <- new.env() :
+  target of assignment expands to non-language object
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_parentenvassign.testParentEnv
+#parent.env(emptyenv()) <- new.env()
+Error in parent.env(emptyenv()) <- new.env() :
+  invalid (NULL) left side of assignment
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_parentframe.testParentFrame
 #parent.frame()
 <environment: R_GlobalEnv>
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_bitwiseAnd.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_bitwiseAnd.java
index d26c48edf1e96dc6a58e248e60ac8a04aede7bb1..5e17f59f744d6ad621bc4bbf2e5f61a07f0c0144 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_bitwiseAnd.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_bitwiseAnd.java
@@ -35,7 +35,7 @@ public class TestBuiltin_bitwiseAnd extends TestBase {
         assertEval("{ bitwAnd(c(10.5,11.6,17.8), c(5L,7L,8L)) }");
 
         assertEval(Output.IgnoreErrorContext, "{ bitwAnd(NULL, NULL) }");
-        assertEval(Ignored.Unknown, "{ bitwAnd(c(), c(1,2,3)) }");
+        assertEval(Output.IgnoreErrorContext, Output.IgnoreErrorMessage, "{ bitwAnd(c(), c(1,2,3)) }");
         // Error message mismatch
         assertEval(Output.IgnoreErrorMessage, "{ bitwAnd(c(1,2,3,4), c(TRUE)) }");
     }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_det.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_det.java
index 57692a786023c32f98daf21e9277fc8da9689abf..03c916578780d4c15100169745c7226f424c5881 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_det.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_det.java
@@ -19,14 +19,12 @@ public class TestBuiltin_det extends TestBase {
 
     @Test
     public void testdet1() {
-        assertEval(Ignored.Unknown,
-                        "argv <- list(structure(c(FALSE, TRUE, TRUE, FALSE), .Dim = c(2L, 2L), .Dimnames = list(c('A', 'B'), c('A', 'B'))), TRUE); .Internal(det_ge_real(argv[[1]], argv[[2]]))");
+        assertEval("argv <- list(structure(c(FALSE, TRUE, TRUE, FALSE), .Dim = c(2L, 2L), .Dimnames = list(c('A', 'B'), c('A', 'B'))), TRUE); .Internal(det_ge_real(argv[[1]], argv[[2]]))");
     }
 
     @Test
     public void testdet2() {
-        assertEval(Ignored.Unknown,
-                        "argv <- list(structure(c(TRUE, TRUE, TRUE, TRUE), .Dim = c(2L, 2L), .Dimnames = list(c('A', 'B'), c('A', 'B'))), TRUE); .Internal(det_ge_real(argv[[1]], argv[[2]]))");
+        assertEval("argv <- list(structure(c(TRUE, TRUE, TRUE, TRUE), .Dim = c(2L, 2L), .Dimnames = list(c('A', 'B'), c('A', 'B'))), TRUE); .Internal(det_ge_real(argv[[1]], argv[[2]]))");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dimnamesassign.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dimnamesassign.java
index 988b62fe8e7a8d8c427e93ed02c0fdb2d1eb4064..f592d11f570e6158b74a8d0baa19023e79463866 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dimnamesassign.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dimnamesassign.java
@@ -74,8 +74,7 @@ public class TestBuiltin_dimnamesassign extends TestBase {
 
     @Test
     public void testdimnamesassign12() {
-        assertEval(Ignored.Unknown,
-                        "argv <- list(structure(list(fair = c(326L, 688L, 343L, 98L), red = c(38L, 116L, 84L, 48L), medium = c(241L, 584L, 909L, 403L), dark = c(110L, 188L, 412L, 681L), black = c(3L, 4L, 26L, 85L)), .Names = c('fair', 'red', 'medium', 'dark', 'black'), class = 'data.frame', row.names = c('blue', 'light', 'medium', 'dark')), value = list(c('blue', 'light', 'medium', 'dark'), c('F', 'R', 'M', 'D', 'B')));`dimnames<-`(argv[[1]],argv[[2]]);");
+        assertEval("argv <- list(structure(list(fair = c(326L, 688L, 343L, 98L), red = c(38L, 116L, 84L, 48L), medium = c(241L, 584L, 909L, 403L), dark = c(110L, 188L, 412L, 681L), black = c(3L, 4L, 26L, 85L)), .Names = c('fair', 'red', 'medium', 'dark', 'black'), class = 'data.frame', row.names = c('blue', 'light', 'medium', 'dark')), value = list(c('blue', 'light', 'medium', 'dark'), c('F', 'R', 'M', 'D', 'B')));`dimnames<-`(argv[[1]],argv[[2]]);");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_environmentassign.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_environmentassign.java
index db14b641246e7d02ecfab7360daf4b07a619059f..af8ec8a7f429a83153e298e6e3d2ab61a2259548 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_environmentassign.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_environmentassign.java
@@ -23,7 +23,14 @@ public class TestBuiltin_environmentassign extends TestBase {
         assertEval("{ e1 <- new.env(); e2 <- new.env(); environment(e1) <- e2 }");
         assertEval("{ e1 <- new.env(); environment(e1) <- 3 }");
 
+        assertEval("{ e1 <- 1; environment(e1) <- NULL }");
+        assertEval("{ e1 <- 1; e2 <- new.env(); environment(e1) <- e2 }");
+        assertEval("{ e1 <- 1; environment(e1) <- 3 }");
+
         assertEval("{ f <- function() {}; e1 <- new.env(); environment(f) <- e1 }");
+        assertEval("{ f <- function() {}; environment(f) <- NULL }");
         assertEval("{ f <- function() x; f2 <- f; e <- new.env(); assign('x', 2, envir=e); x <- 1; environment(f) <- e; c(f(), f2())}");
+
+        assertEval("{ f <- NULL; environment(f) <- new.env() }");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_eval.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_eval.java
index 25c20c74c52029b53faa5d54bf503906b1e7a69c..adeaff0eebe559866fae460c9be9a10a0586836e 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_eval.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_eval.java
@@ -41,6 +41,10 @@ public class TestBuiltin_eval extends TestBase {
         assertEval("{ g<-function(y) { f<-function(x) { x }; substitute(f(y)) } ; eval(g(42)) }");
         assertEval("{ eval({ xx <- pi; xx^2}) ; xx }");
 
+        assertEval("eval('foo')");
+        assertEval(Output.IgnoreErrorContext, "eval(as.symbol('foo'))");
+        assertEval("eval(as.symbol('baseenv'))");
+
         // should print two values, xx^2 and xx
         assertEval("eval({ xx <- pi; xx^2}) ; xx");
 
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_format.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_format.java
index dbf55bd954e4d691b0d2092543110d38a9aa7fe5..eaaffe5711ac037b4c58ad78ec2e3133da8e8299 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_format.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_format.java
@@ -242,8 +242,7 @@ public class TestBuiltin_format extends TestBase {
 
     @Test
     public void testformat46() {
-        assertEval(Ignored.Unknown,
-                        "argv <- list(1.2e+07, FALSE, NULL, 9L, NULL, 3L, TRUE, NA, \".\"); .Internal(format(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]], argv[[8]], argv[[9]]))");
+        assertEval("argv <- list(1.2e+07, FALSE, NULL, 9L, NULL, 3L, TRUE, NA, \".\"); .Internal(format(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]], argv[[8]], argv[[9]]))");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lengthassign.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lengthassign.java
index b5a8b8994137c0aad2a846c89aa732fe35f4219e..d8670d083b79fe18047b381ec55b35ebedcd8bd9 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lengthassign.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lengthassign.java
@@ -46,7 +46,7 @@ public class TestBuiltin_lengthassign extends TestBase {
     public void testlengthassign6() {
         assertEval("argv <- list(list(), value = 0L);`length<-`(argv[[1]],argv[[2]]);");
 
-        assertEval(Ignored.Unknown, "argv <- structure(list(1:3, value = TRUE), .Names = c('', 'value'));do.call('length<-', argv)");
+        assertEval(Output.IgnoreErrorContext, "argv <- structure(list(1:3, value = TRUE), .Names = c('', 'value'));do.call('length<-', argv)");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lockEnvironment.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lockEnvironment.java
new file mode 100644
index 0000000000000000000000000000000000000000..725d9b47df88cb9f3c774ae1ffa574e8ca2a0934
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_lockEnvironment.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+package com.oracle.truffle.r.test.builtins;
+
+import org.junit.Test;
+
+import com.oracle.truffle.r.test.TestBase;
+
+// Checkstyle: stop line length check
+public class TestBuiltin_lockEnvironment extends TestBase {
+
+    @Test
+    public void testlockEnvironment() {
+        assertEval("lockEnvironment('foo', TRUE)");
+        assertEval("e <- new.env(); e$a <- 'foo'; lockEnvironment(e, FALSE); e$b <- 123");
+        assertEval("e <- new.env(); e$a <- 'foo'; lockEnvironment(e, FALSE); e$a <- 123");
+        assertEval("e <- new.env(); e$a <- 'foo'; lockEnvironment(e, 'a'); e$b <- 123");
+        assertEval(Ignored.MissingBuiltin, "e <- new.env(); e$a <- 'foo'; lockEnvironment(e, 'a'); e$a <- 123");
+        assertEval("e <- new.env(); e$a <- 'foo'; lockEnvironment(e, logical()); e$b <- 123");
+        assertEval(Ignored.MissingBuiltin, "e <- new.env(); e$a <- 'foo'; lockEnvironment(e, logical()); e$a <- 123");
+    }
+}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_newenv.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_newenv.java
new file mode 100644
index 0000000000000000000000000000000000000000..10e41b465384b0aadc8c76a53d8e9b15b0dcee5a
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_newenv.java
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+package com.oracle.truffle.r.test.builtins;
+
+import org.junit.Test;
+
+import com.oracle.truffle.r.test.TestBase;
+
+// Checkstyle: stop line length check
+public class TestBuiltin_newenv extends TestBase {
+
+    @Test
+    public void testnewenv() {
+        assertEval(Output.ContainsReferences, "new.env()");
+        assertEval(Output.ContainsReferences, "new.env(1,,2)");
+        assertEval(Output.ContainsReferences, "new.env(logical(),new.env(),1000)");
+        assertEval(Output.ContainsReferences, "parent.env(new.env())");
+        assertEval(Output.ContainsReferences, "e <- new.env(); e; parent.env(new.env(TRUE, e))");
+    }
+}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_options.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_options.java
index 17e9d9199c5eaeb25de8149dae5bcf560137ae83..9e6696ec52b12a5a9bc0da34f275434966ca848b 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_options.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_options.java
@@ -45,7 +45,7 @@ public class TestBuiltin_options extends TestBase {
     @Test
     public void testOptions() {
         assertEval("{ getOption(NULL) }");
-        assertEval(Output.IgnoreErrorContext, Ignored.ImplementationError, "{ getOption(character()) }");
+        assertEval("{ getOption(character()) }");
         assertEval("{ options(\"timeout\", \"width\") }");
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_parentenv.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_parentenv.java
new file mode 100644
index 0000000000000000000000000000000000000000..285f0fa6c305a681287e97e9468249fd5a8427bb
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_parentenv.java
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+package com.oracle.truffle.r.test.builtins;
+
+import org.junit.Test;
+
+import com.oracle.truffle.r.test.TestBase;
+
+public class TestBuiltin_parentenv extends TestBase {
+
+    @Test
+    public void testParentEnv() {
+        assertEval("parent.env()");
+        assertEval("parent.env(NULL)");
+        assertEval("parent.env(1)");
+        assertEval("parent.env(c(1,2,3))");
+        assertEval("e <- new.env(); parent.env(e)");
+    }
+}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_parentenvassign.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_parentenvassign.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a4beabc42275506ec6e55528bfbaecd3b7f71fe
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_parentenvassign.java
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+package com.oracle.truffle.r.test.builtins;
+
+import org.junit.Test;
+
+import com.oracle.truffle.r.test.TestBase;
+
+public class TestBuiltin_parentenvassign extends TestBase {
+
+    @Test
+    public void testParentEnv() {
+        assertEval("parent.env() <- new.env()");
+        assertEval(Output.IgnoreErrorContext, "parent.env(NULL) <- new.env()");
+        assertEval(Output.IgnoreErrorContext, "parent.env(1) <- new.env()");
+        assertEval(Output.IgnoreErrorContext, "parent.env(c(1,2,3)) <- new.env()");
+        assertEval("parent.env(emptyenv()) <- new.env()");
+        assertEval(Output.IgnoreErrorContext, "e <- new.env(); parent.env(e) <- 44");
+        assertEval(Output.IgnoreErrorContext, Output.IgnoreErrorMessage, "e <- new.env(); parent.env(e) <- NULL");
+        assertEval("e <- new.env(); parent.env(e) <- emptyenv(); parent.env(e)");
+        assertEval(Output.IgnoreErrorContext, "e <- new.env(); parent.env(e) <- c(1,2,3)");
+        assertEval(Output.ContainsReferences, "e <- new.env(); e2 <- new.env(); parent.env(e) <- e2; parent.env(e)");
+    }
+}
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_qr.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_qr.java
index eb2f41390a276a78aff063abaf6e838aab057780..a4e57175ddfa4f8ff1d9b0ee8fb0332a803cec65 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_qr.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_qr.java
@@ -44,7 +44,7 @@ public class TestBuiltin_qr extends TestBase {
         assertEval(Ignored.Unknown, "{ round( qr(matrix(1:6,nrow=2), LAPACK=TRUE)$qr, digits=5) }");
 
         // qr.coef
-        assertEval(Ignored.Unknown, Output.IgnoreErrorContext, "{ x <- qr(cbind(1:10,2:11), LAPACK=TRUE) ; qr.coef(x, 1:2) }");
+        assertEval(Output.IgnoreErrorContext, "{ x <- qr(cbind(1:10,2:11), LAPACK=TRUE) ; qr.coef(x, 1:2) }");
         assertEval(Ignored.Unknown, " { x <- qr(cbind(1:10,2:11), LAPACK=TRUE) ; round( qr.coef(x, 1:10), digits=5 ) }");
         assertEval(Ignored.Unknown, "{ x <- qr(c(3,1,2), LAPACK=TRUE) ; round( qr.coef(x, c(1,3,2)), digits=5 ) }");
         // FIXME: GNU-R will print negative zero as zero
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rm.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rm.java
index 70ec6e7b32e6ab0c6c21f6de392faed39fe84f1f..15ac77f83a1e5334aa682d597a9de56d8068e55a 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rm.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rm.java
@@ -33,7 +33,7 @@ public class TestBuiltin_rm extends TestBase {
         assertEval("tmp <- 42; rm(tmp); tmp");
         assertEval("tmp <- 42; rm(list='tmp'); tmp");
         assertEval(" e <- new.env(); e$a <- 42; rm(list='a', envir=e); e$a");
-        assertEval(Ignored.Unimplemented, "tmp <- 42; f <- function() rm(list='tmp',inherits=T); f(); tmp");
+        assertEval(Output.IgnoreErrorContext, "tmp <- 42; f <- function() rm(list='tmp',inherits=T); f(); tmp");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/functions/TestFunctions.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/functions/TestFunctions.java
index 1d63aeeb26b2c5afc1b95efb1684b89c1e4ae331..bce570f903c34c7adf70c8a76b6332518dddbad4 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/functions/TestFunctions.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/functions/TestFunctions.java
@@ -148,7 +148,7 @@ public class TestFunctions extends TestBase {
         assertEval("{ f <- function(a,b,c,d) { a + b } ; f(1,x=1,2,3,4) }");
 
         assertEval(Ignored.Unknown, Output.IgnoreErrorContext, "{ x<-function(y, b){1} ; x(y=1, 2, 3, z = 5) }");
-        assertEval(Ignored.Unknown, Output.IgnoreErrorContext, "{ x<-function(a){1} ; x(1,) }");
+        assertEval("{ x<-function(a){1} ; x(1,) }");
 
         // note exactly GNU-R message
         assertEval(Ignored.Unknown, Output.IgnoreErrorContext, "{ f <- function(a,a) {1} }");
@@ -331,7 +331,7 @@ public class TestFunctions extends TestBase {
         assertEval(Ignored.Unknown, Output.IgnoreErrorContext, "{ lapply(1:3, \"dummy\") }");
 
         assertEval(Ignored.Unknown, Output.IgnoreErrorContext, "{ f <- function(a, barg, bextra, dummy) { a + barg } ; g <- function(...) { f(a=1, ..., x=2,z=3) } ; g(1) }");
-        assertEval(Ignored.Unknown, Output.IgnoreErrorContext, "{ f <- function(a, barg, bextra, dummy) { a + barg } ; g <- function(...) { f(a=1, ...,,,) } ; g(1) }");
+        assertEval("{ f <- function(a, barg, bextra, dummy) { a + barg } ; g <- function(...) { f(a=1, ...,,,) } ; g(1) }");
         assertEval(Ignored.Unknown, Output.IgnoreErrorContext, "{ f <- function(...) { ..2 + ..2 } ; f(1,,2) }");
         assertEval(Ignored.Unknown, Output.IgnoreErrorContext, "{ f <- function(...) { ..1 + ..2 } ; f(1,,3) }");
     }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleArithmetic.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleArithmetic.java
index 239cd80e0dc7ce48f3d45b4049ed7892638b3dbd..9aa145f1373cbadd6a7c110df8f1a2364744b525 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleArithmetic.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleArithmetic.java
@@ -307,7 +307,7 @@ public class TestSimpleArithmetic extends TestBase {
     public void testVectorsComplex() {
         assertEval("{ 1:4+c(1,2+2i) }");
         assertEval("{ c(1,2+2i)+1:4 }");
-        assertEval(Ignored.ImplementationError, "x <- c(NaN, 3+2i); xre <- Re(x); xim <- (0+1i) * Im(x); xre + xim");
+        assertEval("x <- c(NaN, 3+2i); xre <- Re(x); xim <- (0+1i) * Im(x); xre + xim");
     }
 
     @Test