diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Array.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Array.java
index d6e7259a25514429a9b088b7ee6f21662c796196..31c17451af606214a9552bd2cf6d5a7487a458f8 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Array.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Array.java
@@ -42,7 +42,6 @@ import com.oracle.truffle.r.runtime.data.RIntVector;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RLogicalVector;
 import com.oracle.truffle.r.runtime.data.RNull;
-import com.oracle.truffle.r.runtime.data.RRaw;
 import com.oracle.truffle.r.runtime.data.RRawVector;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RTypedValue;
@@ -54,7 +53,6 @@ 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;
 
 /**
  * The {@code} .Internal part of the {@code array} function. The R code may alter the arguments
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java
index c4fb5330bdcd0ac41c253c49b64fe851285cf1ac..7c29e7beb057ffa40802f9bf1c38f497b40fc028 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java
@@ -28,27 +28,26 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.RDeparse;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
-import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RStringVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 
 @RBuiltin(name = "as.character", kind = PRIMITIVE, parameterNames = {"x", "..."}, dispatch = INTERNAL_GENERIC, behavior = PURE)
 public abstract class AsCharacter extends RBuiltinNode {
 
-    public static AsCharacter create() {
-        return AsCharacterNodeGen.create(null);
-    }
+    private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile();
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.arg("x").mapIf(instanceOf(RList.class).not(), asStringVector());
+        casts.arg("x").mapIf(instanceOf(RAbstractListVector.class).not(), asStringVector());
     }
 
     @Specialization
@@ -58,12 +57,15 @@ public abstract class AsCharacter extends RBuiltinNode {
 
     @Specialization
     protected RAbstractStringVector asCharacter(RAbstractStringVector v) {
-        return v;
+        if (noAttributes.profile(v.getAttributes() == null)) {
+            return v;
+        } else {
+            return (RAbstractStringVector) v.copyDropAttributes();
+        }
     }
 
     @Specialization
-    protected RStringVector asCharacter(Object l) {
-        RList list = (RList) l;
+    protected RStringVector asCharacter(RAbstractListVector list) {
         int len = list.getLength();
         boolean complete = RDataFactory.COMPLETE_VECTOR;
         String[] data = new String[len];
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsComplex.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsComplex.java
index b962a7a88ae0cf3c00cd0ecced191c31f3bb5273..964c8bceec1b1198a9d4b2d4a4cc554e722f92a3 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsComplex.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsComplex.java
@@ -25,72 +25,37 @@ package com.oracle.truffle.r.nodes.builtin.base;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
-import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.nodes.unary.CastComplexNode;
-import com.oracle.truffle.r.nodes.unary.CastComplexNodeGen;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RComplex;
-import com.oracle.truffle.r.runtime.data.RComplexVector;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RNull;
-import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
 
 @RBuiltin(name = "as.complex", kind = PRIMITIVE, parameterNames = {"x", "..."}, behavior = PURE)
 public abstract class AsComplex extends RBuiltinNode {
 
-    @Child private CastComplexNode castComplexNode;
+    private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile();
 
-    private void initCast() {
-        if (castComplexNode == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            castComplexNode = insert(CastComplexNodeGen.create(false, false, false));
-        }
-    }
-
-    @Specialization
-    protected RComplex doComplex(RComplex value) {
-        return value;
-    }
-
-    @Specialization
-    protected RComplex doInt(int value) {
-        initCast();
-        return (RComplex) castComplexNode.executeComplex(value);
-    }
-
-    @Specialization
-    protected RComplex doDouble(double value) {
-        initCast();
-        return (RComplex) castComplexNode.executeComplex(value);
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("x").asComplexVector();
     }
 
     @Specialization
-    protected RComplex doLogical(byte value) {
-        initCast();
-        return (RComplex) castComplexNode.executeComplex(value);
+    protected RAbstractComplexVector asComplex(@SuppressWarnings("unused") RNull n) {
+        return RDataFactory.createEmptyComplexVector();
     }
 
     @Specialization
-    protected RComplex doString(String value) {
-        initCast();
-        return (RComplex) castComplexNode.executeComplex(value);
-    }
-
-    @Specialization
-    protected RComplexVector doNull(@SuppressWarnings("unused") RNull value) {
-        return RDataFactory.createComplexVector(0);
-    }
-
-    @Specialization
-    protected RComplexVector doComplexVector(RComplexVector vector) {
-        return RDataFactory.createComplexVector(vector.getDataCopy(), vector.isComplete());
+    protected RAbstractComplexVector asComplex(RAbstractComplexVector v) {
+        if (noAttributes.profile(v.getAttributes() == null)) {
+            return v;
+        } else {
+            return (RAbstractComplexVector) v.copyDropAttributes();
+        }
     }
 
-    @Specialization
-    protected RComplexVector doIntVector(RAbstractVector vector) {
-        initCast();
-        return (RComplexVector) castComplexNode.executeComplex(vector);
-    }
 }
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 d177ac1281fb04a3f54e792612a17b1cb20149d7..39780bb2a6ad5b9880a96d7d39422154be6673fe 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
@@ -25,84 +25,36 @@ package com.oracle.truffle.r.nodes.builtin.base;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
-import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.nodes.unary.CastDoubleNode;
-import com.oracle.truffle.r.nodes.unary.CastDoubleNodeGen;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
-import com.oracle.truffle.r.runtime.data.RDoubleSequence;
-import com.oracle.truffle.r.runtime.data.RDoubleVector;
-import com.oracle.truffle.r.runtime.data.RIntSequence;
 import com.oracle.truffle.r.runtime.data.RNull;
-import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
 
 @RBuiltin(name = "as.double", aliases = {"as.numeric"}, kind = PRIMITIVE, parameterNames = {"x", "..."}, behavior = PURE)
 public abstract class AsDouble extends RBuiltinNode {
 
-    @Child private CastDoubleNode castDoubleNode;
+    private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile();
 
-    private void initCast() {
-        if (castDoubleNode == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            castDoubleNode = insert(CastDoubleNodeGen.create(false, false, false));
-        }
-    }
-
-    @Specialization
-    protected double asDouble(double value) {
-        return value;
-    }
-
-    @Specialization
-    protected double asDoubleInt(int value) {
-        initCast();
-        return (double) castDoubleNode.executeDouble(value);
-    }
-
-    @Specialization
-    protected double asDouble(byte value) {
-        initCast();
-        return (double) castDoubleNode.executeDouble(value);
-    }
-
-    @Specialization
-    protected double asDouble(RComplex value) {
-        initCast();
-        return (double) castDoubleNode.executeDouble(value);
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("x").asDoubleVector();
     }
 
     @Specialization
-    protected double asDouble(String value) {
-        initCast();
-        return (double) castDoubleNode.executeDouble(value);
+    protected RAbstractDoubleVector asDouble(@SuppressWarnings("unused") RNull n) {
+        return RDataFactory.createEmptyDoubleVector();
     }
 
     @Specialization
-    protected RDoubleVector asDouble(@SuppressWarnings("unused") RNull vector) {
-        return RDataFactory.createDoubleVector(0);
-    }
-
-    @Specialization
-    protected RDoubleVector asDouble(RDoubleVector vector) {
-        return RDataFactory.createDoubleVector(vector.getDataCopy(), vector.isComplete());
-    }
-
-    @Specialization
-    protected RDoubleSequence asDouble(RDoubleSequence sequence) {
-        return sequence;
-    }
-
-    @Specialization
-    protected RDoubleSequence asDouble(RIntSequence sequence) {
-        return RDataFactory.createDoubleSequence(sequence.getStart(), sequence.getStride(), sequence.getLength());
-    }
-
-    @Specialization
-    protected RDoubleVector asDouble(RAbstractVector vector) {
-        initCast();
-        return (RDoubleVector) castDoubleNode.executeDouble(vector);
+    protected RAbstractDoubleVector asDouble(RAbstractDoubleVector v) {
+        if (noAttributes.profile(v.getAttributes() == null)) {
+            return v;
+        } else {
+            return (RAbstractDoubleVector) v.copyDropAttributes();
+        }
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsInteger.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsInteger.java
index 0f64433f130c212751add7f60c81ba9a70816ee7..c6a78959fa4142db09ac12146080ef1d05d2f176 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsInteger.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsInteger.java
@@ -25,92 +25,43 @@ package com.oracle.truffle.r.nodes.builtin.base;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
-import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.nodes.unary.CastIntegerNode;
-import com.oracle.truffle.r.nodes.unary.CastIntegerNodeGen;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.conn.RConnection;
-import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
-import com.oracle.truffle.r.runtime.data.RIntSequence;
-import com.oracle.truffle.r.runtime.data.RIntVector;
 import com.oracle.truffle.r.runtime.data.RNull;
-import com.oracle.truffle.r.runtime.data.RRaw;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 
 @RBuiltin(name = "as.integer", kind = PRIMITIVE, parameterNames = {"x", "..."}, behavior = PURE)
 public abstract class AsInteger extends RBuiltinNode {
 
-    @Child private CastIntegerNode castIntNode;
+    private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile();
 
-    private void initCast() {
-        if (castIntNode == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            castIntNode = insert(CastIntegerNodeGen.create(false, false, false));
-        }
-    }
-
-    @Specialization
-    protected int asInteger(int value) {
-        return value;
-    }
-
-    @Specialization
-    protected int asInteger(double value) {
-        initCast();
-        return (int) castIntNode.executeInt(value);
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("x").asIntegerVector();
     }
 
     @Specialization
-    protected int asInteger(byte value) {
-        initCast();
-        return (int) castIntNode.executeInt(value);
-    }
-
-    @Specialization
-    protected int asInteger(RComplex value) {
-        initCast();
-        return (int) castIntNode.executeInt(value);
-    }
-
-    @Specialization
-    protected int asInteger(RRaw value) {
-        initCast();
-        return (int) castIntNode.executeInt(value);
-    }
-
-    @Specialization
-    protected int asInteger(String value) {
-        initCast();
-        return (int) castIntNode.executeInt(value);
-    }
-
-    @Specialization
-    protected RIntVector asInteger(@SuppressWarnings("unused") RNull value) {
+    protected RAbstractIntVector asInteger(@SuppressWarnings("unused") RNull n) {
         return RDataFactory.createEmptyIntVector();
     }
 
     @Specialization
-    protected RIntVector asInteger(RIntVector vector) {
-        return RDataFactory.createIntVector(vector.getDataCopy(), vector.isComplete());
-    }
-
-    @Specialization
-    protected RIntVector asInteger(RIntSequence sequence) {
-        return (RIntVector) sequence.createVector();
-    }
-
-    @Specialization
-    protected RAbstractIntVector asInteger(RAbstractVector vector) {
-        initCast();
-        return (RAbstractIntVector) castIntNode.executeInt(vector);
+    protected RAbstractIntVector asInteger(RAbstractIntVector v) {
+        if (noAttributes.profile(v.getAttributes() == null)) {
+            return v;
+        } else {
+            return (RAbstractIntVector) v.copyDropAttributes();
+        }
     }
 
     @Specialization
     protected int asInteger(RConnection conn) {
         return conn.getDescriptor();
     }
+
 }
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 640ce0cc091da04dbb221a7b92356d03ed43c468..d92ed1e1a988451b5bbc6501fb6d855bcb10d436 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
@@ -25,76 +25,36 @@ package com.oracle.truffle.r.nodes.builtin.base;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
-import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.nodes.unary.CastLogicalNode;
-import com.oracle.truffle.r.nodes.unary.CastLogicalNodeGen;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
-import com.oracle.truffle.r.runtime.data.RLogicalVector;
 import com.oracle.truffle.r.runtime.data.RNull;
-import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
+import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
 
 @RBuiltin(name = "as.logical", kind = PRIMITIVE, parameterNames = {"x", "..."}, behavior = PURE)
 public abstract class AsLogical extends RBuiltinNode {
 
-    @Child private CastLogicalNode castLogicalNode;
+    private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile();
 
-    private byte castLogical(Object o) {
-        if (castLogicalNode == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            castLogicalNode = insert(CastLogicalNodeGen.create(false, false, false));
-        }
-        return (byte) castLogicalNode.execute(o);
-    }
-
-    private RLogicalVector castLogicalVector(Object o) {
-        if (castLogicalNode == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            castLogicalNode = insert(CastLogicalNodeGen.create(false, false, false));
-        }
-        return (RLogicalVector) castLogicalNode.execute(o);
-    }
-
-    @Specialization
-    protected byte asLogical(byte value) {
-        return value;
-    }
-
-    @Specialization
-    protected byte asLogical(int value) {
-        return castLogical(value);
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("x").asLogicalVector();
     }
 
     @Specialization
-    protected byte asLogical(double value) {
-        return castLogical(value);
+    protected RAbstractLogicalVector asLogicaleger(@SuppressWarnings("unused") RNull n) {
+        return RDataFactory.createEmptyLogicalVector();
     }
 
     @Specialization
-    protected byte asLogical(RComplex value) {
-        return castLogical(value);
-    }
-
-    @Specialization
-    protected byte asLogical(String value) {
-        return castLogical(value);
-    }
-
-    @Specialization
-    protected RLogicalVector asLogical(@SuppressWarnings("unused") RNull vector) {
-        return RDataFactory.createLogicalVector(0);
-    }
-
-    @Specialization
-    protected RLogicalVector asLogical(RLogicalVector vector) {
-        return RDataFactory.createLogicalVector(vector.getDataCopy(), vector.isComplete());
-    }
-
-    @Specialization
-    protected RLogicalVector asLogical(RAbstractContainer container) {
-        return castLogicalVector(container);
+    protected RAbstractLogicalVector asLogicaleger(RAbstractLogicalVector v) {
+        if (noAttributes.profile(v.getAttributes() == null)) {
+            return v;
+        } else {
+            return (RAbstractLogicalVector) v.copyDropAttributes();
+        }
     }
 }
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 4d03ae68c19173386b5d5fe3bd0fc8f2c07f16f0..1300bfa38b2addff31d700096f857731d464eda8 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
@@ -25,93 +25,36 @@ package com.oracle.truffle.r.nodes.builtin.base;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
-import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.profiles.ConditionProfile;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
-import com.oracle.truffle.r.nodes.unary.CastIntegerNode;
-import com.oracle.truffle.r.nodes.unary.CastRawNode;
-import com.oracle.truffle.r.nodes.unary.CastRawNodeGen;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
-import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
-import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RNull;
-import com.oracle.truffle.r.runtime.data.RRaw;
-import com.oracle.truffle.r.runtime.data.RRawVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
 
 @RBuiltin(name = "as.raw", kind = PRIMITIVE, parameterNames = {"x"}, behavior = PURE)
 public abstract class AsRaw extends RBuiltinNode {
 
-    @Child private CastIntegerNode castInteger;
-    @Child private CastRawNode castRawNode;
+    private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile();
 
-    private void initCast() {
-        if (castRawNode == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            castRawNode = insert(CastRawNodeGen.create(false, false, false));
-        }
-    }
-
-    @Specialization
-    protected RRawVector asRaw(@SuppressWarnings("unused") RNull vector) {
-        return RDataFactory.createRawVector(0);
-    }
-
-    @Specialization
-    protected RRaw asRaw(byte logical) {
-        initCast();
-        return (RRaw) castRawNode.executeRaw(logical);
-    }
-
-    @Specialization
-    protected RRaw asRaw(int value) {
-        initCast();
-        return (RRaw) castRawNode.executeRaw(value);
-    }
-
-    @Specialization
-    protected RRaw asRaw(double value) {
-        initCast();
-        return (RRaw) castRawNode.executeRaw(value);
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("x").asRawVector();
     }
 
     @Specialization
-    protected RRaw asRaw(RComplex value) {
-        initCast();
-        return (RRaw) castRawNode.executeRaw(value);
+    protected RAbstractRawVector asRaw(@SuppressWarnings("unused") RNull n) {
+        return RDataFactory.createEmptyRawVector();
     }
 
     @Specialization
-    protected RRaw asRaw(String value) {
-        initCast();
-        return (RRaw) castRawNode.executeRaw(value);
-    }
-
-    @Specialization
-    protected RRaw asRaw(RRaw value) {
-        return value;
-    }
-
-    @Specialization
-    protected RRawVector asRaw(RRawVector value) {
-        return RDataFactory.createRawVector(value.getDataCopy());
-    }
-
-    @Specialization
-    protected RRawVector asRaw(RList value) {
-        initCast();
-        int length = value.getLength();
-        RRawVector result = RDataFactory.createRawVector(length);
-        for (int i = 0; i < length; i++) {
-            result.updateDataAt(i, (RRaw) castRawNode.executeRaw(value.getDataAt(i)));
+    protected RAbstractRawVector asRaw(RAbstractRawVector v) {
+        if (noAttributes.profile(v.getAttributes() == null)) {
+            return v;
+        } else {
+            return (RAbstractRawVector) v.copyDropAttributes();
         }
-        return result;
-    }
-
-    @Specialization
-    protected RRawVector asRaw(RAbstractVector vector) {
-        initCast();
-        return (RRawVector) castRawNode.executeRaw(vector);
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
index 77e3ff3f897bc2a370e4ddbfe8e3e31757d91254..0b2ccbc14eccadf9815d60c7143b773489712d2e 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
@@ -34,6 +34,7 @@ import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.dsl.TypeSystemReference;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
@@ -57,6 +58,7 @@ import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.data.RAttributable;
 import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
@@ -118,41 +120,54 @@ public abstract class AsVector extends RBuiltinNode {
         public abstract Object execute(Object x, String mode);
 
         private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
+        private final BranchProfile hasAttributes = BranchProfile.create();
+
+        private Object dropAttributesIfNeeded(Object o) {
+            Object res = o;
+            if (res instanceof RAttributable && ((RAttributable) res).getAttributes() != null) {
+                // the assertion should hold because of how cast works and it's only used for
+                // vectors (as per as.vector docs)
+                assert res instanceof RAbstractVector;
+                hasAttributes.enter();
+                res = ((RAbstractVector) res).copyDropAttributes();
+            }
+            return res;
+        }
 
         @Specialization(guards = "castToString(mode)")
         protected Object asVectorString(Object x, @SuppressWarnings("unused") String mode, //
                         @Cached("createNonPreserving()") CastStringNode cast) {
-            return cast.execute(x);
+            return dropAttributesIfNeeded(cast.execute(x));
         }
 
         @Specialization(guards = "castToInt(x, mode)")
         protected Object asVectorInt(RAbstractContainer x, @SuppressWarnings("unused") String mode, //
                         @Cached("createNonPreserving()") CastIntegerNode cast) {
-            return cast.execute(x);
+            return dropAttributesIfNeeded(cast.execute(x));
         }
 
         @Specialization(guards = "castToDouble(x, mode)")
         protected Object asVectorDouble(RAbstractContainer x, @SuppressWarnings("unused") String mode, //
                         @Cached("createNonPreserving()") CastDoubleNode cast) {
-            return cast.execute(x);
+            return dropAttributesIfNeeded(cast.execute(x));
         }
 
         @Specialization(guards = "castToComplex(x, mode)")
         protected Object asVectorComplex(RAbstractContainer x, @SuppressWarnings("unused") String mode, //
                         @Cached("createNonPreserving()") CastComplexNode cast) {
-            return cast.execute(x);
+            return dropAttributesIfNeeded(cast.execute(x));
         }
 
         @Specialization(guards = "castToLogical(x, mode)")
         protected Object asVectorLogical(RAbstractContainer x, @SuppressWarnings("unused") String mode, //
                         @Cached("createNonPreserving()") CastLogicalNode cast) {
-            return cast.execute(x);
+            return dropAttributesIfNeeded(cast.execute(x));
         }
 
         @Specialization(guards = "castToRaw(x, mode)")
         protected Object asVectorRaw(RAbstractContainer x, @SuppressWarnings("unused") String mode, //
                         @Cached("createNonPreserving()") CastRawNode cast) {
-            return cast.execute(x);
+            return dropAttributesIfNeeded(cast.execute(x));
         }
 
         protected static CastListNode createListCast() {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java
index b02a20b452417ce0cc22054770b83dee658b682a..06b412f7ff1036479ec6735517bce5f188b53a8a 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java
@@ -32,6 +32,7 @@ import java.util.ArrayList;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RInternalError;
@@ -56,6 +57,13 @@ public class DynLoadFunctions {
 
     @RBuiltin(name = "dyn.load", visibility = OFF, kind = INTERNAL, parameterNames = {"lib", "local", "now", "unused"}, behavior = COMPLEX)
     public abstract static class DynLoad extends RBuiltinNode {
+
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            // TODO: not sure if the behavior is 100% compliant
+            casts.arg("now").asLogicalVector().findFirst();
+        }
+
         @Specialization
         @TruffleBoundary
         protected RList doDynLoad(RAbstractStringVector libVec, RAbstractLogicalVector localVec, byte now, @SuppressWarnings("unused") String unused) {
@@ -147,6 +155,12 @@ public class DynLoadFunctions {
     @RBuiltin(name = "getSymbolInfo", kind = INTERNAL, parameterNames = {"symbol", "package", "withReg"}, behavior = READS_STATE)
     public abstract static class GetSymbolInfo extends RBuiltinNode {
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            // TODO: not sure if the behavior is 100% compliant
+            casts.arg("withReg").asLogicalVector().findFirst();
+        }
+
         @Specialization
         @TruffleBoundary
         protected Object getSymbolInfo(RAbstractStringVector symbolVec, String packageName, byte withReg) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
index 95b36bcc700b122afd4a35a94c4be94e0908b7e9..899f34632cfbc9570f8ca59d055e8179bf9bf4cc 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
@@ -362,7 +362,9 @@ public class HiddenInternalFunctions {
 
         @Override
         protected void createCasts(CastBuilder casts) {
-            casts.toInteger(2).toInteger(3);
+            // TODO: not sure if the behavior is 100% compliant
+            casts.arg("ascii").asIntegerVector().findFirst();
+            casts.arg("compsxp").asIntegerVector().findFirst();
         }
 
         @Specialization
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java
index 699b9fe4219a49ab2dd8e3b8977e5dacf4125e7f..fef9305da7c55355d10060f099bf09024f8e2a32 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java
@@ -77,7 +77,7 @@ public abstract class Paste extends RBuiltinNode {
         } else if (ret == RNull.instance) {
             return RDataFactory.createEmptyStringVector();
         } else {
-            return (RStringVector) ret;
+            return (RStringVector) ((RStringVector) ret).copyDropAttributes();
         }
     }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtoi.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtoi.java
index 759459f1f09f5aec597075d536305be5d084bd9e..cbca860f401407a3c234193721821ec4f3a043b1 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtoi.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtoi.java
@@ -27,6 +27,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
@@ -37,6 +38,13 @@ import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
 
 @RBuiltin(name = "strtoi", kind = INTERNAL, parameterNames = {"x", "base"}, behavior = PURE)
 public abstract class Strtoi extends RBuiltinNode {
+
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        // TODO: not sure if the behavior is 100% compliant
+        casts.arg("base").asIntegerVector().findFirst();
+    }
+
     @Specialization
     @TruffleBoundary
     protected RIntVector doStrtoi(RAbstractStringVector vec, int baseArg) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java
index d690fced48fa9dd4ebf4d1442f664e27ca4ec12e..764eed17c3384b043879dbbfb4e20e350ad72ecf 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java
@@ -35,7 +35,9 @@ public abstract class Tabulate extends RBuiltinNode {
 
     @Override
     protected void createCasts(CastBuilder casts) {
-        casts.toInteger(1);
+        // TODO: not sure if the behavior is 100% compliant
+        casts.arg("bin").asIntegerVector();
+        casts.arg("nbins").asIntegerVector().findFirst();
     }
 
     @Specialization
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java
index 4010f36ea20ed08601c93d5b0f72456d7b58d100..0313cad4b98aec16177b01b33fe7021ffa3fa6ee 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java
@@ -27,7 +27,6 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
 import java.util.function.BiFunction;
-import java.util.function.Function;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Specialization;
@@ -100,7 +99,7 @@ public abstract class ToLowerOrUpper {
         }
 
         @TruffleBoundary
-        private static String processElement(String value, int i) {
+        private static String processElement(String value, @SuppressWarnings("unused") int i) {
             return value.toLowerCase();
         }
 
@@ -126,7 +125,7 @@ public abstract class ToLowerOrUpper {
         }
 
         @TruffleBoundary
-        private static String processElement(String value, int i) {
+        private static String processElement(String value, @SuppressWarnings("unused") int i) {
             return value.toUpperCase();
         }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateNames.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateNames.java
index fd9b979a7964a6a0b0532c753bfff0a6e8d5c3f4..93587752d7411f1f797a66f85692de3cc0bf4dbf 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateNames.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateNames.java
@@ -69,7 +69,7 @@ public abstract class UpdateNames extends RBuiltinNode {
         if (newNames instanceof String) {
             stringVector = RDataFactory.createStringVector((String) newNames);
         } else {
-            stringVector = (RStringVector) ((RAbstractVector) newNames).materialize();
+            stringVector = (RStringVector) ((RAbstractVector) newNames).materialize().copyDropAttributes();
         }
         RAbstractContainer result = (RAbstractContainer) container.getNonShared();
         if (stringVector.getLength() < result.getLength()) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java
index b267d9521fcbcc765c10b5591a3e3bb734484085..b8dfa18b98a9656c6d2df0059a5589ebf7deda57 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java
@@ -33,11 +33,11 @@ public final class Dqrcf extends RExternalBuiltinNode {
         Object[] argValues = args.getArguments();
         try {
             RAbstractDoubleVector xVec = (RAbstractDoubleVector) argValues[0];
-            int n = (int) argValues[1];
+            int n = argValues[1] instanceof Integer ? (int) argValues[1] : ((RAbstractIntVector) argValues[1]).getDataAt(0);
             RAbstractIntVector k = (RAbstractIntVector) argValues[2];
             RAbstractDoubleVector qrauxVec = (RAbstractDoubleVector) argValues[3];
             RAbstractDoubleVector yVec = (RAbstractDoubleVector) argValues[4];
-            int ny = (int) argValues[5];
+            int ny = argValues[5] instanceof Integer ? (int) argValues[5] : ((RAbstractIntVector) argValues[5]).getDataAt(0);
             RAbstractDoubleVector bVec = (RAbstractDoubleVector) argValues[6];
             RAbstractIntVector infoVec = (RAbstractIntVector) argValues[7];
             double[] x = xVec.materialize().getDataTemp();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java
index 0e8a93f22444ba6bb03f37a69de841eae38e05e4..fb842d465d81c176cdc1f5aeadaab8f3d07326c0 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java
@@ -32,10 +32,10 @@ public final class Dqrdc2 extends RExternalBuiltinNode {
         Object[] argValues = args.getArguments();
         try {
             RAbstractDoubleVector xVec = (RAbstractDoubleVector) argValues[0];
-            int ldx = (int) argValues[1];
-            int n = (int) argValues[2];
-            int p = (int) argValues[3];
-            double tol = (double) argValues[4];
+            int ldx = argValues[1] instanceof Integer ? (int) argValues[1] : ((RAbstractIntVector) argValues[1]).getDataAt(0);
+            int n = argValues[2] instanceof Integer ? (int) argValues[2] : ((RAbstractIntVector) argValues[2]).getDataAt(0);
+            int p = argValues[3] instanceof Integer ? (int) argValues[3] : ((RAbstractIntVector) argValues[3]).getDataAt(0);
+            double tol = argValues[4] instanceof Double ? (double) argValues[4] : ((RAbstractDoubleVector) argValues[4]).getDataAt(0);
             RAbstractIntVector rankVec = (RAbstractIntVector) argValues[5];
             RAbstractDoubleVector qrauxVec = (RAbstractDoubleVector) argValues[6];
             RAbstractIntVector pivotVec = (RAbstractIntVector) argValues[7];
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java
index 681a49131af2005f5d4f01561a6c8388dd4fad56..e9494ac30eb5871ff6f542787dbd6be94370146a 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java
@@ -675,7 +675,8 @@ public class CastBuilderTest {
 
     private void testPipeline(@SuppressWarnings("unused") boolean positiveMustNotBeEmpty) {
         CastNodeSampler<CastNode> sampler = CastNodeSampler.createSampler(cb.getCasts()[0]);
-        Samples<?> samples = sampler.collectSamples();
+        sampler.collectSamples();
+        // Samples<?> samples = sampler.collectSamples();
         //
         // if (positiveMustNotBeEmpty) {
         // Assert.assertFalse(samples.positiveSamples().isEmpty());
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/ArgumentFilterSampler.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/ArgumentFilterSampler.java
index d3a51f559e4c4b4365265c7e451f1cda91118265..979813ce02f49487c5fb8184e851ffc1c7fa4bc7 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/ArgumentFilterSampler.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/ArgumentFilterSampler.java
@@ -232,7 +232,6 @@ public interface ArgumentFilterSampler<T, R> extends ArgumentFilter<T, R> {
                     return ArgumentTypeFilterSampler.this.trueBranchType().and(other.trueBranchType());
                 }
 
-                @SuppressWarnings("cast")
                 @Override
                 public Samples<R> collectSamples(TypeExpr inputType) {
                     Samples<R> thisSamples = ArgumentTypeFilterSampler.this.collectSamples(inputType);
@@ -269,7 +268,6 @@ public interface ArgumentFilterSampler<T, R> extends ArgumentFilter<T, R> {
             return orig.falseBranchType().not();
         }
 
-        @SuppressWarnings("unchecked")
         @Override
         public Samples<Object> collectSamples(TypeExpr inputType) {
             Samples<? extends R> thisSamples = orig.collectSamples(inputType);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java
index b5ce331f08f10e4dc7964a04fb14f590bfe76997..564660b681f2661cfb9902918ce9f6fd945b3422 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java
@@ -30,6 +30,7 @@ import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNodeGen;
 import com.oracle.truffle.r.nodes.builtin.ArgumentFilter.ArgumentTypeFilter;
 import com.oracle.truffle.r.nodes.builtin.ArgumentFilter.ArgumentValueFilter;
+import com.oracle.truffle.r.nodes.unary.CastComplexNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastDoubleBaseNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastDoubleNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastIntegerBaseNodeGen;
@@ -37,6 +38,7 @@ import com.oracle.truffle.r.nodes.unary.CastIntegerNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastLogicalBaseNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastLogicalNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastNode;
+import com.oracle.truffle.r.nodes.unary.CastRawNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastStringBaseNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastStringNodeGen;
 import com.oracle.truffle.r.nodes.unary.CastToAttributableNodeGen;
@@ -136,6 +138,14 @@ public final class CastBuilder {
         return insert(index, CastStringNodeGen.create(preserveNames, dimensionsPreservation, attrPreservation));
     }
 
+    public CastBuilder toComplex(int index) {
+        return insert(index, CastComplexNodeGen.create(false, false, false));
+    }
+
+    public CastBuilder toRaw(int index) {
+        return insert(index, CastRawNodeGen.create(false, false, false));
+    }
+
     public CastBuilder boxPrimitive(int index) {
         return insert(index, BoxPrimitiveNodeGen.create());
     }
@@ -707,6 +717,14 @@ public final class CastBuilder {
             return phaseBuilder -> CastStringNodeGen.create(false, false, false);
         }
 
+        public static <T> Function<ArgCastBuilder<T, ?>, CastNode> asComplexVector() {
+            return phaseBuilder -> CastComplexNodeGen.create(false, false, false);
+        }
+
+        public static <T> Function<ArgCastBuilder<T, ?>, CastNode> asRawVector() {
+            return phaseBuilder -> CastRawNodeGen.create(false, false, false);
+        }
+
         public static <T> Function<ArgCastBuilder<T, ?>, CastNode> asStringVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) {
             return phaseBuilder -> CastStringNodeGen.create(preserveNames, preserveDimensions, preserveAttributes);
         }
@@ -1384,6 +1402,16 @@ public final class CastBuilder {
             return state().factory.newCoercedPhaseBuilder(this, String.class);
         }
 
+        default CoercedPhaseBuilder<RAbstractComplexVector, RComplex> asComplexVector() {
+            state().castBuilder().toComplex(state().index());
+            return state().factory.newCoercedPhaseBuilder(this, RComplex.class);
+        }
+
+        default CoercedPhaseBuilder<RAbstractRawVector, RRaw> asRawVector() {
+            state().castBuilder().toRaw(state().index());
+            return state().factory.newCoercedPhaseBuilder(this, RRaw.class);
+        }
+
         default CoercedPhaseBuilder<RAbstractVector, Object> asVector() {
             state().castBuilder().toVector(state().index());
             return state().factory.newCoercedPhaseBuilder(this, Object.class);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java
index 2e6fae29105ba85c5233d5ed27c7ec804b8173a1..1ff2e13b0783bb648a3e3f246d8722b5a93a46ad 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java
@@ -24,6 +24,7 @@ package com.oracle.truffle.r.nodes.unary;
 
 import java.util.function.IntFunction;
 
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.profiles.BranchProfile;
@@ -34,6 +35,7 @@ import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.data.RComplex;
 import com.oracle.truffle.r.runtime.data.RComplexVector;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
+import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RLogicalVector;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RRaw;
@@ -41,6 +43,7 @@ import com.oracle.truffle.r.runtime.data.RRawVector;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 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.RAbstractVector;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 import com.oracle.truffle.r.runtime.ops.na.NAProfile;
@@ -63,6 +66,16 @@ public abstract class CastComplexNode extends CastBaseNode {
         super(preserveNames, preserveDimensions, preserveAttributes);
     }
 
+    @Child private CastComplexNode recursiveCastComplex;
+
+    private Object castComplexRecursive(Object o) {
+        if (recursiveCastComplex == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            recursiveCastComplex = insert(CastComplexNodeGen.create(preserveNames(), preserveDimensions(), preserveAttributes()));
+        }
+        return recursiveCastComplex.executeComplex(o);
+    }
+
     @Override
     protected final RType getTargetType() {
         return RType.Complex;
@@ -198,6 +211,50 @@ public abstract class CastComplexNode extends CastBaseNode {
         return createResultVector(operand, index -> RDataFactory.createComplex(operand.getDataAt(index).getValue(), 0));
     }
 
+    @Specialization
+    protected RComplexVector doList(RAbstractListVector list) {
+        int length = list.getLength();
+        double[] result = new double[length * 2];
+        boolean seenNA = false;
+        for (int i = 0, j = 0; i < length; i++, j += 2) {
+            Object entry = list.getDataAt(i);
+            if (entry instanceof RList) {
+                result[j] = RRuntime.DOUBLE_NA;
+                result[j + 1] = RRuntime.DOUBLE_NA;
+                seenNA = true;
+            } else {
+                Object castEntry = castComplexRecursive(entry);
+                if (castEntry instanceof RComplex) {
+                    RComplex value = (RComplex) castEntry;
+                    result[j] = value.getRealPart();
+                    result[j + 1] = value.getImaginaryPart();
+                    seenNA = seenNA || RRuntime.isNA(value);
+                } else if (castEntry instanceof RComplexVector) {
+                    RComplexVector complexVector = (RComplexVector) castEntry;
+                    if (complexVector.getLength() == 1) {
+                        RComplex value = complexVector.getDataAt(0);
+                        result[j] = value.getRealPart();
+                        result[j + 1] = value.getImaginaryPart();
+                        seenNA = seenNA || RRuntime.isNA(value);
+                    } else if (complexVector.getLength() == 0) {
+                        result[j] = RRuntime.DOUBLE_NA;
+                        result[j + 1] = RRuntime.DOUBLE_NA;
+                        seenNA = true;
+                    } else {
+                        throw throwCannotCoerceListError("complex");
+                    }
+                } else {
+                    throw throwCannotCoerceListError("complex");
+                }
+            }
+        }
+        RComplexVector ret = RDataFactory.createComplexVector(result, !seenNA);
+        if (preserveAttributes()) {
+            ret.copyRegAttributesFrom(list);
+        }
+        return ret;
+    }
+
     public static CastComplexNode create() {
         return CastComplexNodeGen.create(true, true, true);
     }
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 47459c84f748ba2d2c43a1eaeb17820d77e69ecb..9e5e541a9d2839cd2ac67f88b782a58a864ec385 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
@@ -38,7 +38,9 @@ import com.oracle.truffle.r.runtime.data.RDoubleVector;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RRawVector;
 import com.oracle.truffle.r.runtime.data.RStringVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 
@@ -58,8 +60,8 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
         return recursiveCastDouble.executeDouble(o);
     }
 
-    private RDoubleVector createResultVector(RAbstractVector operand, double[] ddata) {
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), getPreservedDimensions(operand), getPreservedNames(operand));
+    private RDoubleVector vectorCopy(RAbstractContainer operand, double[] data, boolean isComplete) {
+        RDoubleVector ret = RDataFactory.createDoubleVector(data, isComplete, getPreservedDimensions(operand), getPreservedNames(operand));
         preserveDimensionNames(operand, ret);
         if (preserveAttributes()) {
             ret.copyRegAttributesFrom(operand);
@@ -76,12 +78,7 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
             ddata[i] = value;
             seenNA = seenNA || naProfile.isNA(value);
         }
-        RDoubleVector ret = RDataFactory.createDoubleVector(ddata, !seenNA, getPreservedDimensions(operand), getPreservedNames(operand));
-        preserveDimensionNames(operand, ret);
-        if (preserveAttributes()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
+        return vectorCopy(operand, ddata, !seenNA);
     }
 
     @Specialization
@@ -146,7 +143,7 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
             warningBranch.enter();
             RError.warning(this, RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
         }
-        return createResultVector(operand, ddata);
+        return vectorCopy(operand, ddata, naCheck.neverSeenNA());
     }
 
     @Specialization
@@ -160,12 +157,13 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode {
     }
 
     @Specialization
-    protected RDoubleSequence doDoubleSequence(RDoubleSequence operand) {
+    protected RDoubleSequence doDoubleVector(RDoubleSequence operand) {
+        // sequence does not have attributes - nothing to copy or drop
         return operand;
     }
 
     @Specialization
-    protected RDoubleVector doList(RList list) {
+    protected RDoubleVector doList(RAbstractListVector list) {
         int length = list.getLength();
         double[] result = new double[length];
         boolean seenNA = false;
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 60d21ca021724d29ff2cf57c4277b96bf3088208..59245636fa3c80316e0febe0fa94e27645bd9ebe 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
@@ -61,18 +61,24 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode {
     public abstract Object executeInt(Object o);
 
     @Specialization
-    protected RAbstractIntVector doIntVector(RAbstractIntVector operand) {
+    protected RIntVector doIntVector(RIntVector operand) {
+        return operand;
+    }
+
+    @Specialization
+    protected RIntSequence doIntVector(RIntSequence operand) {
+        // sequence does not have attributes - nothing to copy or drop
         return operand;
     }
 
     @Specialization
     protected RIntSequence doDoubleSequence(RDoubleSequence operand) {
-        naCheck.enable(operand);
-        return RDataFactory.createIntSequence(naCheck.convertDoubleToInt(operand.getStart()), naCheck.convertDoubleToInt(operand.getStride()), operand.getLength());
+        // start and stride cannot be NA so no point checking
+        return RDataFactory.createIntSequence(RRuntime.double2intNoCheck(operand.getStart()), RRuntime.double2intNoCheck(operand.getStride()), operand.getLength());
     }
 
-    private RIntVector createResultVector(RAbstractVector operand, int[] idata) {
-        RIntVector ret = RDataFactory.createIntVector(idata, naCheck.neverSeenNA(), getPreservedDimensions(operand), getPreservedNames(operand));
+    private RIntVector vectorCopy(RAbstractVector operand, int[] idata, boolean isComplete) {
+        RIntVector ret = RDataFactory.createIntVector(idata, isComplete, getPreservedDimensions(operand), getPreservedNames(operand));
         preserveDimensionNames(operand, ret);
         if (preserveAttributes()) {
             ret.copyRegAttributesFrom(operand);
@@ -94,12 +100,7 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode {
             idata[i] = value;
             seenNA = seenNA || naProfile.isNA(value);
         }
-        RIntVector ret = RDataFactory.createIntVector(idata, !seenNA, getPreservedDimensions(operand), getPreservedNames(operand));
-        preserveDimensionNames(operand, ret);
-        if (preserveAttributes()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
+        return vectorCopy(operand, idata, !seenNA);
     }
 
     @Specialization
@@ -119,7 +120,7 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode {
             warningBranch.enter();
             RError.warning(this, RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION);
         }
-        return createResultVector(operand, idata);
+        return vectorCopy(operand, idata, naCheck.neverSeenNA());
     }
 
     @Specialization
@@ -150,12 +151,7 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode {
         if (warning) {
             RError.warning(this, RError.Message.NA_INTRODUCED_COERCION);
         }
-        RIntVector ret = RDataFactory.createIntVector(idata, !seenNA, getPreservedDimensions(operand), getPreservedNames(operand));
-        preserveDimensionNames(operand, ret);
-        if (preserveAttributes()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
+        return vectorCopy(operand, idata, !seenNA);
     }
 
     @Specialization
@@ -166,7 +162,7 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode {
     @Specialization
     protected RIntVector doDoubleVector(RAbstractDoubleVector operand) {
         naCheck.enable(operand);
-        return createResultVector(operand, naCheck.convertDoubleVectorToIntData(operand));
+        return vectorCopy(operand, naCheck.convertDoubleVectorToIntData(operand), naCheck.neverSeenNA());
     }
 
     @Specialization
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 b7eac7f903810077889f3957e746be082c3a64c6..bb333f788f9fe878b320be956239f66f7cf84399 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
@@ -39,6 +39,7 @@ import com.oracle.truffle.r.runtime.data.RRawVector;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 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.RAbstractVector;
 import com.oracle.truffle.r.runtime.ops.na.NAProfile;
 
@@ -79,6 +80,15 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode {
         byte apply(int value);
     }
 
+    private RLogicalVector vectorCopy(RAbstractVector operand, byte[] bdata, boolean isComplete) {
+        RLogicalVector ret = RDataFactory.createLogicalVector(bdata, isComplete, getPreservedDimensions(operand), getPreservedNames(operand));
+        preserveDimensionNames(operand, ret);
+        if (preserveAttributes()) {
+            ret.copyRegAttributesFrom(operand);
+        }
+        return ret;
+    }
+
     private RLogicalVector createResultVector(RAbstractVector operand, IntToByteFunction elementFunction) {
         naCheck.enable(operand);
         byte[] bdata = new byte[operand.getLength()];
@@ -88,12 +98,7 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode {
             bdata[i] = value;
             seenNA = seenNA || naProfile.isNA(value);
         }
-        RLogicalVector ret = RDataFactory.createLogicalVector(bdata, !seenNA, getPreservedDimensions(operand), getPreservedNames(operand));
-        preserveDimensionNames(operand, ret);
-        if (preserveAttributes()) {
-            ret.copyRegAttributesFrom(operand);
-        }
-        return ret;
+        return vectorCopy(operand, bdata, !seenNA);
     }
 
     @Specialization
@@ -134,7 +139,7 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode {
     }
 
     @Specialization
-    protected RLogicalVector doList(RList list) {
+    protected RLogicalVector doList(RAbstractListVector list) {
         int length = list.getLength();
         byte[] result = new byte[length];
         boolean seenNA = false;
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 c4216503fa42031bb450494e4ca88ffeb4c3fad3..69d13990142a7dcd8d52515c28c579f65576df7a 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
@@ -22,6 +22,7 @@
  */
 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.Specialization;
 import com.oracle.truffle.api.profiles.BranchProfile;
