diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsDouble.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsDouble.java
index 690be3687739064daaffa07a9931b00cedbf6257..8ff47c9a33d5c608a49508dc26d528ee4b514ab5 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsDouble.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsDouble.java
@@ -33,6 +33,7 @@ import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.RDispatch;
+import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
@@ -43,7 +44,7 @@ public abstract class AsDouble extends RBuiltinNode.Arg2 {
 
     static {
         Casts casts = new Casts(AsDouble.class);
-        casts.arg("x").returnIf(missingValue().or(nullValue()), emptyDoubleVector()).asDoubleVector();
+        casts.arg("x").defaultWarningContext(RError.NO_CALLER).returnIf(missingValue().or(nullValue()), emptyDoubleVector()).asDoubleVector();
     }
 
     @Specialization(guards = "reuseTemporaryNode.supports(v)", limit = "getVectorAccessCacheSize()")
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsLogical.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsLogical.java
index d83313df5838e4167e85b110ecdbc0c19f7c8e89..b157eb8f052b1e82a6540d1672a7e097dbd4ed55 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsLogical.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsLogical.java
@@ -33,6 +33,7 @@ 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.RBuiltinNode;
+import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
@@ -43,7 +44,7 @@ public abstract class AsLogical extends RBuiltinNode.Arg2 {
 
     static {
         Casts casts = new Casts(AsLogical.class);
-        casts.arg("x").returnIf(missingValue().or(nullValue()), emptyLogicalVector()).asLogicalVector();
+        casts.arg("x").defaultWarningContext(RError.NO_CALLER).returnIf(missingValue().or(nullValue()), emptyLogicalVector()).asLogicalVector();
     }
 
     @Specialization(guards = "reuseTemporaryNode.supports(v)", limit = "getVectorAccessCacheSize()")
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsRaw.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsRaw.java
index d71d282770bc1a4adeefdd769f6388b04b65fb7f..ba0d5efa556a6ae879b8f0b60229ac8d758ce20f 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsRaw.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsRaw.java
@@ -43,7 +43,7 @@ public abstract class AsRaw extends RBuiltinNode.Arg1 {
 
     static {
         Casts casts = new Casts(AsRaw.class);
-        casts.arg("x").mustBe(missingValue().not(), RError.Message.ARGUMENTS_PASSED, 0, "'as.raw'", 1).asRawVector();
+        casts.arg("x").defaultWarningContext(RError.NO_CALLER).mustBe(missingValue().not(), RError.Message.ARGUMENTS_PASSED, 0, "'as.raw'", 1).asRawVector();
     }
 
     @Specialization
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 7c8a2db5b90a8d2364f7d1a49de2aeabe79cedbc..9ba7314e4f22c0ffcf99d460e66d1d2cf25c1f89 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
@@ -237,18 +237,18 @@ public final class PipelineToCastNode {
                     return step.vectorCoercion ? CastIntegerNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, false, step.useClosure, warningContext)
                                     : CastIntegerBaseNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, false, step.useClosure, warningContext);
                 case Double:
-                    return step.vectorCoercion ? CastDoubleNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, false, step.useClosure)
-                                    : CastDoubleBaseNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, false, step.useClosure);
+                    return step.vectorCoercion ? CastDoubleNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, false, step.useClosure, warningContext)
+                                    : CastDoubleBaseNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, false, step.useClosure, warningContext);
                 case Character:
-                    return step.vectorCoercion ? CastStringNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, false, false, warningContext)
-                                    : CastStringBaseNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, false, false, warningContext);
+                    return step.vectorCoercion ? CastStringNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, false, step.useClosure, warningContext)
+                                    : CastStringBaseNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, false, step.useClosure, warningContext);
                 case Logical:
-                    return step.vectorCoercion ? CastLogicalNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes)
-                                    : CastLogicalBaseNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes);
+                    return step.vectorCoercion ? CastLogicalNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, false, step.useClosure, warningContext)
+                                    : CastLogicalBaseNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, false, step.useClosure, warningContext);
                 case Complex:
-                    return CastComplexNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, false, warningContext);
+                    return CastComplexNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, step.useClosure, warningContext);
                 case Raw:
-                    return CastRawNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes);
+                    return CastRawNodeGen.create(step.preserveNames, step.preserveDimensions, step.preserveAttributes, step.useClosure, step.useClosure, warningContext);
                 case Any:
                     return CastToVectorNodeGen.create(step.preserveNonVector);
                 default:
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleBaseNode.java
index 320147333f13418bb72f9e8a7f61994f4f57463c..dee35f5efb184f4ed4da4bdd1b1346d951cd58ff 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleBaseNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleBaseNode.java
@@ -25,6 +25,7 @@ package com.oracle.truffle.r.nodes.unary;
 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.runtime.RError.ErrorContext;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