@@ -39,6 +40,7 @@ import com.oracle.truffle.r.runtime.data.RRawVector;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 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.RAbstractVector;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 import com.oracle.truffle.r.runtime.ops.na.NAProfile;
@@ -52,11 +54,21 @@ public abstract class CastRawNode extends CastBaseNode {
         super(preserveNames, preserveDimensions, preserveAttributes);
     }
 
+    @Child private CastRawNode recursiveCastRaw;
+
     @Override
     protected final RType getTargetType() {
         return RType.Raw;
     }
 
+    protected Object castRawRecursive(Object o) {
+        if (recursiveCastRaw == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            recursiveCastRaw = insert(CastRawNodeGen.create(preserveNames(), preserveDimensions(), preserveAttributes()));
+        }
+        return recursiveCastRaw.executeRaw(o);
+    }
+
     public abstract Object executeRaw(int o);
 
     public abstract Object executeRaw(double o);
@@ -135,7 +147,7 @@ public abstract class CastRawNode extends CastBaseNode {
         return RRaw.valueOf((byte) intRawValue);
     }
 
-    private RRawVector createResultVector(RAbstractVector operand, byte[] bdata) {
+    private RRawVector vectorCopy(RAbstractVector operand, byte[] bdata) {
         RRawVector ret = RDataFactory.createRawVector(bdata, getPreservedDimensions(operand), getPreservedNames(operand));
         preserveDimensionNames(operand, ret);
         if (preserveAttributes()) {
@@ -162,7 +174,7 @@ public abstract class CastRawNode extends CastBaseNode {
         if (warning) {
             RError.warning(this, RError.Message.OUT_OF_RANGE);
         }
-        return createResultVector(operand, bdata);
+        return vectorCopy(operand, bdata);
     }
 
     @Specialization
@@ -182,7 +194,7 @@ public abstract class CastRawNode extends CastBaseNode {
         if (warning) {
             RError.warning(this, RError.Message.OUT_OF_RANGE);
         }
-        return createResultVector(operand, bdata);
+        return vectorCopy(operand, bdata);
     }
 
     @Specialization
@@ -222,7 +234,7 @@ public abstract class CastRawNode extends CastBaseNode {
         if (outOfRangeWarning) {
             RError.warning(this, RError.Message.OUT_OF_RANGE);
         }
-        return createResultVector(operand, bdata);
+        return vectorCopy(operand, bdata);
     }
 
     @Specialization
@@ -250,7 +262,7 @@ public abstract class CastRawNode extends CastBaseNode {
         if (outOfRangeWarning) {
             RError.warning(this, RError.Message.OUT_OF_RANGE);
         }
-        return createResultVector(operand, bdata);
+        return vectorCopy(operand, bdata);
     }
 
     @Specialization
@@ -271,7 +283,7 @@ public abstract class CastRawNode extends CastBaseNode {
         if (warning) {
             RError.warning(this, RError.Message.OUT_OF_RANGE);
         }
-        return createResultVector(operand, bdata);
+        return vectorCopy(operand, bdata);
     }
 
     @Specialization
@@ -279,6 +291,16 @@ public abstract class CastRawNode extends CastBaseNode {
         return operand;
     }
 
+    @Specialization
+    protected RRawVector doList(RAbstractListVector value) {
+        int length = value.getLength();
+        RRawVector result = RDataFactory.createRawVector(length);
+        for (int i = 0; i < length; i++) {
+            result.updateDataAt(i, (RRaw) castRawRecursive(value.getDataAt(i)));
+        }
+        return result;
+    }
+
     public static CastRawNode createNonPreserving() {
         return CastRawNodeGen.create(false, false, false);
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java
index d416956e4a2689e6f5f1098a9b7a4de604697d56..53e23e6e8be1b17af91843b85c673e5d2b31b082 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java
@@ -61,11 +61,7 @@ public abstract class CastStringNode extends CastStringBaseNode {
 
     @Specialization
     protected RStringVector doStringVector(RStringVector vector) {
-        if (preserveAttributes() && preserveDimensions() && preserveNames()) {
-            return vector;
-        } else {
-            return vectorCopy(vector, vector.getDataCopy());
-        }
+        return vector;
     }
 
     @Specialization
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
index 7a1944f3ea0fffa3b0f70da0dc5bc55795507a71..d2f1b99c455dd2b9c2fb9dd0801f9a8fd92ea978 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
@@ -273,6 +273,12 @@ public class RPairList extends RSharingAttributeStorage implements RAbstractCont
             result = (RPairList) result.cdr;
             original = origList.cdr;
         }
+        if (getAttributes() != null) {
+            RAttributes newAttributes = result.initAttributes();
+            for (RAttribute attr : getAttributes()) {
+                newAttributes.put(attr.getName(), attr.getValue());
+            }
+        }
         return result;
     }
 
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 ea9e318c809ae60051f718f3956f08ed1b815ae1..01e3fcd48ae14532a5137cb0329f0b4184b4e46e 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
@@ -5578,6 +5578,20 @@ NAs introduced by coercion
 #{ as.complex(c(0/0, 0/0)) }
 [1] NA NA
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_ascomplex.testAsComplex
+#{ as.complex(list("foo")) }
+[1] NA
+Warning message:
+NAs introduced by coercion
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_ascomplex.testAsComplex
+#{ as.complex(list(42)) }
+[1] 42+0i
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_ascomplex.testAsComplex
+#{ as.complex(list(NULL)) }
+Error: (list) object cannot be coerced to type 'complex'
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_ascomplex.testAsComplex
 #{ x<-c(a=1.1, b=2.2); dim(x)<-c(1,2); attr(x, "foo")<-"foo"; y<-as.complex(x); attributes(y) }
 NULL
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 bdd5b4596b80bf4a7e1a0946cb8cc34723925f20..5de58ac5216bb0d7f4864cc708a62889c1dc00bd 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
@@ -96,5 +96,9 @@ public class TestBuiltin_ascomplex extends TestBase {
         assertEval(Ignored.Unknown, "{ as.complex(\"-.1e10+5i\") }");
         assertEval(Ignored.Unknown, "{ as.complex(\"1e-2+3i\") }");
         assertEval(Ignored.Unknown, "{ as.complex(\"+.1e+2-3i\") }");
+
+        assertEval("{ as.complex(list(42)) }");
+        assertEval(Output.IgnoreErrorContext, "{ as.complex(list(NULL)) }");
+        assertEval(Output.IgnoreWarningContext, "{ as.complex(list(\"foo\")) }");
     }
 }