@@ -32,13 +33,13 @@ import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RRaw;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 import com.oracle.truffle.r.runtime.ops.na.NAProfile;
 
 public abstract class CastDoubleBaseNode extends CastBaseNode {
 
     protected final NACheck naCheck = NACheck.create();
-    protected final NAProfile naProfile = NAProfile.create();
 
     protected CastDoubleBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
         super(preserveNames, preserveDimensions, preserveAttributes);
@@ -48,6 +49,10 @@ public abstract class CastDoubleBaseNode extends CastBaseNode {
         super(preserveNames, preserveDimensions, preserveAttributes, forRFFI, useClosure);
     }
 
+    protected CastDoubleBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI, boolean useClosure, ErrorContext warningContext) {
+        super(preserveNames, preserveDimensions, preserveAttributes, forRFFI, useClosure, warningContext);
+    }
+
     @Override
     protected final RType getTargetType() {
         return RType.Double;
@@ -82,14 +87,18 @@ public abstract class CastDoubleBaseNode extends CastBaseNode {
         return operand;
     }
 
-    @Specialization
-    protected double doDouble(RComplex operand) {
-        naCheck.enable(operand);
-        double result = naCheck.convertComplexToDouble(operand, false);
-        if (operand.getImaginaryPart() != 0.0) {
-            warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
+    @Specialization(guards = "uAccess.supports(operand)", limit = "getVectorAccessCacheSize()")
+    protected double doComplex(RComplex operand,
+                    @Cached("operand.access()") VectorAccess uAccess) {
+        try (VectorAccess.SequentialIterator sIter = uAccess.access(operand, warningContext())) {
+            uAccess.next(sIter);
+            return uAccess.getDouble(sIter);
         }
-        return result;
+    }
+
+    @Specialization(replaces = "doComplex")
+    protected double doComplexGeneric(RComplex operand) {
+        return doComplex(operand, operand.slowPathAccess());
     }
 
     @Specialization
@@ -100,13 +109,14 @@ public abstract class CastDoubleBaseNode extends CastBaseNode {
 
     @Specialization
     protected double doString(String operand,
-                    @Cached("createBinaryProfile()") ConditionProfile emptyStringProfile) {
+                    @Cached("createBinaryProfile()") ConditionProfile emptyStringProfile,
+                    @Cached("create()") NAProfile naProfile) {
         if (naProfile.isNA(operand) || emptyStringProfile.profile(operand.isEmpty())) {
             return RRuntime.DOUBLE_NA;
         }
         double result = RRuntime.string2doubleNoCheck(operand);
         if (RRuntime.isNA(result)) {
-            warning(RError.Message.NA_INTRODUCED_COERCION);
+            warning(warningContext() != null ? warningContext() : null, RError.Message.NA_INTRODUCED_COERCION);
         }
         return result;
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java
index 34461d559e36ddfa3d3a9f4165a3b74af38f8ed7..3f99a6672ab2a45750b78396d70fd7a3089c489c 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java
@@ -22,20 +22,17 @@
  */
 package com.oracle.truffle.r.nodes.unary;
 
-import java.util.function.IntToDoubleFunction;
-
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.ImportStatic;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.interop.TruffleObject;
-import com.oracle.truffle.api.profiles.BranchProfile;
-import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
+import com.oracle.truffle.r.runtime.DSLConfig;
 import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.ErrorContext;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
-import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RDoubleVector;
 import com.oracle.truffle.r.runtime.data.RForeignBooleanWrapper;
 import com.oracle.truffle.r.runtime.data.RForeignIntWrapper;
@@ -44,20 +41,24 @@ import com.oracle.truffle.r.runtime.data.RForeignWrapper;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RPairList;
 import com.oracle.truffle.r.runtime.data.closures.RClosures;
+import com.oracle.truffle.r.runtime.data.model.RAbstractAtomicVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
 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.RAbstractListVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess.SequentialIterator;
 import com.oracle.truffle.r.runtime.interop.ForeignArray2R;
+import com.oracle.truffle.r.runtime.ops.na.NAProfile;
 
-@ImportStatic(RRuntime.class)
+@ImportStatic({RRuntime.class, DSLConfig.class})
 public abstract class CastDoubleNode extends CastDoubleBaseNode {
 
+    protected CastDoubleNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI, boolean withReuse, ErrorContext warningContext) {
+        super(preserveNames, preserveDimensions, preserveAttributes, forRFFI, withReuse, warningContext);
+    }
+
     protected CastDoubleNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI, boolean withReuse) {
         super(preserveNames, preserveDimensions, preserveAttributes, forRFFI, withReuse);
     }
@@ -84,100 +85,36 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
         return ret;
     }
 
-    private RDoubleVector createResultVector(RAbstractVector operand, IntToDoubleFunction elementFunction) {
-        naCheck.enable(operand);
-        double[] ddata = new double[operand.getLength()];
-        boolean seenNA = false;
-        for (int i = 0; i < operand.getLength(); i++) {
-            double value = elementFunction.applyAsDouble(i);
-            ddata[i] = value;
-            seenNA = seenNA || naProfile.isNA(value);
-        }
-        return vectorCopy(operand, ddata, !seenNA);
-    }
-
-    @Specialization(guards = "!isForeignWrapper(x)")
-    protected RAbstractDoubleVector doIntVector(RAbstractIntVector x,
-                    @Cached("createClassProfile()") ValueProfile operandTypeProfile) {
-        RAbstractIntVector operand = operandTypeProfile.profile(x);
-        if (useClosure()) {
-            return (RAbstractDoubleVector) castWithReuse(RType.Double, operand, naProfile.getConditionProfile());
+    private RDoubleVector createResultVector(RAbstractAtomicVector operand, VectorAccess uAccess) {
+        double[] idata = new double[operand.getLength()];
+        try (VectorAccess.SequentialIterator sIter = uAccess.access(operand, warningContext())) {
+            while (uAccess.next(sIter)) {
+                idata[sIter.getIndex()] = uAccess.getDouble(sIter);
+            }
         }
-        return createResultVector(operand, index -> naCheck.convertIntToDouble(operand.getDataAt(index)));
+        return vectorCopy(operand, idata, uAccess.na.neverSeenNAOrNaN());
     }
 
-    @Specialization(guards = "!isForeignWrapper(x)")
-    protected RAbstractDoubleVector doLogicalVector(RAbstractLogicalVector x,
-                    @Cached("createClassProfile()") ValueProfile operandTypeProfile) {
-        RAbstractLogicalVector operand = operandTypeProfile.profile(x);
-        if (useClosure()) {
-            return (RAbstractDoubleVector) castWithReuse(RType.Double, operand, naProfile.getConditionProfile());
-        }
-        return createResultVector(operand, index -> naCheck.convertLogicalToDouble(operand.getDataAt(index)));
+    @Specialization(guards = {"uAccess.supports(x)", "noClosure(x)"}, limit = "getGenericVectorAccessCacheSize()")
+    protected RAbstractDoubleVector doAbstractVector(RAbstractAtomicVector x,
+                    @Cached("createClassProfile()") ValueProfile operandTypeProfile,
+                    @Cached("x.access()") VectorAccess uAccess) {
+        RAbstractAtomicVector operand = operandTypeProfile.profile(x);
+        return createResultVector(operand, uAccess);
     }
 
-    @Specialization
-    protected RAbstractDoubleVector doRawVector(RAbstractRawVector x,
+    @Specialization(replaces = "doAbstractVector", guards = "noClosure(x)")
+    protected RAbstractDoubleVector doAbstractVectorGeneric(RAbstractAtomicVector x,
                     @Cached("createClassProfile()") ValueProfile operandTypeProfile) {
-        RAbstractRawVector operand = operandTypeProfile.profile(x);
-        if (useClosure()) {
-            return (RAbstractDoubleVector) castWithReuse(RType.Double, operand, naProfile.getConditionProfile());
-        }
-        return createResultVector(operand, index -> RRuntime.raw2double(operand.getRawDataAt(index)));
-    }
-
-    @Specialization(guards = "!isForeignWrapper(operand)")
-    protected RDoubleVector doStringVector(RAbstractStringVector operand,
-                    @Cached("createBinaryProfile()") ConditionProfile emptyStringProfile,
-                    @Cached("create()") BranchProfile warningBranch) {
-        naCheck.enable(operand);
-        double[] ddata = new double[operand.getLength()];
-        boolean seenNA = false;
-        boolean warning = false;
-        for (int i = 0; i < operand.getLength(); i++) {
-            String value = operand.getDataAt(i);
-            double doubleValue;
-            if (naCheck.check(value) || emptyStringProfile.profile(value.isEmpty())) {
-                doubleValue = RRuntime.DOUBLE_NA;
-                seenNA = true;
-            } else {
-                doubleValue = RRuntime.string2doubleNoCheck(value);
-                if (naProfile.isNA(doubleValue)) {
-                    seenNA = true;
-                    if (!value.isEmpty()) {
-                        warningBranch.enter();
-                        warning = true;
-                    }
-                }
-            }
-            ddata[i] = doubleValue;
-        }
-        if (warning) {
-            warning(RError.Message.NA_INTRODUCED_COERCION);
-        }
-        RDoubleVector ret = factory().createDoubleVector(ddata, !seenNA, getPreservedDimensions(operand), getPreservedNames(operand), getPreservedDimNames(operand));
-        if (preserveRegAttributes()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
+        return doAbstractVector(x, operandTypeProfile, x.slowPathAccess());
     }
 
-    @Specialization
-    protected RDoubleVector doComplexVector(RAbstractComplexVector operand) {
-        naCheck.enable(operand);
-        double[] ddata = new double[operand.getLength()];
-        boolean warning = false;
-        for (int i = 0; i < operand.getLength(); i++) {
-            RComplex value = operand.getDataAt(i);
-            ddata[i] = naCheck.convertComplexToDouble(value, false);
-            if (value.getImaginaryPart() != 0.0) {
-                warning = true;
-            }
-        }
-        if (warning) {
-            warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
-        }
-        return vectorCopy(operand, ddata, naCheck.neverSeenNA());
+    @Specialization(guards = {"useClosure(x)"})
+    public RAbstractDoubleVector doAbstractVectorClosure(RAbstractAtomicVector x,
+                    @Cached("createClassProfile()") ValueProfile operandTypeProfile,
+                    @Cached("create()") NAProfile naProfile) {
+        RAbstractAtomicVector operand = operandTypeProfile.profile(x);
+        return (RAbstractDoubleVector) castWithReuse(RType.Double, operand, naProfile.getConditionProfile());
     }
 
     @Specialization
@@ -185,36 +122,40 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
         return operand;
     }
 
-    @Specialization
-    protected RDoubleVector doList(RAbstractListVector list) {
+    @Specialization(guards = "uAccess.supports(list)", limit = "getVectorAccessCacheSize()")
+    protected RDoubleVector doList(RAbstractListVector list,
+                    @Cached("list.access()") VectorAccess uAccess) {
         int length = list.getLength();
         double[] result = new double[length];
         boolean seenNA = false;
-        for (int i = 0; i < length; i++) {
-            Object entry = list.getDataAt(i);
-            if (entry instanceof RList) {
-                result[i] = RRuntime.DOUBLE_NA;
-                seenNA = true;
-            } else {
-                Object castEntry = castDoubleRecursive(entry);
-                if (castEntry instanceof Double) {
-                    double value = (Double) castEntry;
-                    result[i] = value;
-                    seenNA = seenNA || RRuntime.isNA(value);
-                } else if (castEntry instanceof RDoubleVector) {
-                    RDoubleVector doubleVector = (RDoubleVector) castEntry;
-                    if (doubleVector.getLength() == 1) {
-                        double value = doubleVector.getDataAt(0);
+        try (SequentialIterator sIter = uAccess.access(list, warningContext())) {
+            while (uAccess.next(sIter)) {
+                int i = sIter.getIndex();
+                Object entry = uAccess.getListElement(sIter);
+                if (entry instanceof RList) {
+                    result[i] = RRuntime.DOUBLE_NA;
+                    seenNA = true;
+                } else {
+                    Object castEntry = castDoubleRecursive(entry);
+                    if (castEntry instanceof Double) {
+                        double value = (Double) castEntry;
                         result[i] = value;
                         seenNA = seenNA || RRuntime.isNA(value);
-                    } else if (doubleVector.getLength() == 0) {
-                        result[i] = RRuntime.DOUBLE_NA;
-                        seenNA = true;
+                    } else if (castEntry instanceof RDoubleVector) {
+                        RDoubleVector doubleVector = (RDoubleVector) castEntry;
+                        if (doubleVector.getLength() == 1) {
+                            double value = doubleVector.getDataAt(0);
+                            result[i] = value;
+                            seenNA = seenNA || RRuntime.isNA(value);
+                        } else if (doubleVector.getLength() == 0) {
+                            result[i] = RRuntime.DOUBLE_NA;
+                            seenNA = true;
+                        } else {
+                            throw throwCannotCoerceListError("numeric");
+                        }
                     } else {
                         throw throwCannotCoerceListError("numeric");
                     }
-                } else {
-                    throw throwCannotCoerceListError("numeric");
                 }
             }
         }
@@ -225,9 +166,14 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
         return ret;
     }
 
+    @Specialization(replaces = "doList")
+    protected RDoubleVector doListGeneric(RAbstractListVector list) {
+        return doList(list, list.slowPathAccess());
+    }
+
     @Specialization(guards = "!pairList.isLanguage()")
     protected RDoubleVector doPairList(RPairList pairList) {
-        return doList(pairList.toRList());
+        return (RDoubleVector) castDoubleRecursive(pairList.toRList());
     }
 
     @Specialization(guards = "isForeignObject(obj)")
@@ -280,4 +226,12 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
     public static CastDoubleNode createNonPreserving() {
         return CastDoubleNodeGen.create(false, false, false, false, false);
     }
+
+    protected boolean useClosure(RAbstractAtomicVector x) {
+        return useClosure() && !isForeignWrapper(x) && !(x instanceof RAbstractDoubleVector) && !(x instanceof RAbstractStringVector || x instanceof RAbstractComplexVector);
+    }
+
+    protected boolean noClosure(RAbstractAtomicVector x) {
+        return !isForeignWrapper(x) && !(x instanceof RAbstractDoubleVector) && (!useClosure() || x instanceof RAbstractStringVector || x instanceof RAbstractComplexVector);
+    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java
index 486d8071a80c14efe50fcc4602b443bf1772670c..ff751fb600ae71324c743746d006d8df14f9df59 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java
@@ -241,10 +241,10 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode {
     }
 
     protected boolean useClosure(RAbstractAtomicVector x) {
-        return !isForeignWrapper(x) && useClosure() && !(x instanceof RAbstractStringVector || x instanceof RAbstractComplexVector);
+        return useClosure() && !isForeignWrapper(x) && !(x instanceof RAbstractIntVector) && !(x instanceof RAbstractStringVector || x instanceof RAbstractComplexVector);
     }
 
     protected boolean noClosure(RAbstractAtomicVector x) {
-        return !isForeignWrapper(x) && (!useClosure() || x instanceof RAbstractStringVector || x instanceof RAbstractComplexVector);
+        return !isForeignWrapper(x) && !(x instanceof RAbstractIntVector) && (!useClosure() || x instanceof RAbstractStringVector || x instanceof RAbstractComplexVector);
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
index fa62efa2653e2edaab589f24187064a289f13bf0..c7dbb24162100635383ee9453be6925d1028111a 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
@@ -27,6 +27,7 @@ import com.oracle.truffle.api.dsl.ImportStatic;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.interop.TruffleObject;
 import com.oracle.truffle.api.profiles.ValueProfile;
+import com.oracle.truffle.r.runtime.DSLConfig;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.data.RExternalPtr;
@@ -38,10 +39,12 @@ import com.oracle.truffle.r.runtime.data.RPairList;
 import com.oracle.truffle.r.runtime.data.RS4Object;
 import com.oracle.truffle.r.runtime.data.RSymbol;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess.SequentialIterator;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.interop.ForeignArray2R;
 
-@ImportStatic(RRuntime.class)
+@ImportStatic({RRuntime.class, DSLConfig.class})
 public abstract class CastListNode extends CastBaseNode {
 
     public abstract RList executeList(Object o);
@@ -74,13 +77,17 @@ public abstract class CastListNode extends CastBaseNode {
         return factory().createList(new Object[]{operand});
     }
 
-    @Specialization
+    @Specialization(guards = "uAccess.supports(operand)", limit = "getVectorAccessCacheSize()")
     protected RList doAbstractVector(RAbstractVector operand,
+                    @Cached("operand.access()") VectorAccess uAccess,
                     @Cached("createClassProfile()") ValueProfile vectorClassProfile) {
         RAbstractVector profiledOperand = vectorClassProfile.profile(operand);
         Object[] data = new Object[profiledOperand.getLength()];
-        for (int i = 0; i < data.length; i++) {
-            data[i] = profiledOperand.getDataAtAsObject(i);
+
+        try (SequentialIterator sIter = uAccess.access(profiledOperand, warningContext())) {
+            while (uAccess.next(sIter)) {
+                data[sIter.getIndex()] = uAccess.getListElement(sIter);
+            }
         }
         RList ret = factory().createList(data, getPreservedDimensions(operand), getPreservedNames(operand), getPreservedDimNames(operand));
         if (preserveRegAttributes()) {
@@ -89,6 +96,12 @@ public abstract class CastListNode extends CastBaseNode {
         return ret;
     }
 
+    @Specialization(replaces = "doAbstractVector")
+    protected RList doAbstractVectorGeneric(RAbstractVector operand,
+                    @Cached("createClassProfile()") ValueProfile vectorClassProfile) {
+        return doAbstractVector(operand, operand.slowPathAccess(), vectorClassProfile);
+    }
+
     @Specialization
     protected RList doPairList(RPairList pl) {
         return pl.toRList();
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalBaseNode.java
index 5ec1dfc078dd6687e3c8ec00487924311547b3e3..d3a723f2e94dd7fa6daf32332a9165ac0f8015fc 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalBaseNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalBaseNode.java
@@ -23,6 +23,7 @@
 package com.oracle.truffle.r.nodes.unary;
 
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.runtime.RError.ErrorContext;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.data.RComplex;
@@ -33,6 +34,10 @@ public abstract class CastLogicalBaseNode extends CastBaseNode {
 
     protected final NACheck naCheck = NACheck.create();
 
+    protected CastLogicalBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI, boolean useClosure, ErrorContext warningContext) {
+        super(preserveNames, preserveDimensions, preserveAttributes, forRFFI, useClosure, warningContext);
+    }
+
     protected CastLogicalBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) {
         super(preserveNames, preserveDimensions, preserveAttributes, forRFFI);
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java
index 0397b7f612bba118adff4de92c2d03f58c1fd3ef..ed21db3395f5bedf7589f9524cc1da94a81c842a 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java
@@ -30,7 +30,9 @@ import com.oracle.truffle.api.dsl.ImportStatic;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.interop.TruffleObject;
 import com.oracle.truffle.r.nodes.helpers.InheritsCheckNode;
+import com.oracle.truffle.r.runtime.DSLConfig;
 import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.ErrorContext;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RList;
@@ -38,22 +40,18 @@ import com.oracle.truffle.r.runtime.data.RLogicalVector;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RPairList;
-import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractAtomicVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess.SequentialIterator;
 import com.oracle.truffle.r.runtime.interop.ForeignArray2R;
-import com.oracle.truffle.r.runtime.ops.na.NAProfile;
 
-@ImportStatic(RRuntime.class)
+@ImportStatic({RRuntime.class, DSLConfig.class})
 public abstract class CastLogicalNode extends CastLogicalBaseNode {
 
-    private final NAProfile naProfile = NAProfile.create();
-
     @Child private CastLogicalNode recursiveCastLogical;
     @Child private InheritsCheckNode inheritsFactorCheck;
 
@@ -65,6 +63,10 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode {
         super(preserveNames, preserveDimensions, preserveAttributes, forRFFI);
     }
 
+    protected CastLogicalNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI, boolean useClosure, ErrorContext warningContext) {
+        super(preserveNames, preserveDimensions, preserveAttributes, forRFFI, useClosure, warningContext);
+    }
+
     protected Object castLogicalRecursive(Object o) {
         if (recursiveCastLogical == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -73,24 +75,11 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode {
         return recursiveCastLogical.execute(o);
     }
 
-    protected boolean isFactor(Object o) {
-        if (inheritsFactorCheck == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            inheritsFactorCheck = insert(new InheritsCheckNode(RRuntime.CLASS_FACTOR));
-        }
-        return inheritsFactorCheck.execute(o);
-    }
-
     @Specialization
     protected RNull doNull(@SuppressWarnings("unused") RNull operand) {
         return RNull.instance;
     }
 
-    @FunctionalInterface
-    private interface IntToByteFunction {
-        byte apply(int value);
-    }
-
     private RLogicalVector vectorCopy(RAbstractVector operand, byte[] bdata, boolean isComplete) {
         RLogicalVector ret = factory().createLogicalVector(bdata, isComplete, getPreservedDimensions(operand), getPreservedNames(operand), getPreservedDimNames(operand));
         if (preserveRegAttributes()) {
@@ -99,16 +88,14 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode {
         return ret;
     }
 
-    private RLogicalVector createResultVector(RAbstractVector operand, IntToByteFunction elementFunction) {
-        naCheck.enable(operand);
+    private RLogicalVector createResultVector(RAbstractVector operand, VectorAccess uAccess) {
         byte[] bdata = new byte[operand.getLength()];
-        boolean seenNA = false;
-        for (int i = 0; i < operand.getLength(); i++) {
-            byte value = elementFunction.apply(i);
-            bdata[i] = value;
-            seenNA = seenNA || naProfile.isNA(value);
+        try (SequentialIterator sIter = uAccess.access(operand, warningContext())) {
+            while (uAccess.next(sIter)) {
+                bdata[sIter.getIndex()] = uAccess.getLogical(sIter);
+            }
         }
-        return vectorCopy(operand, bdata, !seenNA);
+        return vectorCopy(operand, bdata, uAccess.na.neverSeenNAOrNaN());
     }
 
     @Specialization
@@ -116,9 +103,15 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode {
         return operand;
     }
 
-    @Specialization(guards = "!isFactor(operand)")
-    protected RLogicalVector doIntVector(RAbstractIntVector operand) {
-        return createResultVector(operand, index -> naCheck.convertIntToLogical(operand.getDataAt(index)));
+    @Specialization(guards = {"uAccess.supports(operand)", "useVectorAccess(operand)"}, limit = "getGenericVectorAccessCacheSize()")
+    protected RLogicalVector doAbstractVector(RAbstractAtomicVector operand,
+                    @Cached("operand.access()") VectorAccess uAccess) {
+        return createResultVector(operand, uAccess);
+    }
+
+    @Specialization(replaces = "doAbstractVector", guards = {"useVectorAccess(operand)"})
+    protected RLogicalVector doAbstractVectorGeneric(RAbstractAtomicVector operand) {
+        return createResultVector(operand, operand.slowPathAccess());
     }
 
     @Specialization(guards = "isFactor(factor)")
@@ -128,56 +121,40 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode {
         return factory().createLogicalVector(data, RDataFactory.INCOMPLETE_VECTOR);
     }
 
-    @Specialization
-    protected RLogicalVector doDoubleVector(RAbstractDoubleVector operand) {
-        return createResultVector(operand, index -> naCheck.convertDoubleToLogical(operand.getDataAt(index)));
-    }
-
-    @Specialization
-    protected RLogicalVector doStringVector(RAbstractStringVector operand) {
-        return createResultVector(operand, index -> naCheck.convertStringToLogical(operand.getDataAt(index)));
-    }
-
-    @Specialization
-    protected RLogicalVector doComplexVector(RAbstractComplexVector operand) {
-        return createResultVector(operand, index -> naCheck.convertComplexToLogical(operand.getDataAt(index)));
-    }
-
-    @Specialization
-    protected RLogicalVector doRawVectorDims(RAbstractRawVector operand) {
-        return createResultVector(operand, index -> RRuntime.raw2logical(operand.getRawDataAt(index)));
-    }
-
-    @Specialization
-    protected RLogicalVector doList(RAbstractListVector list) {
+    @Specialization(guards = "uAccess.supports(list)", limit = "getVectorAccessCacheSize()")
+    protected RLogicalVector doList(RAbstractListVector list,
+                    @Cached("list.access()") VectorAccess uAccess) {
         int length = list.getLength();
         byte[] result = new byte[length];
         boolean seenNA = false;
-        for (int i = 0; i < length; i++) {
-            Object entry = list.getDataAt(i);
-            if (entry instanceof RList) {
-                result[i] = RRuntime.LOGICAL_NA;
-                seenNA = true;
-            } else {
-                Object castEntry = castLogicalRecursive(entry);
-                if (castEntry instanceof Byte) {
-                    byte value = (Byte) castEntry;
-                    result[i] = value;
-                    seenNA = seenNA || RRuntime.isNA(value);
-                } else if (castEntry instanceof RLogicalVector) {
-                    RLogicalVector logicalVector = (RLogicalVector) castEntry;
-                    if (logicalVector.getLength() == 1) {
-                        byte value = logicalVector.getDataAt(0);
+        try (SequentialIterator sIter = uAccess.access(list, warningContext())) {
+            while (uAccess.next(sIter)) {
+                int i = sIter.getIndex();
+                Object entry = uAccess.getListElement(sIter);
+                if (entry instanceof RList) {
+                    result[i] = RRuntime.LOGICAL_NA;
+                    seenNA = true;
+                } else {
+                    Object castEntry = castLogicalRecursive(entry);
+                    if (castEntry instanceof Byte) {
+                        byte value = (Byte) castEntry;
                         result[i] = value;
                         seenNA = seenNA || RRuntime.isNA(value);
-                    } else if (logicalVector.getLength() == 0) {
-                        result[i] = RRuntime.LOGICAL_NA;
-                        seenNA = true;
+                    } else if (castEntry instanceof RLogicalVector) {
+                        RLogicalVector logicalVector = (RLogicalVector) castEntry;
+                        if (logicalVector.getLength() == 1) {
+                            byte value = logicalVector.getDataAt(0);
+                            result[i] = value;
+                            seenNA = seenNA || RRuntime.isNA(value);
+                        } else if (logicalVector.getLength() == 0) {
+                            result[i] = RRuntime.LOGICAL_NA;
+                            seenNA = true;
+                        } else {
+                            throw throwCannotCoerceListError("logical");
+                        }
                     } else {
                         throw throwCannotCoerceListError("logical");
                     }
-                } else {
-                    throw throwCannotCoerceListError("logical");
                 }
             }
         }
@@ -188,9 +165,14 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode {
         return ret;
     }
 
+    @Specialization(replaces = "doList")
+    protected RLogicalVector doListGeneric(RAbstractListVector list) {
+        return doList(list, list.slowPathAccess());
+    }
+
     @Specialization(guards = "!pairList.isLanguage()")
     protected RLogicalVector doPairList(RPairList pairList) {
-        return doList(pairList.toRList());
+        return (RLogicalVector) castLogicalRecursive(pairList.toRList());
     }
 
     @Specialization
@@ -225,4 +207,19 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode {
     public static CastLogicalNode createNonPreserving() {
         return CastLogicalNodeGen.create(false, false, false);
     }
+
+    protected boolean isFactor(RAbstractIntVector o) {
+        if (inheritsFactorCheck == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            inheritsFactorCheck = insert(new InheritsCheckNode(RRuntime.CLASS_FACTOR));
+        }
+        return inheritsFactorCheck.execute(o);
+    }
+
+    protected boolean useVectorAccess(RAbstractAtomicVector x) {
+        if (x instanceof RAbstractIntVector && isFactor((RAbstractIntVector) x)) {
+            return false;
+        }
+        return !(x instanceof RAbstractLogicalVector);
+    }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java
index 2b8fca447aece3df6390f9748e4c7980091f4b19..33e255794271a51a6d6a033563952a4b8a9ee321 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java
@@ -24,34 +24,32 @@ package com.oracle.truffle.r.nodes.unary;
 
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Cached;
+import com.oracle.truffle.api.dsl.ImportStatic;
 import com.oracle.truffle.api.dsl.Specialization;
-import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.r.runtime.DSLConfig;
 import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.ErrorContext;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.data.RComplex;
+import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RPairList;
 import com.oracle.truffle.r.runtime.data.RRaw;
 import com.oracle.truffle.r.runtime.data.RRawVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
-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.RAbstractAtomicVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
-import com.oracle.truffle.r.runtime.ops.na.NACheck;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess;
+import com.oracle.truffle.r.runtime.data.nodes.VectorAccess.SequentialIterator;
 import com.oracle.truffle.r.runtime.ops.na.NAProfile;
 
+@ImportStatic({DSLConfig.class})
 public abstract class CastRawNode extends CastBaseNode {
 
-    private final NACheck naCheck = NACheck.create();
-    private final BranchProfile warningBranch = BranchProfile.create();
-
     protected CastRawNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
         this(preserveNames, preserveDimensions, preserveAttributes, false);
     }
@@ -60,6 +58,10 @@ public abstract class CastRawNode extends CastBaseNode {
         super(preserveNames, preserveDimensions, preserveAttributes, forRFFI);
     }
 
+    protected CastRawNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI, boolean useClosures, ErrorContext warningContext) {
+        super(preserveNames, preserveDimensions, preserveAttributes, forRFFI, useClosures, warningContext);
+    }
+
     @Child private CastRawNode recursiveCastRaw;
 
     @Override
@@ -95,7 +97,7 @@ public abstract class CastRawNode extends CastBaseNode {
 
     private RRaw checkOutOfRange(int operand, int intResult) {
         if (intResult != operand) {
-            warning(RError.Message.OUT_OF_RANGE);
+            warning(warningContext(), RError.Message.OUT_OF_RANGE);
             return factory().createRaw((byte) 0);
         }
         return factory().createRaw((byte) intResult);
@@ -108,16 +110,41 @@ public abstract class CastRawNode extends CastBaseNode {
     }
 
     @Specialization
-    protected RRaw doDouble(double operand) {
-        int intResult = RRuntime.double2rawIntValue(operand);
+    protected RRaw doDouble(double operand,
+                    @Cached("create()") NAProfile naProfile) {
+        int intResult;
+        if (naProfile.isNA(operand)) {
+            warning(warningContext(), RError.Message.OUT_OF_RANGE);
+            intResult = 0;
+        } else {
+            if (operand > Integer.MAX_VALUE || operand <= Integer.MIN_VALUE) {
+                intResult = 0;
+                warning(warningContext(), RError.Message.NA_INTRODUCED_COERCION_INT);
+            } else {
+                intResult = RRuntime.double2rawIntValue(operand);
+            }
+        }
         return checkOutOfRange((int) operand, intResult);
     }
 
     @Specialization
-    protected RRaw doComplex(RComplex operand) {
-        int intResult = RRuntime.complex2rawIntValue(operand);
-        if (operand.getImaginaryPart() != 0) {
-            warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
+    protected RRaw doComplex(RComplex operand,
+                    @Cached("create()") NAProfile naProfile) {
+        int intResult;
+        if (naProfile.isNA(operand)) {
+            warning(warningContext(), RError.Message.OUT_OF_RANGE);
+            intResult = 0;
+        } else {
+            double realPart = operand.getRealPart();
+            if (realPart > Integer.MAX_VALUE || realPart <= Integer.MIN_VALUE) {
+                intResult = 0;
+                warning(warningContext(), RError.Message.NA_INTRODUCED_COERCION_INT);
+            } else {
+                intResult = RRuntime.complex2rawIntValue(operand);
+                if (operand.getImaginaryPart() != 0) {
+                    warning(warningContext(), RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
+                }
+            }
         }
         return checkOutOfRange((int) operand.getRealPart(), intResult);
     }
@@ -144,12 +171,17 @@ public abstract class CastRawNode extends CastBaseNode {
         } else {
             intValue = RRuntime.string2intNoCheck(operand);
             if (RRuntime.isNA(intValue)) {
-                warning(RError.Message.NA_INTRODUCED_COERCION);
+                try {
+                    Double.parseDouble(operand);
+                    warning(warningContext(), RError.Message.NA_INTRODUCED_COERCION_INT);
+                } catch (NumberFormatException e) {
+                    warning(warningContext(), RError.Message.NA_INTRODUCED_COERCION);
+                }
             }
         }
         int intRawValue = RRuntime.int2rawIntValue(intValue);
         if (intRawValue != intValue) {
-            warning(RError.Message.OUT_OF_RANGE);
+            warning(warningContext(), RError.Message.OUT_OF_RANGE);
             return RRaw.valueOf((byte) 0);
         }
         return RRaw.valueOf((byte) intRawValue);
@@ -163,134 +195,25 @@ public abstract class CastRawNode extends CastBaseNode {
         return ret;
     }
 
-    @Specialization
-    protected RRawVector doIntVector(RAbstractIntVector operand) {
-        int length = operand.getLength();
-        byte[] bdata = new byte[length];
-        boolean warning = false;
-        for (int i = 0; i < length; i++) {
-            int intValue = operand.getDataAt(i);
-            int intRawValue = RRuntime.int2rawIntValue(intValue);
-            if (intRawValue != intValue) {
-                warningBranch.enter();
-                warning = true;
-                intRawValue = 0;
-            }
-            bdata[i] = (byte) intRawValue;
-        }
-        if (warning) {
-            warning(RError.Message.OUT_OF_RANGE);
-        }
-        return vectorCopy(operand, bdata);
-    }
-
-    @Specialization
-    protected RRawVector doLogicalVector(RAbstractLogicalVector operand) {
-        byte[] bdata = new byte[operand.getLength()];
-        boolean warning = false;
-        for (int i = 0; i < operand.getLength(); i++) {
-            int intVal = RRuntime.logical2int(operand.getDataAt(i));
-            int intRawValue = RRuntime.int2rawIntValue(intVal);
-            if (intVal != intRawValue) {
-                warningBranch.enter();
-                warning = true;
-                intRawValue = 0;
-            }
-            bdata[i] = (byte) intRawValue;
-        }
-        if (warning) {
-            warning(RError.Message.OUT_OF_RANGE);
-        }
-        return vectorCopy(operand, bdata);
-    }
-
-    @Specialization
-    protected RRawVector doStringVector(RAbstractStringVector operand,
-                    @Cached("createBinaryProfile()") ConditionProfile emptyStringProfile,
-                    @Cached("create()") NAProfile naProfile) {
-        naCheck.enable(operand);
+    private RRawVector createResultVector(RAbstractVector operand, VectorAccess uAccess) {
         byte[] bdata = new byte[operand.getLength()];
-
-        boolean naCoercionWarning = false;
-        boolean outOfRangeWarning = false;
-        for (int i = 0; i < operand.getLength(); i++) {
-            String value = operand.getDataAt(i);
-            int intValue;
-            if (naCheck.check(value) || emptyStringProfile.profile(value.isEmpty())) {
-                intValue = RRuntime.INT_NA;
-            } else {
-                intValue = RRuntime.string2intNoCheck(value);
-                if (naProfile.isNA(intValue)) {
-                    if (!value.isEmpty()) {
-                        warningBranch.enter();
-                        naCoercionWarning = true;
-                    }
-                }
-                int intRawValue = RRuntime.int2rawIntValue(intValue);
-                if (intValue != intRawValue) {
-                    warningBranch.enter();
-                    outOfRangeWarning = true;
-                    intValue = 0;
-                }
+        try (SequentialIterator sIter = uAccess.access(operand, warningContext())) {
+            while (uAccess.next(sIter)) {
+                bdata[sIter.getIndex()] = uAccess.getRaw(sIter);
             }
-            bdata[i] = (byte) intValue;
-        }
-        if (naCoercionWarning) {
-            warning(RError.Message.NA_INTRODUCED_COERCION);
-        }
-        if (outOfRangeWarning) {
-            warning(RError.Message.OUT_OF_RANGE);
         }
         return vectorCopy(operand, bdata);
     }
 
-    @Specialization
-    protected RRawVector doComplexVector(RAbstractComplexVector operand) {
-        byte[] bdata = new byte[operand.getLength()];
-        boolean imaginaryDiscardedWarning = false;
-        boolean outOfRangeWarning = false;
-        for (int i = 0; i < operand.getLength(); i++) {
-            RComplex complexVal = operand.getDataAt(i);
-            int intRawValue = RRuntime.complex2rawIntValue(complexVal);
-            if (complexVal.getImaginaryPart() != 0.0) {
-                warningBranch.enter();
-                imaginaryDiscardedWarning = true;
-            }
-            if ((int) complexVal.getRealPart() != intRawValue) {
-                warningBranch.enter();
-                outOfRangeWarning = true;
-                intRawValue = 0;
-            }
-            bdata[i] = (byte) intRawValue;
-        }
-        if (imaginaryDiscardedWarning) {
-            warning(RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
-        }
-        if (outOfRangeWarning) {
-            warning(RError.Message.OUT_OF_RANGE);
-        }
-        return vectorCopy(operand, bdata);
+    @Specialization(guards = {"uAccess.supports(operand)", "!isRawVector(operand)"}, limit = "getGenericVectorAccessCacheSize()")
+    protected RRawVector doAbstractVector(RAbstractAtomicVector operand,
+                    @Cached("operand.access()") VectorAccess uAccess) {
+        return createResultVector(operand, uAccess);
     }
 
-    @Specialization
-    protected RRawVector doDoubleVector(RAbstractDoubleVector operand) {
-        int length = operand.getLength();
-        byte[] bdata = new byte[length];
-        boolean warning = false;
-        for (int i = 0; i < length; i++) {
-            double doubleValue = operand.getDataAt(i);
-            int intRawValue = RRuntime.double2rawIntValue(doubleValue);
-            if (intRawValue != (int) doubleValue) {
-                warningBranch.enter();
-                warning = true;
-                intRawValue = 0;
-            }
-            bdata[i] = (byte) intRawValue;
-        }
-        if (warning) {
-            warning(RError.Message.OUT_OF_RANGE);
-        }
-        return vectorCopy(operand, bdata);
+    @Specialization(replaces = "doAbstractVector", guards = {"!isRawVector(operand)"})
+    protected RRawVector doAbstractVectorGeneric(RAbstractAtomicVector operand) {
+        return createResultVector(operand, operand.slowPathAccess());
     }
 
     @Specialization
@@ -298,23 +221,50 @@ public abstract class CastRawNode extends CastBaseNode {
         return operand;
     }
 
-    @Specialization
-    protected RRawVector doList(RAbstractListVector value) {
-        int length = value.getLength();
-        byte[] data = new byte[length];
-        for (int i = 0; i < length; i++) {
-            data[i] = ((RRaw) castRawRecursive(value.getDataAt(i))).getValue();
+    @Specialization(guards = {"uAccess.supports(value)"}, limit = "getVectorAccessCacheSize()")
+    protected RRawVector doList(RAbstractListVector value,
+                    @Cached("value.access()") VectorAccess uAccess) {
+        byte[] bdata = new byte[value.getLength()];
+        try (SequentialIterator sIter = uAccess.access(value, warningContext())) {
+            while (uAccess.next(sIter)) {
+                int i = sIter.getIndex();
+                Object entry = uAccess.getListElement(sIter);
+                if (entry instanceof RList) {
+                    bdata[i] = 0;
+                } else {
+                    Object castEntry = castRawRecursive(entry);
+                    if (castEntry instanceof RRaw) {
+                        bdata[i] = ((RRaw) castRawRecursive(castEntry)).getValue();
+                    } else if (castEntry instanceof RAbstractRawVector) {
+                        RAbstractRawVector rawVector = (RAbstractRawVector) castEntry;
+                        if (rawVector.getLength() == 1) {
+                            bdata[i] = rawVector.getRawDataAt(0);
+                        } else if (rawVector.getLength() == 0) {
+                            bdata[i] = 0;
+                        } else {
+                            throw throwCannotCoerceListError("object");
+                        }
+                    } else {
+                        throw throwCannotCoerceListError("object");
+                    }
+                }
+            }
         }
-        RRawVector result = factory().createRawVector(data, getPreservedDimensions(value), getPreservedNames(value), null);
+        RRawVector result = factory().createRawVector(bdata, getPreservedDimensions(value), getPreservedNames(value), null);
         if (preserveRegAttributes()) {
             result.copyRegAttributesFrom(value);
         }
         return result;
     }
 
+    @Specialization(replaces = "doList")
+    protected RRawVector doListGenric(RAbstractListVector value) {
+        return doList(value, value.slowPathAccess());
+    }
+
     @Specialization(guards = "!pairList.isLanguage()")
     protected RRawVector doPairList(RPairList pairList) {
-        return doList(pairList.toRList());
+        return (RRawVector) castRawRecursive(pairList.toRList());
     }
 
     public static CastRawNode createForRFFI(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
@@ -324,4 +274,9 @@ public abstract class CastRawNode extends CastBaseNode {
     public static CastRawNode createNonPreserving() {
         return CastRawNodeGen.create(false, false, false);
     }
+
+    protected boolean isRawVector(RAbstractAtomicVector x) {
+        return x instanceof RAbstractRawVector;
+    }
+
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/FastPathVectorAccess.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/FastPathVectorAccess.java
index cae6a747e75e43c1adce82cb6f564649854b95bf..f7d15ce1285143d4a3fca5d2d696811ec2c63274 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/FastPathVectorAccess.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/FastPathVectorAccess.java
@@ -24,6 +24,7 @@ package com.oracle.truffle.r.runtime.data.nodes;
 
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
+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;
@@ -34,6 +35,7 @@ import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RRaw;
 import com.oracle.truffle.r.runtime.data.RVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
+import com.oracle.truffle.r.runtime.ops.na.NAProfile;
 
 /**
  * Base classes for {@link VectorAccess} implementations that are used on the fast path. For
@@ -443,17 +445,28 @@ public abstract class FastPathVectorAccess extends VectorAccess {
 
         @Override
         protected final byte getRawImpl(AccessIterator accessIter, int index) {
-            double value = getComplexRImpl(accessIter, index);
-            if (Double.isNaN(value) || value < 0 || value >= 256) {
+            RComplex value = getComplexImpl(accessIter, index);
+
+            double realPart = value.getRealPart();
+            double realResult = realPart;
+
+            if (realPart > Integer.MAX_VALUE || realPart <= Integer.MIN_VALUE) {
                 warningReportedProfile.enter();
-                accessIter.warning(Message.OUT_OF_RANGE);
-                return 0;
+                accessIter.warning(RError.Message.NA_INTRODUCED_COERCION_INT);
+                realResult = 0;
             }
+
             if (getComplexIImpl(accessIter, index) != 0) {
                 warningReportedProfile.enter();
                 accessIter.warning(Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
             }
-            return (byte) value;
+
+            if (Double.isNaN(realPart) || realPart < 0 || realPart >= 256) {
+                warningReportedProfile.enter();
+                accessIter.warning(Message.OUT_OF_RANGE);
+                realResult = 0;
+            }
+            return (byte) RRuntime.double2rawIntValue(realResult);
         }
 
         @Override
@@ -497,6 +510,7 @@ public abstract class FastPathVectorAccess extends VectorAccess {
     public abstract static class FastPathFromStringAccess extends FastPathVectorAccess {
 
         ConditionProfile emptyStringProfile = ConditionProfile.createBinaryProfile();
+        private NAProfile naProfile = NAProfile.create();
 
         public FastPathFromStringAccess(Object value) {
             super(value);
@@ -526,13 +540,48 @@ public abstract class FastPathVectorAccess extends VectorAccess {
 
         @Override
         protected final double getDoubleImpl(AccessIterator accessIter, int index) {
-            return na.convertStringToDouble(getStringImpl(accessIter, index));
+            String str = getStringImpl(accessIter, index);
+            if (na.check(str) || emptyStringProfile.profile(str.isEmpty())) {
+                na.enable(true);
+                return RRuntime.DOUBLE_NA;
+            }
+            double value = na.convertStringToDouble(str);
+            if (RRuntime.isNA(value)) {
+                na.enable(true);
+                warningReportedProfile.enter();
+                accessIter.warning(Message.NA_INTRODUCED_COERCION);
+                return RRuntime.DOUBLE_NA;
+            }
+            return value;
         }
 
         @Override
         protected final byte getRawImpl(AccessIterator accessIter, int index) {
-            int value = na.convertStringToInt(getStringImpl(accessIter, index));
-            return value >= 0 && value <= 255 ? (byte) value : 0;
+            String value = getStringImpl(accessIter, index);
+            int intValue;
+            if (na.check(value) || emptyStringProfile.profile(value.isEmpty())) {
+                intValue = RRuntime.INT_NA;
+            } else {
+                intValue = RRuntime.string2intNoCheck(value);
+                if (naProfile.isNA(intValue)) {
+                    if (!value.isEmpty()) {
+                        warningReportedProfile.enter();
+                        try {
+                            Double.parseDouble(value);
+                            accessIter.warning(RError.Message.NA_INTRODUCED_COERCION_INT);
+                        } catch (NumberFormatException e) {
+                            accessIter.warning(RError.Message.NA_INTRODUCED_COERCION);
+                        }
+                    }
+                }
+                int intRawValue = RRuntime.int2rawIntValue(intValue);
+                if (intValue != intRawValue) {
+                    warningReportedProfile.enter();
+                    accessIter.warning(Message.OUT_OF_RANGE);
+                    intValue = 0;
+                }
+            }
+            return intValue >= 0 && intValue <= 255 ? (byte) intValue : 0;
         }
 
         @Override
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/SlowPathVectorAccess.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/SlowPathVectorAccess.java
index 0c6c1a9611df82c707fd3a115c0f83b1136cf0d6..92b904a098d2e17563051253118eb9e034133e4d 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/SlowPathVectorAccess.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/nodes/SlowPathVectorAccess.java
@@ -70,9 +70,8 @@ public abstract class SlowPathVectorAccess extends VectorAccess {
             int value = getIntImpl(accessIter, index);
             byte result = (byte) value;
             if ((result & 0xff) != value) {
-                if (accessIter.warning(Message.OUT_OF_RANGE)) {
-                    warningReportedProfile.enter();
-                }
+                warningReportedProfile.enter();
+                accessIter.warning(Message.OUT_OF_RANGE);
                 return 0;
             }
             return result;
@@ -150,9 +149,8 @@ public abstract class SlowPathVectorAccess extends VectorAccess {
             }
             if (value > Integer.MAX_VALUE || value <= Integer.MIN_VALUE) {
                 na.enable(true);
-                if (accessIter.warning(Message.NA_INTRODUCED_COERCION_INT)) {
-                    warningReportedProfile.enter();
-                }
+                warningReportedProfile.enter();
+                accessIter.warning(Message.NA_INTRODUCED_COERCION_INT);
                 return RRuntime.INT_NA;
             }
             return (int) value;
@@ -163,9 +161,8 @@ public abstract class SlowPathVectorAccess extends VectorAccess {
             int value = (int) getDoubleImpl(accessIter, index);
             byte result = (byte) value;
             if ((result & 0xff) != value) {
-                if (accessIter.warning(Message.OUT_OF_RANGE)) {
-                    warningReportedProfile.enter();
-                }
+                warningReportedProfile.enter();
+                accessIter.warning(Message.OUT_OF_RANGE);
                 return 0;
             }
             return result;
@@ -250,9 +247,8 @@ public abstract class SlowPathVectorAccess extends VectorAccess {
         protected final byte getRawImpl(AccessIterator accessIter, int index) {
             byte value = getLogicalImpl(accessIter, index);
             if (na.check(value)) {
-                if (accessIter.warning(Message.OUT_OF_RANGE)) {
-                    warningReportedProfile.enter();
-                }
+                warningReportedProfile.enter();
+                accessIter.warning(Message.OUT_OF_RANGE);
                 return 0;
             }
             return value;
@@ -395,15 +391,13 @@ public abstract class SlowPathVectorAccess extends VectorAccess {
             }
             if (value > Integer.MAX_VALUE || value <= Integer.MIN_VALUE) {
                 na.enable(true);
-                if (accessIter.warning(Message.NA_INTRODUCED_COERCION_INT)) {
-                    warningReportedProfile.enter();
-                }
+                warningReportedProfile.enter();
+                accessIter.warning(Message.NA_INTRODUCED_COERCION_INT);
                 return RRuntime.INT_NA;
             }
             if (getComplexIImpl(accessIter, index) != 0) {
-                if (accessIter.warning(Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION)) {
-                    warningReportedProfile.enter();
-                }
+                warningReportedProfile.enter();
+                accessIter.warning(Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
             }
             return (int) value;
         }
@@ -416,9 +410,8 @@ public abstract class SlowPathVectorAccess extends VectorAccess {
                 return RRuntime.DOUBLE_NA;
             }
             if (getComplexIImpl(accessIter, index) != 0) {
-                if (accessIter.warning(Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION)) {
-                    warningReportedProfile.enter();
-                }
+                warningReportedProfile.enter();
+                accessIter.warning(Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
             }
             return value;
         }
@@ -427,15 +420,13 @@ public abstract class SlowPathVectorAccess extends VectorAccess {
         protected final byte getRawImpl(AccessIterator accessIter, int index) {
             double value = getComplexRImpl(accessIter, index);
             if (Double.isNaN(value) || value < 0 || value >= 256) {
-                if (accessIter.warning(Message.OUT_OF_RANGE)) {
-                    warningReportedProfile.enter();
-                }
+                warningReportedProfile.enter();
+                accessIter.warning(Message.OUT_OF_RANGE);
                 return 0;
             }
             if (getComplexIImpl(accessIter, index) != 0) {
-                if (accessIter.warning(Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION)) {
-                    warningReportedProfile.enter();
-                }
+                warningReportedProfile.enter();
+                accessIter.warning(Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
             }
             return (byte) value;
         }
@@ -495,9 +486,8 @@ public abstract class SlowPathVectorAccess extends VectorAccess {
             int value = na.convertStringToInt(str);
             if (RRuntime.isNA(value)) {
                 na.enable(true);
-                if (accessIter.warning(Message.NA_INTRODUCED_COERCION)) {
-                    warningReportedProfile.enter();
-                }
+                warningReportedProfile.enter();
+                accessIter.warning(Message.NA_INTRODUCED_COERCION);
                 return RRuntime.INT_NA;
             }
             return value;
@@ -505,7 +495,19 @@ public abstract class SlowPathVectorAccess extends VectorAccess {
 
         @Override
         protected final double getDoubleImpl(AccessIterator accessIter, int index) {
-            return na.convertStringToDouble(getStringImpl(accessIter, index));
+            String str = getStringImpl(accessIter, index);
+            if (na.check(str) || str.isEmpty()) {
+                na.enable(true);
+                return RRuntime.DOUBLE_NA;
+            }
+            double value = na.convertStringToDouble(str);
+            if (RRuntime.isNA(value)) {
+                na.enable(true);
+                warningReportedProfile.enter();
+                accessIter.warning(Message.NA_INTRODUCED_COERCION);
+                return RRuntime.DOUBLE_NA;
+            }
+            return value;
         }
 
         @Override
@@ -528,6 +530,7 @@ public abstract class SlowPathVectorAccess extends VectorAccess {
             } else {
                 complexValue = RRuntime.string2complexNoCheck(value);
                 if (complexValue.isNA()) {
+                    warningReportedProfile.enter();
                     na.enable(true);
                     accessIter.warning(Message.NA_INTRODUCED_COERCION);
                 }
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 24be500cb18fe54ba85bcbd257d418d1b1149bea..0a6b1dce988003c6e5dcf6359cbe5a521c00005e 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
@@ -6079,6 +6079,10 @@ quote(80L)
 #argv <- list(list(quote(quote), NA));as.call(argv[[1]]);
 quote(NA)
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_ascharacter.noCopyCheck#
+#if (!any(R.version$engine == "FastR")) { [1] TRUE } else { { x <- c('a', 'abc'); .fastr.identity(x) == .fastr.identity(as.character(x)); } }
+Error: unexpected '[' in "if (!any(R.version$engine == "FastR")) { ["
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_ascharacter.testAsCharacter#
 #{ as.character() }
 character(0)
@@ -6462,6 +6466,10 @@ character(0)
 #argv <- structure(list(x = structure(c(1L, 2L, NA), .Label = c('AB',     'CD'), class = 'factor')), .Names = 'x');do.call('as.character.factor', argv)
 [1] "AB" "CD" NA
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_ascomplex.noCopyCheck#
+#if (!any(R.version$engine == "FastR")) { [1] TRUE } else { { x <- c(1+2i, 3.5+3i); .fastr.identity(x) == .fastr.identity(as.complex(x)); } }
+Error: unexpected '[' in "if (!any(R.version$engine == "FastR")) { ["
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_ascomplex.testAsComplex#Ignored.ImplementationError#
 #{ as.complex("+.1e+2-3i") }
 [1] 10-3i
@@ -6658,12 +6666,16 @@ Time differences in mins
 Time differences in hours
 [1]  3.333333 23.250000        NA
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asdouble.noCopyCheck#
+#if (!any(R.version$engine == "FastR")) { [1] TRUE } else { { x <- c(1, 3.5); .fastr.identity(x) == .fastr.identity(as.double(x)); } }
+Error: unexpected '[' in "if (!any(R.version$engine == "FastR")) { ["
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_asdouble.testAsDouble#
 #{ as.double("1.27") }
 [1] 1.27
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asdouble.testAsDouble#Output.IgnoreWarningContext#
-#{ as.double("TRUE") }
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asdouble.testAsDouble#
+#{ as.double('TRUE') }
 [1] NA
 Warning message:
 NAs introduced by coercion
@@ -6672,7 +6684,7 @@ NAs introduced by coercion
 #{ as.double() }
 numeric(0)
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asdouble.testAsDouble#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asdouble.testAsDouble#
 #{ as.double(10+2i) }
 [1] 10
 Warning message:
@@ -6690,13 +6702,13 @@ numeric(0)
 #{ as.double(as.raw(1)) }
 [1] 1
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asdouble.testAsDouble#Output.IgnoreWarningContext#
-#{ as.double(c("1","hello")) }
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asdouble.testAsDouble#
+#{ as.double(c('1','hello')) }
 [1]  1 NA
 Warning message:
 NAs introduced by coercion
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asdouble.testAsDouble#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asdouble.testAsDouble#
 #{ as.double(c(3+3i, 4+4i)) }
 [1] 3 4
 Warning message:
@@ -6930,7 +6942,7 @@ numeric(0)
 [26] -6.364429e-03 -4.837092e-02 -7.047955e-02  3.494377e-02 -2.648308e-02
 [31]  2.009015e-02
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asdouble.testasdouble9#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asdouble.testasdouble9#
 #argv <- list(c('-.1', ' 2.7 ', 'B'));as.double(argv[[1]]);
 [1] -0.1  2.7   NA
 Warning message:
@@ -6940,6 +6952,10 @@ NAs introduced by coercion
 #argv <- structure(list(x = structure(16351.8259046444, units = 'days',     class = 'difftime', origin = structure(0, class = c('POSIXct',         'POSIXt'), tzone = 'GMT'))), .Names = 'x');do.call('as.double.difftime', argv)
 [1] 16351.83
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asexpression.noCopyCheck#
+#if (!any(R.version$engine == "FastR")) { [1] TRUE } else { { x <- as.expression(quote(x+2)); .fastr.identity(x) == .fastr.identity(as.expression(x)); } }
+Error: unexpected '[' in "if (!any(R.version$engine == "FastR")) { ["
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_asexpression.testAsExpression#
 #{ as.expression("name") }
 expression("name")
@@ -7128,6 +7144,14 @@ numeric(0)
 #argv <- list(c(0.34345+233i,-0.34345+0.3334i));asinh(argv[[1]]);
 [1]  6.1441821+1.5693223i -0.3542312+0.3189009i
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asinteger.noCopyCheck#
+#if (!any(R.version$engine == "FastR")) { [1] TRUE } else { { x <- 1:10; .fastr.identity(x) == .fastr.identity(as.integer(x)); } }
+Error: unexpected '[' in "if (!any(R.version$engine == "FastR")) { ["
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asinteger.noCopyCheck#
+#if (!any(R.version$engine == "FastR")) { [1] TRUE } else { { x <- c(1L, 3L); .fastr.identity(x) == .fastr.identity(as.integer(x)); } }
+Error: unexpected '[' in "if (!any(R.version$engine == "FastR")) { ["
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_asinteger.testAsInteger#
 #{ as.integer("") }
 [1] NA
@@ -7262,6 +7286,12 @@ Error: (list) object cannot be coerced to type 'integer'
 #{ as.integer.cls <- function(x) 42; as.integer(structure(c(1,2), class='cls')); }
 [1] 42
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asinteger.testAsInteger#Output.IgnoreWarningContext#
+#{ f <- function() as.integer(10+2i); f() }
+[1] 10
+Warning message:
+In f() : imaginary parts discarded in coercion
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_asinteger.testAsInteger#
 #{ x<-c(a=1.1, b=2.2); dim(x)<-c(1,2); attr(x, "foo")<-"foo"; y<-as.integer(x); attributes(y) }
 NULL
@@ -7384,6 +7414,10 @@ integer(0)
 #argv <- list('-1');as.integer(argv[[1]]);
 [1] -1
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_aslist.noCopyCheck#
+#if (!any(R.version$engine == "FastR")) { [1] TRUE } else { { x <- list(1, 'abc', list(32)); .fastr.identity(x) == .fastr.identity(as.list(x)); } }
+Error: unexpected '[' in "if (!any(R.version$engine == "FastR")) { ["
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_aslist.testaslist1#
 #argv <- structure(list(x = structure(c(9.83610941897737, 1.76740501065812,     3.23822416444495, -2.66666666666667, -10, 28), .Names = c('X',     'Y', 'Z', 'a', 'b', 'c'))), .Names = 'x');do.call('as.list', argv)
 $X
@@ -7405,6 +7439,10 @@ $c
 [1] 28
 
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_aslogical.noCopyCheck#
+#if (!any(R.version$engine == "FastR")) { [1] TRUE } else { { x <- c(T, F, T, T); .fastr.identity(x) == .fastr.identity(as.logical(x)); } }
+Error: unexpected '[' in "if (!any(R.version$engine == "FastR")) { ["
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_aslogical.testAsLogical#
 #{ as.logical("TRUE") }
 [1] TRUE
@@ -7783,30 +7821,45 @@ C:D         9
 [241] "361" "362" "363" "364" "365" "366" "367" "370" "371" "372" "373" "374"
 [253] "375" "376" "377"
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWarningContext#
-#{ as.raw("test") }
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.noCopyCheck#
+#if (!any(R.version$engine == "FastR")) { [1] TRUE } else { { x <- as.raw(c(1, 3)); .fastr.identity(x) == .fastr.identity(as.raw(x)); } }
+Error: unexpected '[' in "if (!any(R.version$engine == "FastR")) { ["
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw('1') }
+[1] 01
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw('1000') }
+[1] 00
+Warning message:
+out-of-range values treated as 0 in coercion to raw
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWhitespace#
+#{ as.raw('10000000000000000') }
 [1] 00
 Warning messages:
-1: NAs introduced by coercion
+1: NAs introduced by coercion to integer range
 2: out-of-range values treated as 0 in coercion to raw
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWarningContext#
-#{ as.raw('10000001') }
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWhitespace#
+#{ as.raw('test') }
 [1] 00
-Warning message:
-out-of-range values treated as 0 in coercion to raw
+Warning messages:
+1: NAs introduced by coercion
+2: out-of-range values treated as 0 in coercion to raw
 
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
 #{ as.raw() }
 Error in as.raw() : 0 arguments passed to 'as.raw' which requires 1
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
 #{ as.raw(-1) }
 [1] 00
 Warning message:
 out-of-range values treated as 0 in coercion to raw
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
 #{ as.raw(-1L) }
 [1] 00
 Warning message:
@@ -7816,7 +7869,7 @@ out-of-range values treated as 0 in coercion to raw
 #{ as.raw(1) }
 [1] 01
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
 #{ as.raw(1+1i) }
 [1] 01
 Warning message:
@@ -7826,26 +7879,125 @@ imaginary parts discarded in coercion
 #{ as.raw(1.1) }
 [1] 01
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(1000) }
+[1] 00
+Warning message:
+out-of-range values treated as 0 in coercion to raw
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWhitespace#
+#{ as.raw(1000+1i) }
+[1] 00
+Warning messages:
+1: imaginary parts discarded in coercion
+2: out-of-range values treated as 0 in coercion to raw
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWhitespace#
+#{ as.raw(10000000000000000) }
+[1] 00
+Warning messages:
+1: NAs introduced by coercion to integer range
+2: out-of-range values treated as 0 in coercion to raw
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWhitespace#
+#{ as.raw(10000000000000000+1i) }
+[1] 00
+Warning messages:
+1: NAs introduced by coercion to integer range
+2: out-of-range values treated as 0 in coercion to raw
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(1000L) }
+[1] 00
+Warning message:
+out-of-range values treated as 0 in coercion to raw
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
 #{ as.raw(1L) }
 [1] 01
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
 #{ as.raw(NA) }
 [1] 00
 Warning message:
 out-of-range values treated as 0 in coercion to raw
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(NA_complex_) }
+[1] 00
+Warning message:
+out-of-range values treated as 0 in coercion to raw
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(NA_integer_) }
+[1] 00
+Warning message:
+out-of-range values treated as 0 in coercion to raw
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
 #{ as.raw(NULL) }
 raw(0)
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWarningContext#
-#{ as.raw(c('10000001', '42')) }
-[1] 00 2a
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(TRUE) }
+[1] 01
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(as.raw(list(1, 1+1i)) }
+Error: unexpected '}' in "{ as.raw(as.raw(list(1, 1+1i)) }"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(as.raw(list(1, 10000000000000)) }
+Error: unexpected '}' in "{ as.raw(as.raw(list(1, 10000000000000)) }"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(as.raw(list(1, 10000000000000, 1+1i)) }
+Error: unexpected '}' in "{ as.raw(as.raw(list(1, 10000000000000, 1+1i)) }"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(as.raw(list(1, 2, c(1, 2, 3))) }
+Error: unexpected '}' in "{ as.raw(as.raw(list(1, 2, c(1, 2, 3))) }"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(as.raw(list(1, 2, new.env())) }
+Error: unexpected '}' in "{ as.raw(as.raw(list(1, 2, new.env())) }"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(as.raw(list(1, NA)) }
+Error: unexpected '}' in "{ as.raw(as.raw(list(1, NA)) }"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(as.raw(list(1, NA, list(1))) }
+Error: unexpected '}' in "{ as.raw(as.raw(list(1, NA, list(1))) }"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(as.raw(list(1, NA, list(1, 2, 3))) }
+Error: unexpected '}' in "{ as.raw(as.raw(list(1, NA, list(1, 2, 3))) }"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(c('1', '1000')) }
+[1] 01 00
 Warning message:
 out-of-range values treated as 0 in coercion to raw
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(c('1', '2')) }
+[1] 01 02
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWhitespace#
+#{ as.raw(c('10000000000000000', '1')) }
+[1] 00 01
+Warning messages:
+1: NAs introduced by coercion to integer range
+2: out-of-range values treated as 0 in coercion to raw
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWhitespace#
+#{ as.raw(c('10000000000000000', '1000')) }
+[1] 00 00
+Warning messages:
+1: NAs introduced by coercion to integer range
+2: out-of-range values treated as 0 in coercion to raw
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWarningContext#
 #{ as.raw(c(1+3i, -2-1i, NA)) }
 [1] 01 00 00
@@ -7853,7 +8005,7 @@ Warning messages:
 1: imaginary parts discarded in coercion
 2: out-of-range values treated as 0 in coercion to raw
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
 #{ as.raw(c(1, -2, 3)) }
 [1] 01 00 03
 Warning message:
@@ -7863,19 +8015,49 @@ out-of-range values treated as 0 in coercion to raw
 #{ as.raw(c(1, 2, 3)) }
 [1] 01 02 03
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
 #{ as.raw(c(1,1000,NA)) }
 [1] 01 00 00
 Warning message:
 out-of-range values treated as 0 in coercion to raw
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWarningMessage#
+#{ as.raw(c(1000, 1+1i)) }
+[1] 00 01
+Warning messages:
+1: imaginary parts discarded in coercion
+2: out-of-range values treated as 0 in coercion to raw
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWhitespace#
+#{ as.raw(c(10000000000000000+1i, 1+1i)) }
+[1] 00 01
+Warning messages:
+1: NAs introduced by coercion to integer range
+2: imaginary parts discarded in coercion
+3: out-of-range values treated as 0 in coercion to raw
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWhitespace#
+#{ as.raw(c(10000000000000000+1i, 1000+1i, NA_complex_, 1+1i)) }
+[1] 00 00 00 01
+Warning messages:
+1: NAs introduced by coercion to integer range
+2: imaginary parts discarded in coercion
+3: out-of-range values treated as 0 in coercion to raw
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWarningMessage#
+#{ as.raw(c(1000L, 1+1i)) }
+[1] 00 01
+Warning messages:
+1: imaginary parts discarded in coercion
+2: out-of-range values treated as 0 in coercion to raw
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
 #{ as.raw(c(1L, -2L, 3L)) }
 [1] 01 00 03
 Warning message:
 out-of-range values treated as 0 in coercion to raw
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
 #{ as.raw(c(1L, -2L, NA)) }
 [1] 01 00 00
 Warning message:
@@ -7885,6 +8067,23 @@ out-of-range values treated as 0 in coercion to raw
 #{ as.raw(c(1L, 2L, 3L)) }
 [1] 01 02 03
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(c(1L, 2L, NA_integer_)) }
+[1] 01 02 00
+Warning message:
+out-of-range values treated as 0 in coercion to raw
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#Output.IgnoreWhitespace#
+#{ as.raw(c(NA_complex_, 1+1i)) }
+[1] 00 01
+Warning messages:
+1: imaginary parts discarded in coercion
+2: out-of-range values treated as 0 in coercion to raw
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
+#{ as.raw(c(TRUE, FALSE)) }
+[1] 01 00
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_asraw.testAsRaw#
 #{ as.raw(list("1", 2L, 3.4)) }
 [1] 01 02 03
@@ -81971,7 +82170,7 @@ Error in call(f, quote(A)) : first argument must be a character string
 #{ as.complex(as.character(c(1+1i,1+1i))) }
 [1] 1+1i 1+1i
 
-##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testCasts#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testCasts#
 #{ as.complex(as.double(c(1+1i,1+1i))) }
 [1] 1+0i 1+0i
 Warning message:
@@ -81987,7 +82186,7 @@ imaginary parts discarded in coercion
 #{ as.complex(as.logical(c(1+1i,1+1i))) }
 [1] 1+0i 1+0i
 
-##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testCasts#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.builtins.TestMiscBuiltins.testCasts#
 #{ as.complex(as.raw(c(1+1i,1+1i))) }
 [1] 1+0i 1+0i
 Warning message:
@@ -145078,13 +145277,13 @@ NAs introduced by coercion
 #if (!any(R.version$engine == "FastR")) { as.complex(c(TRUE,FALSE,TRUE)) } else { to <- .fastr.interop.new(java.type('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'));as.complex(to$listBoolean); }
 [1] 1+0i 0+0i 1+0i
 
-##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAsXXX#Output.IgnoreWarningMessage#
+##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAsXXX#
 #if (!any(R.version$engine == "FastR")) { as.double("a string") } else { to <- .fastr.interop.new(java.type('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'));as.double(to$fieldStaticStringObject) }
 [1] NA
 Warning message:
 NAs introduced by coercion
 
-##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAsXXX#Output.IgnoreWarningMessage#
+##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAsXXX#
 #if (!any(R.version$engine == "FastR")) { as.double("a") } else { to <- .fastr.interop.new(java.type('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'));as.double(to$fieldStaticCharObject) }
 [1] NA
 Warning message:
@@ -145671,13 +145870,13 @@ Warning messages:
 #if (!any(R.version$engine == "FastR")) { as.raw(127) } else { to <- .fastr.interop.new(java.type('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'));as.raw(to$fieldStaticByteObject) }
 [1] 7f
 
-##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAsXXX#Output.IgnoreWarningMessage#
+##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAsXXX#
 #if (!any(R.version$engine == "FastR")) { as.raw(2147483647) } else { to <- .fastr.interop.new(java.type('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'));as.raw(to$fieldStaticIntegerObject) }
 [1] 00
 Warning message:
 out-of-range values treated as 0 in coercion to raw
 
-##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAsXXX#Output.IgnoreWarningMessage#
+##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testAsXXX#
 #if (!any(R.version$engine == "FastR")) { as.raw(32767) } else { to <- .fastr.interop.new(java.type('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'));as.raw(to$fieldStaticShortObject) }
 [1] 00
 Warning message:
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascharacter.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascharacter.java
index 6e399a441abd6d4f46051720d2ed0de86bbe484e..4f5d29c038e4e7362ca58732176868733e161776 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascharacter.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascharacter.java
@@ -281,4 +281,9 @@ public class TestBuiltin_ascharacter extends TestBase {
         assertEval("{ as.character.cls <- function(x) 42; as.character(structure(c(1,2), class='cls')); }");
         assertEval("{ y <- c('a', 'b'); attr(y, 'someAttr') <- 'someValue'; x <- as.character(y); x[[1]] <- '42'; y }");
     }
+
+    @Test
+    public void noCopyCheck() {
+        assertEvalFastR("{ x <- c('a', 'abc'); .fastr.identity(x) == .fastr.identity(as.character(x)); }", "[1] TRUE");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascomplex.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascomplex.java
index 17871c3a901121188d634a07c72ede6fec287ddf..ec38db8e732b7e20430b0cb062695dc58fa466b3 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascomplex.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascomplex.java
@@ -116,4 +116,9 @@ public class TestBuiltin_ascomplex extends TestBase {
         assertEval(Output.IgnoreWarningContext, "{ as.complex(list(\"foo\")) }");
         assertEval("{ as.complex.cls <- function(x) 42; as.complex(structure(c(1,2), class='cls')); }");
     }
+
+    @Test
+    public void noCopyCheck() {
+        assertEvalFastR("{ x <- c(1+2i, 3.5+3i); .fastr.identity(x) == .fastr.identity(as.complex(x)); }", "[1] TRUE");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asdouble.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asdouble.java
index 4e7a8fd0cc6cb914133986bbc05578bdc41c50d1..c17644bebbfbcffe8fad88f394fc78770b5f09c1 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asdouble.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asdouble.java
@@ -69,7 +69,7 @@ public class TestBuiltin_asdouble extends TestBase {
 
     @Test
     public void testasdouble9() {
-        assertEval(Output.IgnoreWarningContext, "argv <- list(c('-.1', ' 2.7 ', 'B'));as.double(argv[[1]]);");
+        assertEval("argv <- list(c('-.1', ' 2.7 ', 'B'));as.double(argv[[1]]);");
     }
 
     @Test
@@ -188,14 +188,19 @@ public class TestBuiltin_asdouble extends TestBase {
         assertEval("{ as.double(\"1.27\") }");
         assertEval("{ as.double(1L) }");
         assertEval("{ as.double(as.raw(1)) }");
-        assertEval(Output.IgnoreWarningContext, "{ as.double(c(\"1\",\"hello\")) }");
-        assertEval(Output.IgnoreWarningContext, "{ as.double(\"TRUE\") }");
-        assertEval(Output.IgnoreWarningContext, "{ as.double(10+2i) }");
-        assertEval(Output.IgnoreWarningContext, "{ as.double(c(3+3i, 4+4i)) }");
+        assertEval("{ as.double(c('1','hello')) }");
+        assertEval("{ as.double('TRUE') }");
+        assertEval("{ as.double(10+2i) }");
+        assertEval("{ as.double(c(3+3i, 4+4i)) }");
         assertEval("{ x<-c(a=1.1, b=2.2); dim(x)<-c(1,2); attr(x, \"foo\")<-\"foo\"; y<-as.double(x); attributes(y) }");
         assertEval("{ x<-c(a=1L, b=2L); dim(x)<-c(1,2); attr(x, \"foo\")<-\"foo\"; y<-as.double(x); attributes(y) }");
         assertEval("{ as.double(NULL) }");
         assertEval("{ as.double.cls <- function(x) 42; as.double(structure(c(1,2), class='cls')); }");
         assertEval("{ y <- c(3.1, 3.2); attr(y, 'someAttr') <- 'someValue'; x <- as.double(y); x[[1]] <- 42; y }");
     }
+
+    @Test
+    public void noCopyCheck() {
+        assertEvalFastR("{ x <- c(1, 3.5); .fastr.identity(x) == .fastr.identity(as.double(x)); }", "[1] TRUE");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asexpression.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asexpression.java
index ac10247fbe5be7a0a41cb806567857f810cb7a8d..f105859b422f4481da0edad905b916bd80a244f0 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asexpression.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asexpression.java
@@ -45,4 +45,9 @@ public class TestBuiltin_asexpression extends TestBase {
         assertEval(Output.IgnoreErrorContext, "{ as.expression(sum) }");
         assertEval(Output.IgnoreErrorContext, "{ as.expression(function() {}) }");
     }
+
+    @Test
+    public void noCopyCheck() {
+        assertEvalFastR("{ x <- as.expression(quote(x+2)); .fastr.identity(x) == .fastr.identity(as.expression(x)); }", "[1] TRUE");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asinteger.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asinteger.java
index dff1e558d942c4ac14007c559e22f05eed1201b8..b4a10d805407ed648820074951978e381ca909b5 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asinteger.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asinteger.java
@@ -138,6 +138,7 @@ public class TestBuiltin_asinteger extends TestBase {
         assertEval("{ as.integer(-0/0) }");
         assertEval("{ as.integer(as.raw(c(1,2,3,4))) }");
         assertEval("{ as.integer(10+2i) }");
+        assertEval(Output.IgnoreWarningContext, "{ f <- function() as.integer(10+2i); f() }");
         assertEval("{ as.integer(c(3+3i, 4+4i)) }");
         assertEval("{ as.integer(10000000000000) }");
         assertEval("{ as.integer(list(c(1),2,3)) }");
@@ -162,4 +163,10 @@ public class TestBuiltin_asinteger extends TestBase {
         assertEval("{ as.integer(c(100, -1e-13, Inf, -Inf, NaN, 3.14159265358979, NA)) }");
         assertEval("{ y <- c(3L, 4L); attr(y, 'someAttr') <- 'someValue'; x <- as.integer(y); x[[1]] <- 42L; y }");
     }
+
+    @Test
+    public void noCopyCheck() {
+        assertEvalFastR("{ x <- c(1L, 3L); .fastr.identity(x) == .fastr.identity(as.integer(x)); }", "[1] TRUE");
+        assertEvalFastR("{ x <- 1:10; .fastr.identity(x) == .fastr.identity(as.integer(x)); }", "[1] TRUE");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_aslist.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_aslist.java
index d722f781e1613f5f065cae918de7e94184385138..a758d09f06a8d5a26b674e993c902e97f31ea9d2 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_aslist.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_aslist.java
@@ -33,4 +33,9 @@ public class TestBuiltin_aslist extends TestBase {
         assertEval("argv <- structure(list(x = structure(c(9.83610941897737, 1.76740501065812,     3.23822416444495, -2.66666666666667, -10, 28), .Names = c('X',     'Y', 'Z', 'a', 'b', 'c'))), .Names = 'x');" +
                         "do.call('as.list', argv)");
     }
+
+    @Test
+    public void noCopyCheck() {
+        assertEvalFastR("{ x <- list(1, 'abc', list(32)); .fastr.identity(x) == .fastr.identity(as.list(x)); }", "[1] TRUE");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_aslogical.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_aslogical.java
index f29842171b408c5c981402cb5a6fb98280f51150..9928a518fbfa5c55ddd698f799339fd4fc91b31c 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_aslogical.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_aslogical.java
@@ -112,4 +112,9 @@ public class TestBuiltin_aslogical extends TestBase {
         assertEval("{ as.logical.cls <- function(x) 42; as.logical(structure(c(1,2), class='cls')); }");
         assertEval("{ y <- c(T, F); attr(y, 'someAttr') <- 'someValue'; x <- as.logical(y); x[[1]] <- F; y }");
     }
+
+    @Test
+    public void noCopyCheck() {
+        assertEvalFastR("{ x <- c(T, F, T, T); .fastr.identity(x) == .fastr.identity(as.logical(x)); }", "[1] TRUE");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asraw.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asraw.java
index af160b0108a973cc3eb43f1e2e43d14fd7239c22..cb6347db0484d5e96597acbebf38f2e5ce37dca4 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asraw.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asraw.java
@@ -63,25 +63,60 @@ public class TestBuiltin_asraw extends TestBase {
         assertEval("{ as.raw(NULL) }");
         assertEval("{ as.raw(1) }");
         assertEval("{ as.raw(1L) }");
+        assertEval("{ as.raw(TRUE) }");
+        assertEval("{ as.raw(c(TRUE, FALSE)) }");
+        assertEval("{ as.raw(NA_integer_) }");
         assertEval("{ as.raw(1.1) }");
         assertEval("{ as.raw(c(1, 2, 3)) }");
         assertEval("{ as.raw(c(1L, 2L, 3L)) }");
+        assertEval("{ as.raw(c(1L, 2L, NA_integer_)) }");
         assertEval("{ as.raw(list(1,2,3)) }");
         assertEval("{ as.raw(list(\"1\", 2L, 3.4)) }");
+        assertEval("{ as.raw(as.raw(list(1, 2, c(1, 2, 3))) }");
+        assertEval("{ as.raw(as.raw(list(1, 2, new.env())) }");
+        assertEval("{ as.raw(as.raw(list(1, 10000000000000)) }");
+        assertEval("{ as.raw(as.raw(list(1, 1+1i)) }");
+        assertEval("{ as.raw(as.raw(list(1, 10000000000000, 1+1i)) }");
+        assertEval("{ as.raw(as.raw(list(1, NA)) }");
+        assertEval("{ as.raw(as.raw(list(1, NA, list(1))) }");
+        assertEval("{ as.raw(as.raw(list(1, NA, list(1, 2, 3))) }");
         assertEval("{ as.raw.cls <- function(x) 42; as.raw(structure(c(1,2), class='cls')); }");
 
-        assertEval(Output.IgnoreWarningContext, "{ as.raw(1+1i) }");
-        assertEval(Output.IgnoreWarningContext, "{ as.raw(-1) }");
-        assertEval(Output.IgnoreWarningContext, "{ as.raw(-1L) }");
-        assertEval(Output.IgnoreWarningContext, "{ as.raw(NA) }");
-        assertEval(Output.IgnoreWarningContext, "{ as.raw(\"test\") }");
+        assertEval("{ as.raw(1+1i) }");
+        assertEval("{ as.raw(-1) }");
+        assertEval("{ as.raw(-1L) }");
+        assertEval("{ as.raw(NA) }");
+        assertEval("{ as.raw(1000L) }");
+        assertEval("{ as.raw(1000) }");
+        assertEval(Output.IgnoreWhitespace, "{ as.raw(10000000000000000) }");
+        assertEval(Output.IgnoreWhitespace, "{ as.raw('test') }");
+        assertEval("{ as.raw('1') }");
+        assertEval("{ as.raw('1000') }");
+        assertEval(Output.IgnoreWhitespace, "{ as.raw('10000000000000000') }");
+        assertEval("{ as.raw(c('1', '2')) }");
+        assertEval("{ as.raw(c('1', '1000')) }");
+        assertEval(Output.IgnoreWhitespace, "{ as.raw(c('10000000000000000', '1000')) }");
+        assertEval(Output.IgnoreWhitespace, "{ as.raw(c('10000000000000000', '1')) }");
         assertEval(Output.IgnoreWarningContext, "{ as.raw(c(1+3i, -2-1i, NA)) }");
-        assertEval(Output.IgnoreWarningContext, "{ as.raw(c(1, -2, 3)) }");
-        assertEval(Output.IgnoreWarningContext, "{ as.raw(c(1,1000,NA)) }");
-        assertEval(Output.IgnoreWarningContext, "{ as.raw(c(1L, -2L, 3L)) }");
-        assertEval(Output.IgnoreWarningContext, "{ as.raw(c(1L, -2L, NA)) }");
-        assertEval(Output.IgnoreWarningContext, "{ as.raw('10000001') }");
-        assertEval(Output.IgnoreWarningContext, "{ as.raw(c('10000001', '42')) }");
+        assertEval(Output.IgnoreWhitespace, "{ as.raw(10000000000000000+1i) }");
+        assertEval("{ as.raw(NA_complex_) }");
+        assertEval(Output.IgnoreWhitespace, "{ as.raw(1000+1i) }");
+        assertEval(Output.IgnoreWhitespace, "{ as.raw(c(10000000000000000+1i, 1+1i)) }");
+        assertEval(Output.IgnoreWhitespace, "{ as.raw(c(NA_complex_, 1+1i)) }");
+        // gnur has a fixed warnign order,
+        // no matter how they are encountered while traversing the vector
+        assertEval(Output.IgnoreWarningMessage, "{ as.raw(c(1000L, 1+1i)) }");
+        assertEval(Output.IgnoreWarningMessage, "{ as.raw(c(1000, 1+1i)) }");
+        assertEval(Output.IgnoreWhitespace, "{ as.raw(c(10000000000000000+1i, 1000+1i, NA_complex_, 1+1i)) }");
+        assertEval("{ as.raw(c(1, -2, 3)) }");
+        assertEval("{ as.raw(c(1,1000,NA)) }");
+        assertEval("{ as.raw(c(1L, -2L, 3L)) }");
+        assertEval("{ as.raw(c(1L, -2L, NA)) }");
         assertEval("{ y <- as.raw(c(5L, 6L)); attr(y, 'someAttr') <- 'someValue'; x <- as.raw(y); x[[1]] <- as.raw(42); y }");
     }
+
+    @Test
+    public void noCopyCheck() {
+        assertEvalFastR("{ x <- as.raw(c(1, 3)); .fastr.identity(x) == .fastr.identity(as.raw(x)); }", "[1] TRUE");
+    }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestMiscBuiltins.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestMiscBuiltins.java
index 846505b5dbf4d8fc8d913bcf5dd911bd65d6f62b..53e851c99ef1a9dc771733f010e73063c70f3a9b 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestMiscBuiltins.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestMiscBuiltins.java
@@ -109,8 +109,8 @@ public class TestMiscBuiltins extends TestBase {
         assertEval("{ x <- 1:3; z <- as.matrix(x); x }");
         assertEval("{ x <- 1:3 ; attr(x,\"my\") <- 10 ; attributes(as.matrix(x)) }");
 
-        assertEval(Output.IgnoreWarningContext, "{ as.complex(as.double(c(1+1i,1+1i))) }");
-        assertEval(Output.IgnoreWarningContext, "{ as.complex(as.raw(c(1+1i,1+1i))) }");
+        assertEval("{ as.complex(as.double(c(1+1i,1+1i))) }");
+        assertEval("{ as.complex(as.raw(c(1+1i,1+1i))) }");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestJavaInterop.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestJavaInterop.java
index 0b61650e7f505ebb35d33f562157e55a96858bbf..0c765ee621c368083deeabf0850b649487d3586a 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestJavaInterop.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestJavaInterop.java
@@ -978,11 +978,11 @@ public class TestJavaInterop extends TestBase {
             if (name.startsWith("fieldStatic") && name.endsWith("Object")) {
                 if (asXXX.equals("as.character") && name.contains("Long")) {
                     assertEvalFastR(Ignored.ImplementationError, expr, getAsXXX(f.get(t), asXXX));
-                } else if ((asXXX.equals("as.double") || asXXX.equals("as.raw")) && (name.contains("String") || name.contains("Char"))) {
+                } else if ((asXXX.equals("as.raw")) && (name.contains("String") || name.contains("Char"))) {
                     assertEvalFastR(Output.IgnoreWarningMessage, expr, getAsXXX(f.get(t), asXXX));
                 } else if (asXXX.equals("as.expression") && (name.contains("Long") || name.contains("Double"))) {
                     assertEvalFastR(Ignored.ImplementationError, expr, getAsXXX(f.get(t), asXXX));
-                } else if (asXXX.equals("as.raw") && (name.contains("Short") || name.contains("Integer") || name.contains("Long") || name.contains("Double") || name.contains("NaN"))) {
+                } else if (asXXX.equals("as.raw") && (name.contains("Long") || name.contains("Double") || name.contains("NaN"))) {
                     assertEvalFastR(Output.IgnoreWarningMessage, expr, getAsXXX(f.get(t), asXXX));
                 } else if (asXXX.equals("as.symbol") && (name.contains("Long") || name.contains("Double") || name.contains("Float"))) {
                     assertEvalFastR(Ignored.ImplementationError, expr, getAsXXX(f.get(t), asXXX));