diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/WriteTable.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/WriteTable.java
index 2142b56585aa19571ba600037f19b93d99ada053..0565887ef245b76273e32b4221d709b9a412a143 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/WriteTable.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/WriteTable.java
@@ -46,12 +46,12 @@ public final class WriteTable extends RExternalBuiltinNode {
                     throws IOException, IllegalArgumentException {
         String tmp = null;
         if (RRuntime.hasRClass(xx, RRuntime.CLASS_DATA_FRAME)) {
-            executeDataFrame(con, (RVector) xx, nr, nc, rnames, csep, ceol, cna, cdec, qmethod, quoteCol, quoteRn);
+            executeDataFrame(con, (RVector<?>) xx, nr, nc, rnames, csep, ceol, cna, cdec, qmethod, quoteCol, quoteRn);
         } else { /* A matrix */
 
             // if (!isVectorAtomic(x))
             // UNIMPLEMENTED_TYPE("write.table, matrix method", x);
-            RVector x = (RVector) xx;
+            RVector<?> x = (RVector<?>) xx;
             /* quick integrity check */
             if (x.getLength() != nr * nc) {
                 throw new IllegalArgumentException("corrupt matrix -- dims not not match length");
@@ -84,7 +84,7 @@ public final class WriteTable extends RExternalBuiltinNode {
         return RNull.instance;
     }
 
-    private static void executeDataFrame(RConnection con, RVector x, int nr, int nc, Object rnames, String csep, String ceol, String cna, char cdec, boolean qmethod, boolean[] quoteCol,
+    private static void executeDataFrame(RConnection con, RVector<?> x, int nr, int nc, Object rnames, String csep, String ceol, String cna, char cdec, boolean qmethod, boolean[] quoteCol,
                     boolean quoteRn)
                     throws IOException {
         String tmp;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java
index a6cc8d2f64441a99abe144cc1b0c4dd40ebc939b..41b81cd7d5f17ddbdb85309114d67f0361492c58 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java
@@ -68,7 +68,7 @@ public abstract class APerm extends RBuiltinNode {
         int[] dim = vector.getDimensions();
         final int diml = dim.length;
 
-        RVector result = vector.createEmptySameType(vector.getLength(), vector.isComplete());
+        RVector<?> result = vector.createEmptySameType(vector.getLength(), vector.isComplete());
 
         if (mustResize.profile(resize == RRuntime.LOGICAL_TRUE)) {
             int[] pDim = new int[diml];
@@ -111,7 +111,7 @@ public abstract class APerm extends RBuiltinNode {
         int[] posV = new int[dim.length];
         int[] pDim = applyPermute(dim, perm, false);
 
-        RVector result = vector.createEmptySameType(vector.getLength(), vector.isComplete());
+        RVector<?> result = vector.createEmptySameType(vector.getLength(), vector.isComplete());
 
         result.setDimensions(resize == RRuntime.LOGICAL_TRUE ? pDim : dim);
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java
index 4801f2931bbc2a46779c038660c264e66593797e..24230ab782dd9c5f20a36b003f41380a6acb2c35 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java
@@ -445,18 +445,18 @@ public abstract class Bind extends RBaseNode {
             dimNamesB = RDataFactory.createStringVector(names, RDataFactory.COMPLETE_VECTOR);
         }
 
-        RVector res = (RVector) vec.copyWithNewDimensions(dims);
+        RVector<?> res = (RVector<?>) vec.copyWithNewDimensions(dims);
         res.setDimNames(RDataFactory.createList(type == BindType.cbind ? new Object[]{dimNamesA, dimNamesB} : new Object[]{dimNamesB, dimNamesA}));
         res.copyRegAttributesFrom(vec);
         return res;
     }
 
-    public RVector genericCBind(RArgsValuesAndNames promiseArgs, RAbstractVector[] vectors, boolean complete, String[] vecNames, boolean vecNamesComplete, int deparseLevel) {
+    public RVector<?> genericCBind(RArgsValuesAndNames promiseArgs, RAbstractVector[] vectors, boolean complete, String[] vecNames, boolean vecNamesComplete, int deparseLevel) {
 
         int[] resultDimensions = new int[2];
         int[] secondDims = new int[vectors.length];
         boolean notEqualRows = getResultDimensions(vectors, resultDimensions, secondDims);
-        RVector result = resultProfile.profile(vectors[0].createEmptySameType(resultDimensions[0] * resultDimensions[1], complete));
+        RVector<?> result = resultProfile.profile(vectors[0].createEmptySameType(resultDimensions[0] * resultDimensions[1], complete));
 
         int ind = 0;
         Object rowDimResultNames = RNull.instance;
@@ -531,12 +531,12 @@ public abstract class Bind extends RBaseNode {
         }
     }
 
-    public RVector genericRBind(RArgsValuesAndNames promiseArgs, RAbstractVector[] vectors, boolean complete, String[] vecNames, boolean vecNamesComplete, int deparseLevel) {
+    public RVector<?> genericRBind(RArgsValuesAndNames promiseArgs, RAbstractVector[] vectors, boolean complete, String[] vecNames, boolean vecNamesComplete, int deparseLevel) {
 
         int[] resultDimensions = new int[2];
         int[] firstDims = new int[vectors.length];
         boolean notEqualColumns = getResultDimensions(vectors, resultDimensions, firstDims);
-        RVector result = resultProfile.profile(vectors[0].createEmptySameType(resultDimensions[0] * resultDimensions[1], complete));
+        RVector<?> result = resultProfile.profile(vectors[0].createEmptySameType(resultDimensions[0] * resultDimensions[1], complete));
 
         Object colDimResultNames = RNull.instance;
         String[] rowDimNamesArray = new String[resultDimensions[0]];
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java
index 90f3be78349a430b590e49655c4e7b52dc4f7957..09f63d4ef28b36e3b1e0926fcbc68c2eaec598ea 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java
@@ -137,7 +137,7 @@ public abstract class Combine extends RBuiltinNode {
         RStringVector namesVector = hasNamesProfile.profile(signatureHasNames || hasNames(elements)) ? foldNames(naNameBranch, naNameCheck, elements, size, cachedSignature) : null;
 
         // get the actual contents of the result
-        RVector result = foldContents(cachedPrecedence, elements, size, namesVector);
+        RVector<?> result = foldContents(cachedPrecedence, elements, size, namesVector);
 
         RNode.reportWork(this, size);
 
@@ -244,8 +244,8 @@ public abstract class Combine extends RBuiltinNode {
     }
 
     @ExplodeLoop
-    private RVector foldContents(int cachedPrecedence, Object[] elements, int size, RStringVector namesVector) {
-        RVector result = createResultVector(cachedPrecedence, size, namesVector);
+    private RVector<?> foldContents(int cachedPrecedence, Object[] elements, int size, RStringVector namesVector) {
+        RVector<?> result = createResultVector(cachedPrecedence, size, namesVector);
         int pos = 0;
         for (Object element : elements) {
             pos += processContentElement(result, pos, element);
@@ -253,7 +253,7 @@ public abstract class Combine extends RBuiltinNode {
         return result;
     }
 
-    private int processContentElement(RVector result, int pos, Object element) {
+    private int processContentElement(RVector<?> result, int pos, Object element) {
         if (isAbstractVectorProfile.profile(element instanceof RAbstractVector)) {
             RAbstractVector v = (RAbstractVector) element;
             for (int i = 0; i < v.getLength(); i++) {
@@ -326,7 +326,7 @@ public abstract class Combine extends RBuiltinNode {
         return CombineNodeGen.create(null);
     }
 
-    private static RVector createResultVector(int precedence, int size, RStringVector names) {
+    private static RVector<?> createResultVector(int precedence, int size, RStringVector names) {
         switch (precedence) {
             case COMPLEX_PRECEDENCE:
                 return RDataFactory.createComplexVector(new double[size * 2], true, names);
@@ -434,8 +434,8 @@ public abstract class Combine extends RBuiltinNode {
         protected RAbstractVector noCopy(RAbstractVector vector, //
                         @Cached("createBinaryProfile()") ConditionProfile hasNamesProfile, //
                         @Cached("createBinaryProfile()") ConditionProfile hasDimNamesProfile) {
-            RVector materialized = vector.materialize();
-            RVector result = materialized.copyDropAttributes();
+            RVector<?> materialized = vector.materialize();
+            RVector<?> result = materialized.copyDropAttributes();
 
             RStringVector vecNames = materialized.getInternalNames();
             if (hasNamesProfile.profile(vecNames != null)) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConnectionFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConnectionFunctions.java
index 4f519e17009281861e026bdcf577a533414c85e7..dc86b26875e6c3c0507ec1a3451c203ab297c16d 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConnectionFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ConnectionFunctions.java
@@ -738,7 +738,7 @@ public abstract class ConnectionFunctions {
         @TruffleBoundary
         protected Object readBin(RConnection con, String what, int n, @SuppressWarnings("unused") int size, @SuppressWarnings("unused") boolean signed,
                         boolean swap) {
-            RVector result = null;
+            RVector<?> result = null;
             try (RConnection openConn = con.forceOpen("rb")) {
                 if (getBaseConnection(openConn).getOpenMode().isText()) {
                     throw RError.error(this, RError.Message.ONLY_READ_BINARY_CONNECTION);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CopyDFAttr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CopyDFAttr.java
index 7cf35c43f2710d39e66e4f09fedc23335a5c4670..bd91785573149dbf784c85774719cfbb211c6064 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CopyDFAttr.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CopyDFAttr.java
@@ -41,7 +41,7 @@ public abstract class CopyDFAttr extends RBuiltinNode {
 
     @Specialization()
     protected RAttributable copy(RAbstractContainer in, RAbstractVector out) {
-        RVector res = out.materialize();
+        RVector<?> res = out.materialize();
         res.resetAllAttributes(false);
         return res.copyAttributesFrom(attrProfiles, in);
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java
index d66bf8c20b26f8b703ca1c02f5ad993fe30e92e7..e36efcd23f30aee4e3a34d8c3cf91c65e5e07833 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java
@@ -128,7 +128,7 @@ public class LaFunctions {
                     break;
                 }
             }
-            RVector values = null;
+            RVector<?> values = null;
             Object vectorValues = RNull.instance;
             if (hasComplexValues.profile(complexValues)) {
                 double[] data = new double[n * 2];
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Matrix.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Matrix.java
index c08dac062a534ae42c95cc34eed11ec82d8cd89a..65c6f9e3f163f3bf751c6aca26de7a9d06694798 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Matrix.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Matrix.java
@@ -93,7 +93,7 @@ public abstract class Matrix extends RBuiltinNode {
                         CompilerDirectives.transferToInterpreterAndInvalidate();
                         transpose = insert(TransposeNodeGen.create(null));
                     }
-                    res = (RVector) transpose.execute(res);
+                    res = (RVector<?>) transpose.execute(res);
                 }
                 if (isListProfile.profile(dimnames instanceof RAbstractListVector)) {
                     res = updateDimNames(res, dimnames);
@@ -109,7 +109,7 @@ public abstract class Matrix extends RBuiltinNode {
                     CompilerDirectives.transferToInterpreterAndInvalidate();
                     transpose = insert(TransposeNodeGen.create(null));
                 }
-                res = (RVector) transpose.execute(res);
+                res = (RVector<?>) transpose.execute(res);
             }
             if (isListProfile.profile(dimnames instanceof RAbstractListVector)) {
                 res = updateDimNames(res, dimnames);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Quote.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Quote.java
index 5856f0db32f15b61bc97a5af71abd1ab88ea917f..f3d805fcebb1295617aaf6fd4b0fb5e0715c9339 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Quote.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Quote.java
@@ -56,7 +56,7 @@ public abstract class Quote extends RBuiltinNode {
         return result;
     }
 
-    protected static final Object createLanguage(Closure closure) {
+    protected static Object createLanguage(Closure closure) {
         return RASTUtils.createLanguageElement(closure.getExpr().asRSyntaxNode());
     }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Range.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Range.java
index 5db642574c7f1e5925a1260bc6177e5bca5c3ce6..951ffd64bc07fc5f182600ff09a7c26a1b3b00c5 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Range.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Range.java
@@ -63,13 +63,13 @@ public abstract class Range extends RBuiltinNode {
     }
 
     @Specialization(guards = "args.getLength() == 1")
-    protected RVector rangeLengthOne(RArgsValuesAndNames args, boolean naRm, boolean finite) {
+    protected RVector<?> rangeLengthOne(RArgsValuesAndNames args, boolean naRm, boolean finite) {
         Object min = minReduce.executeReduce(args.getArgument(0), naRm, finite);
         Object max = maxReduce.executeReduce(args.getArgument(0), naRm, finite);
         return createResult(min, max);
     }
 
-    private static RVector createResult(Object min, Object max) {
+    private static RVector<?> createResult(Object min, Object max) {
         if (min instanceof Integer) {
             return RDataFactory.createIntVector(new int[]{(Integer) min, (Integer) max}, false);
         } else {
@@ -78,7 +78,7 @@ public abstract class Range extends RBuiltinNode {
     }
 
     @Specialization(contains = "rangeLengthOne")
-    protected RVector range(RArgsValuesAndNames args, boolean naRm, boolean finite, //
+    protected RVector<?> range(RArgsValuesAndNames args, boolean naRm, boolean finite, //
                     @Cached("create()") Combine combine) {
         Object combined = combine.executeCombine(args);
         Object min = minReduce.executeReduce(combined, naRm, finite);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java
index fc26c8e3365e813b31cdb70fa6f5e27f2844690e..0820f3320239aa69feccf632bfa81a158c35c260 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java
@@ -156,7 +156,7 @@ public abstract class Repeat extends RBuiltinNode {
         }
         RAbstractVector input = handleEach(x, each);
         RStringVector names = (RStringVector) handleEach(x.getNames(attrProfiles), each);
-        RVector r;
+        RVector<?> r;
         if (lengthOutOrTimes.profile(!RRuntime.isNA(lengthOut))) {
             names = (RStringVector) handleLengthOut(names, lengthOut, false);
             r = handleLengthOut(input, lengthOut, false);
@@ -174,7 +174,7 @@ public abstract class Repeat extends RBuiltinNode {
                     @Cached("create()") InitAttributesNode initAttributes,
                     @Cached("createNames()") PutAttributeNode putNames) {
         RStringVector names;
-        RVector r;
+        RVector<?> r;
         if (lengthOutOrTimes.profile(!RRuntime.isNA(lengthOut))) {
             names = (RStringVector) handleLengthOut(x.getNames(attrProfiles), lengthOut, true);
             r = handleLengthOut(x, lengthOut, true);
@@ -190,8 +190,8 @@ public abstract class Repeat extends RBuiltinNode {
     /**
      * Prepare the input vector by replicating its elements.
      */
-    private static RVector handleEach(RAbstractVector x, int each) {
-        RVector r = x.createEmptySameType(x.getLength() * each, x.isComplete());
+    private static RVector<?> handleEach(RAbstractVector x, int each) {
+        RVector<?> r = x.createEmptySameType(x.getLength() * each, x.isComplete());
         for (int i = 0; i < x.getLength(); i++) {
             for (int j = i * each; j < (i + 1) * each; j++) {
                 r.transferElementSameType(j, x, i);
@@ -203,9 +203,9 @@ public abstract class Repeat extends RBuiltinNode {
     /**
      * Extend or truncate the vector to a specified length.
      */
-    private static RVector handleLengthOut(RAbstractVector x, int lengthOut, boolean copyIfSameSize) {
+    private static RVector<?> handleLengthOut(RAbstractVector x, int lengthOut, boolean copyIfSameSize) {
         if (x.getLength() == lengthOut) {
-            return (RVector) (copyIfSameSize ? x.copy() : x);
+            return (RVector<?>) (copyIfSameSize ? x.copy() : x);
         }
         return x.copyResized(lengthOut, false);
     }
@@ -213,7 +213,7 @@ public abstract class Repeat extends RBuiltinNode {
     /**
      * Replicate the vector a given number of times.
      */
-    private RVector handleTimes(RAbstractVector x, RAbstractIntVector times, boolean copyIfSameSize) {
+    private RVector<?> handleTimes(RAbstractVector x, RAbstractIntVector times, boolean copyIfSameSize) {
         if (oneTimeGiven.profile(times.getLength() == 1)) {
             // only one times value is given
             final int howManyTimes = times.getDataAt(0);
@@ -222,7 +222,7 @@ public abstract class Repeat extends RBuiltinNode {
                 throw invalidTimes();
             }
             if (replicateOnce.profile(howManyTimes == 1)) {
-                return (RVector) (copyIfSameSize ? x.copy() : x);
+                return (RVector<?>) (copyIfSameSize ? x.copy() : x);
             } else {
                 return x.copyResized(x.getLength() * howManyTimes, false);
             }
@@ -243,7 +243,7 @@ public abstract class Repeat extends RBuiltinNode {
                 resultLength += t;
             }
             // create and populate result vector
-            RVector r = x.createEmptySameType(resultLength, x.isComplete());
+            RVector<?> r = x.createEmptySameType(resultLength, x.isComplete());
             int wp = 0; // write pointer
             for (int i = 0; i < x.getLength(); i++) {
                 for (int j = 0; j < times.getDataAt(i); ++j, ++wp) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RowsumFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RowsumFunctions.java
index 782ee89bcaaac6cf996fbfcc559bc6ee93df2aa2..207312d8a64a1ec44f1c22307794fdccb5b51052 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RowsumFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RowsumFunctions.java
@@ -84,7 +84,7 @@ public class RowsumFunctions {
             int offsetg = 0;
 
             boolean isInt = xv instanceof RIntVector;
-            RVector result;
+            RVector<?> result;
             na.enable(xv);
             boolean complete = xv.isComplete();
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Scan.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Scan.java
index 70f24818979646f4ac10c6abfc5a9ec3b868fa98..3c8739d3f62699f6ba4dd85ee6a674aab8048910 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Scan.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Scan.java
@@ -313,12 +313,13 @@ public abstract class Scan extends RBuiltinNode {
 
     private void fillEmpty(int from, int to, int records, RList list, LocalData data) {
         for (int i = from; i < to; i++) {
-            RVector vec = (RVector) list.getDataAt(i);
+            RVector<?> vec = (RVector<?>) list.getDataAt(i);
             vec.updateDataAtAsObject(records, extractItem(vec, "", data), naCheck);
         }
     }
 
-    private RVector scanFrame(RList what, int maxRecords, int maxLines, boolean flush, boolean fill, @SuppressWarnings("unused") boolean stripWhite, boolean blSkip, boolean multiLine, LocalData data)
+    private RVector<?> scanFrame(RList what, int maxRecords, int maxLines, boolean flush, boolean fill, @SuppressWarnings("unused") boolean stripWhite, boolean blSkip, boolean multiLine,
+                    LocalData data)
                     throws IOException {
 
         int nc = what.getLength();
@@ -345,7 +346,7 @@ public abstract class Scan extends RBuiltinNode {
     }
 
     @TruffleBoundary
-    private RVector scanFrameInternal(int maxRecords, int maxLines, boolean flush, boolean fill, boolean blSkip, boolean multiLine, LocalData data, int nc, int initialBlockSize, RList list)
+    private RVector<?> scanFrameInternal(int maxRecords, int maxLines, boolean flush, boolean fill, boolean blSkip, boolean multiLine, LocalData data, int nc, int initialBlockSize, RList list)
                     throws IOException {
         int blockSize = initialBlockSize;
         int n = 0;
@@ -386,13 +387,13 @@ public abstract class Scan extends RBuiltinNode {
                     // enlarge the vector
                     blockSize = blockSize * 2;
                     for (int j = 0; j < nc; j++) {
-                        RVector vec = (RVector) list.getDataAt(j);
+                        RVector<?> vec = (RVector<?>) list.getDataAt(j);
                         vec = vec.copyResized(blockSize, false);
                         list.updateDataAt(j, vec, null);
                     }
                 }
 
-                RVector vec = (RVector) list.getDataAt(n);
+                RVector<?> vec = (RVector<?>) list.getDataAt(n);
                 vec.updateDataAtAsObject(records, item, naCheck);
                 n++;
                 if (n == nc) {
@@ -431,7 +432,7 @@ public abstract class Scan extends RBuiltinNode {
         }
         // trim vectors if necessary
         for (int i = 0; i < nc; i++) {
-            RVector vec = (RVector) list.getDataAt(i);
+            RVector<?> vec = (RVector<?>) list.getDataAt(i);
             if (vec.getLength() > records) {
                 list.updateDataAt(i, vec.copyResized(records, false), null);
             }
@@ -441,10 +442,10 @@ public abstract class Scan extends RBuiltinNode {
     }
 
     @TruffleBoundary
-    private RVector scanVector(RAbstractVector what, int maxItems, int maxLines, @SuppressWarnings("unused") boolean flush, @SuppressWarnings("unused") boolean stripWhite, boolean blSkip,
+    private RVector<?> scanVector(RAbstractVector what, int maxItems, int maxLines, @SuppressWarnings("unused") boolean flush, @SuppressWarnings("unused") boolean stripWhite, boolean blSkip,
                     LocalData data) throws IOException {
         int blockSize = maxItems > 0 ? maxItems : SCAN_BLOCKSIZE;
-        RVector vec = what.createEmptySameType(blockSize, RDataFactory.COMPLETE_VECTOR);
+        RVector<?> vec = what.createEmptySameType(blockSize, RDataFactory.COMPLETE_VECTOR);
         naCheck.enable(true);
 
         int n = 0;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java
index e9088eeb636daa0ba882e7913ceef4134f86132b..b31b88e2a07d514e25968d47ad9336e7a096e2e3 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java
@@ -70,7 +70,7 @@ public abstract class Transpose extends RBuiltinNode {
         void apply(A array, T vector, int i, int j);
     }
 
-    protected <T extends RAbstractVector, A> RVector transposeInternal(T vector, Function<Integer, A> createArray, WriteArray<T, A> writeArray, BiFunction<A, Boolean, RVector> createResult) {
+    protected <T extends RAbstractVector, A> RVector<?> transposeInternal(T vector, Function<Integer, A> createArray, WriteArray<T, A> writeArray, BiFunction<A, Boolean, RVector<?>> createResult) {
         int length = lengthProfile.profile(vector.getLength());
         int firstDim;
         int secondDim;
@@ -92,7 +92,7 @@ public abstract class Transpose extends RBuiltinNode {
             }
             writeArray.apply(array, vector, i, j);
         }
-        RVector r = createResult.apply(array, vector.isComplete());
+        RVector<?> r = createResult.apply(array, vector.isComplete());
         // copy attributes
         copyRegAttributes.execute(vector, r);
         // set new dimensions
@@ -112,22 +112,22 @@ public abstract class Transpose extends RBuiltinNode {
     }
 
     @Specialization
-    protected RVector transpose(RAbstractIntVector x) {
+    protected RVector<?> transpose(RAbstractIntVector x) {
         return transposeInternal(x, l -> new int[l], (a, v, i, j) -> a[i] = v.getDataAt(j), RDataFactory::createIntVector);
     }
 
     @Specialization
-    protected RVector transpose(RAbstractLogicalVector x) {
+    protected RVector<?> transpose(RAbstractLogicalVector x) {
         return transposeInternal(x, l -> new byte[l], (a, v, i, j) -> a[i] = v.getDataAt(j), RDataFactory::createLogicalVector);
     }
 
     @Specialization
-    protected RVector transpose(RAbstractDoubleVector x) {
+    protected RVector<?> transpose(RAbstractDoubleVector x) {
         return transposeInternal(x, l -> new double[l], (a, v, i, j) -> a[i] = v.getDataAt(j), RDataFactory::createDoubleVector);
     }
 
     @Specialization
-    protected RVector transpose(RAbstractComplexVector x) {
+    protected RVector<?> transpose(RAbstractComplexVector x) {
         return transposeInternal(x, l -> new double[l * 2], (a, v, i, j) -> {
             RComplex d = v.getDataAt(j);
             a[i * 2] = d.getRealPart();
@@ -136,22 +136,22 @@ public abstract class Transpose extends RBuiltinNode {
     }
 
     @Specialization
-    protected RVector transpose(RAbstractStringVector x) {
+    protected RVector<?> transpose(RAbstractStringVector x) {
         return transposeInternal(x, l -> new String[l], (a, v, i, j) -> a[i] = v.getDataAt(j), RDataFactory::createStringVector);
     }
 
     @Specialization
-    protected RVector transpose(RAbstractListVector x) {
+    protected RVector<?> transpose(RAbstractListVector x) {
         return transposeInternal(x, l -> new Object[l], (a, v, i, j) -> a[i] = v.getDataAt(j), (a, c) -> RDataFactory.createList(a));
     }
 
     @Specialization
-    protected RVector transpose(RAbstractRawVector x) {
+    protected RVector<?> transpose(RAbstractRawVector x) {
         return transposeInternal(x, l -> new byte[l], (a, v, i, j) -> a[i] = v.getRawDataAt(j), (a, c) -> RDataFactory.createRawVector(a));
     }
 
     @Fallback
-    protected RVector transpose(@SuppressWarnings("unused") Object x) {
+    protected RVector<?> transpose(@SuppressWarnings("unused") Object x) {
         throw RError.error(RError.SHOW_CALLER, Message.ARGUMENT_NOT_MATRIX);
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java
index 9f6d574f555cf4b776024d331357cadc9a50c460..a6aadc4565ca7a321c33c9886a9d0c83bca66c75 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java
@@ -46,7 +46,7 @@ public abstract class UnClass extends RBuiltinNode {
 
     @TruffleBoundary
     private static Object unClassVector(RAbstractVector arg) {
-        RVector resultVector = arg.materialize();
+        RVector<?> resultVector = arg.materialize();
         if (!resultVector.isTemporary()) {
             resultVector = resultVector.copy();
             resultVector.incRefCount();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java
index c3a5cceffc39f8029bbe9fb0e99a206a91d25ea7..c397bb15c5dd0d59548651c617a42220f77447fe 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java
@@ -58,7 +58,7 @@ public abstract class UpdateDim extends RBuiltinNode {
 
     @Specialization
     protected RAbstractVector updateDim(RAbstractVector vector, @SuppressWarnings("unused") RNull dimensions) {
-        RVector result = ((RAbstractVector) reuse.execute(vector)).materialize();
+        RVector<?> result = ((RAbstractVector) reuse.execute(vector)).materialize();
         result.resetDimensions(null);
         return result;
     }
@@ -70,7 +70,7 @@ public abstract class UpdateDim extends RBuiltinNode {
         RIntVector dimensionsMaterialized = dimensions.materialize();
         int[] dimsData = dimensionsMaterialized.getDataCopy();
         RVector.verifyDimensions(vector.getLength(), dimsData, this);
-        RVector result = ((RAbstractVector) reuse.execute(vector)).materialize();
+        RVector<?> result = ((RAbstractVector) reuse.execute(vector)).materialize();
         result.setInternalDimensions(dimsData);
         result.setInternalNames(null);
         result.setInternalDimNames(null);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java
index 347a75879a47bc43836426da6989aee36d6704a7..d77eb154b652b762b180dd82927db291d3658158 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java
@@ -97,7 +97,7 @@ public abstract class UpdateDimNames extends RBuiltinNode {
                     @Cached("create(DIMNAMES_ATTR_KEY)") RemoveAttributeNode remove) {
         RAbstractContainer result = (RAbstractContainer) container.getNonShared();
         if (isRVectorProfile.profile(container instanceof RVector)) {
-            RVector vector = (RVector) result;
+            RVector<?> vector = (RVector<?>) result;
             if (vector.getInternalDimNames() != null) {
                 vector.setInternalDimNames(null);
                 remove.execute(vector.getAttributes());
@@ -131,7 +131,7 @@ public abstract class UpdateDimNames extends RBuiltinNode {
     private void setDimNames(RAbstractContainer container, RList newDimNames, PutAttributeNode put) {
         assert newDimNames != null;
         if (isRVectorProfile.profile(container instanceof RVector)) {
-            RVector vector = (RVector) container;
+            RVector<?> vector = (RVector<?>) container;
             int[] dimensions = vector.getDimensions();
             if (dimensions == null) {
                 CompilerDirectives.transferToInterpreter();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java
index 5ffaf8da7fb1c5c4457f4a87c73b2971c52c6241..003fb96b284730de7da4a616d917c24c3f2d541e 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java
@@ -44,14 +44,14 @@ public abstract class UpdateLevels extends RBuiltinNode {
 
     @Specialization
     protected RAbstractVector updateLevels(RAbstractVector vector, @SuppressWarnings("unused") RNull levels) {
-        RVector v = (RVector) vector.getNonShared();
+        RVector<?> v = (RVector<?>) vector.getNonShared();
         v.removeAttr(attrProfiles, RRuntime.LEVELS_ATTR_KEY);
         return v;
     }
 
     @Specialization(guards = "levelsNotNull(levels)")
     protected RAbstractVector updateLevels(RAbstractVector vector, Object levels) {
-        RVector v = (RVector) vector.getNonShared();
+        RVector<?> v = (RVector<?>) vector.getNonShared();
         v.setAttr(RRuntime.LEVELS_ATTR_KEY, castVector(levels));
         return v;
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/VApply.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/VApply.java
index f27617a2fd13d84181bd9e7bc97fdb0ffcea59de..5b514a32e191e56f36d88ec6df4221ec3844fbee 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/VApply.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/VApply.java
@@ -139,12 +139,12 @@ public abstract class VApply extends RBuiltinNode {
 
     @Specialization
     protected Object vapply(VirtualFrame frame, RAbstractVector vec, RFunction fun, RAbstractVector funValue, byte useNames) {
-        RVector result = delegateToLapply(frame, vec, fun, funValue, useNames);
+        RVector<?> result = delegateToLapply(frame, vec, fun, funValue, useNames);
         // set here else it gets overridden by the iterator evaluation
         return result;
     }
 
-    private RVector delegateToLapply(VirtualFrame frame, RAbstractVector vec, RFunction fun, RAbstractVector funValueVec, byte useNames) {
+    private RVector<?> delegateToLapply(VirtualFrame frame, RAbstractVector vec, RFunction fun, RAbstractVector funValueVec, byte useNames) {
         /*
          * The implementation is complicated by the existence of scalar length 1 vectors (e.g.
          * Integer) and concrete length 1 vectors (e.g. RIntVector), as either form can occur in
@@ -153,10 +153,10 @@ public abstract class VApply extends RBuiltinNode {
          */
         int funValueVecLen = funValueVec.getLength();
 
-        RVector vecMat = vec.materialize();
+        RVector<?> vecMat = vec.materialize();
         Object[] applyResult = doApply.execute(frame, vecMat, fun);
 
-        RVector result = null;
+        RVector<?> result = null;
         boolean applyResultZeroLength = applyResult.length == 0;
 
         naCheck.enable(true);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FactorPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FactorPrinter.java
index 0fe9536e21eed8c0d1f581aa79d6051f878dc1ba..9cbb2a9c13abdb8102a4f3d5ffb622989a457e23 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FactorPrinter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FactorPrinter.java
@@ -49,7 +49,7 @@ final class FactorPrinter extends AbstractValuePrinter<RAbstractIntVector> {
         // TODO: this should be handled by an S3 function. Should it? For example, in C code for
         // split, there is direct call to getAttrib. This should be refactored to use
         // AttributeAccess node or even Factor.GetLevels node. The same holds for the access
-        RVector levels = RFactor.getLevels(operand);
+        RVector<?> levels = RFactor.getLevels(operand);
         String[] strings;
         if (levels == null) {
             strings = new String[0];
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java
index e3783b83080ad0f4b91a9c35ac793ac5e5973f38..3310513ca6ea51d98ca80c8224cbd52287e97a76 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java
@@ -301,11 +301,6 @@ public final class ValuePrinterNode extends RBaseNode {
                                 return RList.implicitClassHeader;
                             }
 
-                            @Override
-                            public RStringVector getNames() {
-                                return null;
-                            }
-
                             @Override
                             public RList materialize() {
                                 throw RInternalError.shouldNotReachHere();
@@ -354,11 +349,6 @@ public final class ValuePrinterNode extends RBaseNode {
                             return RList.implicitClassHeader;
                         }
 
-                        @Override
-                        public RStringVector getNames() {
-                            return names;
-                        }
-
                         @Override
                         public RStringVector getNames(RAttributeProfiles attrProfiles) {
                             return names;
@@ -445,7 +435,7 @@ public final class ValuePrinterNode extends RBaseNode {
         }
 
         @Override
-        public RVector copyResized(int size, boolean fillNA) {
+        public RVector<?> copyResized(int size, boolean fillNA) {
             throw RInternalError.shouldNotReachHere();
         }
 
@@ -455,7 +445,7 @@ public final class ValuePrinterNode extends RBaseNode {
         }
 
         @Override
-        public RVector copyResizedWithDimensions(int[] newDimensions, boolean fillNA) {
+        public RVector<?> copyResizedWithDimensions(int[] newDimensions, boolean fillNA) {
             throw RInternalError.shouldNotReachHere();
         }
 
@@ -465,7 +455,7 @@ public final class ValuePrinterNode extends RBaseNode {
         }
 
         @Override
-        public RVector createEmptySameType(int newLength, boolean newIsComplete) {
+        public RVector<?> createEmptySameType(int newLength, boolean newIsComplete) {
             throw RInternalError.shouldNotReachHere();
         }
 
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java
index bb690557e1b0f3050f4b633f9b3212a63aef7467..0c92ea9cede464583612935435e0608bfd3fb3e1 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java
@@ -250,8 +250,8 @@ public class BinaryArithmeticNodeTest extends BinaryVectorTest {
             ((RShareable) b).incRefCount();
         }
 
-        RVector aMaterialized = a.copy().materialize();
-        RVector bMaterialized = b.copy().materialize();
+        RVector<?> aMaterialized = a.copy().materialize();
+        RVector<?> bMaterialized = b.copy().materialize();
 
         aMaterialized.setAttr("a", "a");
         bMaterialized.setAttr("b", "b");
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java
index caf3f27d52dbc46a48bd6270f80e63733b86e498..731c23a0b23818a2357f1205027ed773e92f65d9 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java
@@ -150,7 +150,7 @@ public class UnaryArithmeticNodeTest extends BinaryVectorTest {
             ((RShareable) a).incRefCount();
         }
 
-        RVector aMaterialized = a.copy().materialize();
+        RVector<?> aMaterialized = a.copy().materialize();
         aMaterialized.setAttr("a", "a");
         assertAttributes(executeArithmetic(factory, aMaterialized.copy()), "a");
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java
index 2e87926b33cf3a75057b5114c8026c2892fb6f4a..1c62578267bd856845c1ac5fd597a82b8ac5eb21 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java
@@ -160,7 +160,7 @@ final class CachedExtractVectorNode extends CachedVectorNode {
         }
 
         int extractedVectorLength = positionsCheckNode.getSelectedPositionsCount(positionProfiles);
-        final RVector extractedVector;
+        final RVector<?> extractedVector;
         switch (vectorType) {
             case Expression:
                 extractedVector = RType.Expression.create(extractedVectorLength, false);
@@ -278,7 +278,7 @@ final class CachedExtractVectorNode extends CachedVectorNode {
     private final ConditionProfile foundNamesProfile = ConditionProfile.createBinaryProfile();
 
     @ExplodeLoop
-    private void applyDimensions(RAbstractContainer originalTarget, RVector extractedTarget, int extractedTargetLength, PositionProfile[] positionProfile, Object[] positions) {
+    private void applyDimensions(RAbstractContainer originalTarget, RVector<?> extractedTarget, int extractedTargetLength, PositionProfile[] positionProfile, Object[] positions) {
         // TODO speculate on the number of counted dimensions
         int dimCount = countDimensions(positionProfile);
 
@@ -406,7 +406,7 @@ final class CachedExtractVectorNode extends CachedVectorNode {
         }
     }
 
-    private void setNames(RVector vector, Object newNames) {
+    private void setNames(RVector<?> vector, Object newNames) {
         if (setNamesNode == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
             setNamesNode = insert(SetNamesNodeGen.create());
@@ -416,10 +416,10 @@ final class CachedExtractVectorNode extends CachedVectorNode {
 
     protected abstract static class SetNamesNode extends Node {
 
-        public abstract void execute(RVector container, Object newNames);
+        public abstract void execute(RVector<?> container, Object newNames);
 
         @Specialization
-        protected void setNames(RVector container, RAbstractStringVector newNames) {
+        protected void setNames(RVector<?> container, RAbstractStringVector newNames) {
             RStringVector newNames1 = newNames.materialize();
             assert newNames1.getLength() <= container.getLength();
             assert container.getInternalDimensions() == null;
@@ -438,13 +438,13 @@ final class CachedExtractVectorNode extends CachedVectorNode {
         }
 
         @Specialization
-        protected void setNames(RVector container, String newNames) {
+        protected void setNames(RVector<?> container, String newNames) {
             // TODO: why materialize()?
             setNames(container, RString.valueOf(newNames).materialize());
         }
 
         @Specialization
-        protected void setNames(RVector container, @SuppressWarnings("unused") RNull newNames) {
+        protected void setNames(RVector<?> container, @SuppressWarnings("unused") RNull newNames) {
             assert container.getAttributes() == null;
         }
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java
index ca7282c166d6e1ed73dcf766408f6545829a3a67..5cfa7d0fd7044fb240eed4b22305d51bff2c6664 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java
@@ -507,9 +507,9 @@ final class CachedReplaceVectorNode extends CachedVectorNode {
     // TODO (chumer) this is way to complicated at the moment
     // its not yet worth compiling it we need a better attribute system
     @TruffleBoundary
-    private RVector resizeVector(RAbstractVector vector, int size) {
+    private RVector<?> resizeVector(RAbstractVector vector, int size) {
         RStringVector oldNames = vector.getNames(vectorNamesProfile);
-        RVector res = vector.copyResized(size, true).materialize();
+        RVector<?> res = vector.copyResized(size, true).materialize();
         if (vector instanceof RVector) {
             res.copyAttributesFrom(positionNamesProfile, vector);
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyAttributesNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyAttributesNode.java
index 79c34d928574bbcfd5679d9990cc84cbb7e5746c..5bb402d333800d9d0f7e5a5b2450ee011a57840a 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyAttributesNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyAttributesNode.java
@@ -126,7 +126,7 @@ public abstract class CopyAttributesNode extends RBaseNode {
             log("copyAttributes: ==");
             countEquals++;
         }
-        RVector result = target.materialize();
+        RVector<?> result = target.materialize();
         if (copyAllAttributes) {
             if (result != right) {
                 copyOfRegRight.execute(right, result);
@@ -210,7 +210,7 @@ public abstract class CopyAttributesNode extends RBaseNode {
             countSmaller++;
         }
         boolean rightNotResult = rightNotResultProfile.profile(right != target);
-        RVector result = target.materialize();
+        RVector<?> result = target.materialize();
         if (copyAllAttributes && rightNotResult) {
             copyOfReg.execute(right, result);
         }
@@ -264,7 +264,7 @@ public abstract class CopyAttributesNode extends RBaseNode {
             log("copyAttributes: >");
             countLarger++;
         }
-        RVector result = target.materialize();
+        RVector<?> result = target.materialize();
         if (copyAllAttributes && result != left) {
             copyOfReg.execute(left, result);
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyOfRegAttributesNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyOfRegAttributesNode.java
index de60064a28a74110e61b45178f375df86982aeb0..b8ea14716d31665ae98772bf93e62ff79e7285e0 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyOfRegAttributesNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyOfRegAttributesNode.java
@@ -40,7 +40,7 @@ public abstract class CopyOfRegAttributesNode extends RBaseNode {
 
     private final ConditionProfile sizeOneProfile = ConditionProfile.createBinaryProfile();
 
-    public abstract void execute(RAbstractVector source, RVector target);
+    public abstract void execute(RAbstractVector source, RVector<?> target);
 
     public static CopyOfRegAttributesNode create() {
         return CopyOfRegAttributesNodeGen.create();
@@ -48,7 +48,7 @@ public abstract class CopyOfRegAttributesNode extends RBaseNode {
 
     @SuppressWarnings("unused")
     @Specialization(guards = "source.getAttributes() == null")
-    protected void copyNoAttributes(RAbstractVector source, RVector target) {
+    protected void copyNoAttributes(RAbstractVector source, RVector<?> target) {
         // nothing to do
     }
 
@@ -59,7 +59,7 @@ public abstract class CopyOfRegAttributesNode extends RBaseNode {
 
     @SuppressWarnings("unused")
     @Specialization(guards = "emptyAttributes(source)", contains = "copyNoAttributes")
-    protected void copyEmptyAttributes(RAbstractVector source, RVector target) {
+    protected void copyEmptyAttributes(RAbstractVector source, RVector<?> target) {
         // nothing to do
     }
 
@@ -70,7 +70,7 @@ public abstract class CopyOfRegAttributesNode extends RBaseNode {
 
     @SuppressWarnings("unused")
     @Specialization(guards = "onlyDimAttribute(source)")
-    protected void copyDimOnly(RAbstractVector source, RVector target) {
+    protected void copyDimOnly(RAbstractVector source, RVector<?> target) {
         // nothing to do
     }
 
@@ -81,7 +81,7 @@ public abstract class CopyOfRegAttributesNode extends RBaseNode {
 
     @SuppressWarnings("unused")
     @Specialization(guards = "onlyNamesAttribute(source)")
-    protected void copyNamesOnly(RAbstractVector source, RVector target) {
+    protected void copyNamesOnly(RAbstractVector source, RVector<?> target) {
         // nothing to do
     }
 
@@ -91,12 +91,12 @@ public abstract class CopyOfRegAttributesNode extends RBaseNode {
     }
 
     @Specialization(guards = "onlyClassAttribute(source)")
-    protected void copyClassOnly(RAbstractVector source, RVector target) {
+    protected void copyClassOnly(RAbstractVector source, RVector<?> target) {
         target.initAttributes(RAttributes.createInitialized(new String[]{RRuntime.CLASS_ATTR_KEY}, new Object[]{source.getAttributes().getValueAtIndex(0)}));
     }
 
     @Specialization
-    protected void copyGeneric(RAbstractVector source, RVector target) {
+    protected void copyGeneric(RAbstractVector source, RVector<?> target) {
         RAttributes orgAttributes = source.getAttributes();
         if (orgAttributes != null) {
             Object newRowNames = null;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UnaryCopyAttributesNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UnaryCopyAttributesNode.java
index 0d12ad9c1a8cdcce3a5ce8359ca12422e33fed45..e6f9d802e696bc4f99360bc4ff7761d45f200c55 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UnaryCopyAttributesNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UnaryCopyAttributesNode.java
@@ -79,7 +79,7 @@ public abstract class UnaryCopyAttributesNode extends RBaseNode {
                     @Cached("createBinaryProfile()") ConditionProfile noDimensions, //
                     @Cached("createBinaryProfile()") ConditionProfile hasNamesSource, //
                     @Cached("createBinaryProfile()") ConditionProfile hasDimNames) {
-        RVector result = target.materialize();
+        RVector<?> result = target.materialize();
 
         if (copyAllAttributes) {
             copyOfReg.execute(source, result);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/WrapArgumentBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/WrapArgumentBaseNode.java
index ea78fd31ab168ccb3dd5c1bde48c717af525b335..722e6566d56123ae845ef36608b91fc83c4910b8 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/WrapArgumentBaseNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/WrapArgumentBaseNode.java
@@ -73,7 +73,7 @@ public abstract class WrapArgumentBaseNode extends RNode {
         Object result = argumentValueProfile.profile(initialResult);
         if (result instanceof RVector) {
             everSeenVector.enter();
-            return (RVector) result;
+            return (RVector<?>) result;
         } else if (result instanceof RLanguage) {
             everSeenLanguage.enter();
             return (RLanguage) result;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/RFactorNodes.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/RFactorNodes.java
index cf65a15c602e85f5eccf5e005c31402e5c68ff30..85fb3995c0838da54cf667862767ae5576beb39f 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/RFactorNodes.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/RFactorNodes.java
@@ -82,11 +82,11 @@ public final class RFactorNodes {
             Object attr = attrAccess.execute(factor.getAttributes());
 
             // Convert scalars to vector if necessary
-            RVector vec;
+            RVector<?> vec;
             if (nonScalarLevels.profile(attr instanceof RVector)) {
-                vec = (RVector) attr;
+                vec = (RVector<?>) attr;
             } else if (attr != null) {
-                vec = (RVector) RRuntime.asAbstractVector(attr);   // scalar to vector
+                vec = (RVector<?>) RRuntime.asAbstractVector(attr);   // scalar to vector
             } else {
                 notVectorBranch.enter();
                 // N.B: when a factor is lacking the 'levels' attribute, GNU R uses range 1:14331272
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java
index 98bfef344407cdf0d8a635dadf0742f77f547966..95c12bd9fa164c812483478877d00b4ae380a07f 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java
@@ -170,7 +170,7 @@ public final class UnaryMapNode extends RBaseNode {
         if (containsMetadata(operand) && operand != target) {
             hasAttributesProfile.enter();
             result = result.materialize();
-            copyAttributesInternal((RVector) result, operand);
+            copyAttributesInternal((RVector<?>) result, operand);
         }
         return result;
     }
@@ -184,7 +184,7 @@ public final class UnaryMapNode extends RBaseNode {
     }
 
     @TruffleBoundary
-    private void copyAttributesInternal(RVector result, RAbstractVector attributeSource) {
+    private void copyAttributesInternal(RVector<?> result, RAbstractVector attributeSource) {
         result.copyRegAttributesFrom(attributeSource);
         result.setDimensions(attributeSource.getDimensions());
         result.copyNamesFrom(attrProfiles, attributeSource);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java
index 9f401aa09158f569c14c17be0220dbd234d13d1e..e9b89627095e03cd06329d0eee7a0082a7ea2ab5 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java
@@ -93,7 +93,7 @@ public abstract class CastBaseNode extends CastNode {
         }
     }
 
-    protected void preserveDimensionNames(RAbstractContainer operand, RVector ret) {
+    protected void preserveDimensionNames(RAbstractContainer operand, RVector<?> ret) {
         if (preserveDimensions()) {
             RList dimNames = operand.getDimNames(attrProfiles);
             if (hasDimNamesProfile.profile(dimNames != null)) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java
index 9964f1c01d7ec9cb144018e509f17cbe40933817..d0817ba5237595ce31d44d938e5f70d1e61ec27c 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java
@@ -960,9 +960,9 @@ public class RSerialize {
                 if (attrValue instanceof RShareable && ((RShareable) attrValue).isTemporary()) {
                     ((RShareable) attrValue).incRefCount();
                 }
-                if (result instanceof RVector && tag.equals(RRuntime.CLASS_ATTR_KEY)) {
+                if (result instanceof RVector<?> && tag.equals(RRuntime.CLASS_ATTR_KEY)) {
                     RStringVector classes = (RStringVector) attrValue;
-                    result = ((RVector) result).setClassAttr(classes);
+                    result = ((RVector<?>) result).setClassAttr(classes);
                 } else {
                     rAttributable.setAttr(tag, attrValue);
                 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java
index 4d6af76e83190c8b4ced43b067e46cf599c76759..9da38a9af9e03e131dadae2b0f7bc36b94c89fea 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java
@@ -182,7 +182,7 @@ public enum RType {
         }
     }
 
-    public RVector getEmpty() {
+    public RVector<?> getEmpty() {
         switch (this) {
             case Double:
                 return RDataFactory.createEmptyDoubleVector();
@@ -203,7 +203,7 @@ public enum RType {
         }
     }
 
-    public RVector create(int length, boolean fillNA) {
+    public RVector<?> create(int length, boolean fillNA) {
         switch (this) {
             case Logical:
                 return RDataFactory.createLogicalVector(length, fillNA);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/ConnectionSupport.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/ConnectionSupport.java
index 94bbb2c406c799f13df7f27a6e06e0d27c4c9e49..3a77d377e1efc512c34ba49461afb6616cd1d789 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/ConnectionSupport.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/ConnectionSupport.java
@@ -333,7 +333,7 @@ public class ConnectionSupport {
      * if the result isn't actually a valid connection, e.g.
      * {@code structure(2, class=c("terminal","connection"))}.
      */
-    public static RConnection fromVector(RVector vector, @SuppressWarnings("unused") RStringVector classAttr) {
+    public static RConnection fromVector(RVector<?> vector, @SuppressWarnings("unused") RStringVector classAttr) {
         int index = RRuntime.asInteger(vector);
         RConnection result = RContext.getInstance().stateRConnection.getConnection(index);
         if (result == null) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/RConnection.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/RConnection.java
index b54b5995afd58769b1094ffc7740fc74f9be1ee4..4939a1c008c1c6cd9d4840df95e5b3f1441205df 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/RConnection.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/RConnection.java
@@ -331,7 +331,7 @@ public abstract class RConnection extends RAttributeStorage implements AutoClose
     public abstract boolean isOpen();
 
     /*
-     * Methods from the RAbstractContainer interface, which is implemented to allow an RVector to
+     * Methods from the RAbstractContainer interface, which is implemented to allow an RVector<?>to
      * transform to an RConnection via a class update.
      */
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RComplexVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RComplexVector.java
index e94bd445cc3b6d629053f86da551dbab6deea2bf..2b4e628ef8416530303763ffca4fce869cb62368 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RComplexVector.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RComplexVector.java
@@ -33,7 +33,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 
-public final class RComplexVector extends RVector implements RAbstractComplexVector {
+public final class RComplexVector extends RVector<double[]> implements RAbstractComplexVector {
 
     public static final RStringVector implicitClassHeader = RDataFactory.createStringVectorFromScalar(RType.Complex.getClazz());
 
@@ -117,41 +117,20 @@ public final class RComplexVector extends RVector implements RAbstractComplexVec
         return true;
     }
 
+    @Override
     public double[] getDataCopy() {
-        double[] copy = new double[data.length];
-        System.arraycopy(data, 0, copy, 0, data.length);
-        return copy;
+        return Arrays.copyOf(data, data.length);
     }
 
     /**
      * Intended for external calls where a copy is not needed. WARNING: think carefully before using
      * this method rather than {@link #getDataCopy()}.
      */
+    @Override
     public double[] getDataWithoutCopying() {
         return data;
     }
 
-    /**
-     * Return vector data (copying if necessary) that's guaranteed not to be shared with any other
-     * vector instance (but maybe non-temporary in terms of vector's sharing mode).
-     *
-     * @return vector data
-     */
-    public double[] getDataNonShared() {
-        return isShared() ? getDataCopy() : getDataWithoutCopying();
-
-    }
-
-    /**
-     * Return vector data (copying if necessary) that's guaranteed to be "fresh" (temporary in terms
-     * of vector sharing mode).
-     *
-     * @return vector data
-     */
-    public double[] getDataTemp() {
-        return isTemporary() ? getDataWithoutCopying() : getDataCopy();
-    }
-
     @Override
     public RComplexVector copyWithNewDimensions(int[] newDimensions) {
         return RDataFactory.createComplexVector(data, isComplete(), newDimensions);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDoubleVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDoubleVector.java
index c542875fa7f26d8e6b64219f65df90db26b6db82..1dff2eea8b12fc648242ff07d855683a2be82bdc 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDoubleVector.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDoubleVector.java
@@ -33,7 +33,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 
-public final class RDoubleVector extends RVector implements RAbstractDoubleVector {
+public final class RDoubleVector extends RVector<double[]> implements RAbstractDoubleVector {
 
     public static final RStringVector implicitClassHeader = RDataFactory.createStringVectorFromScalar(RType.Double.getClazz());
 
@@ -129,41 +129,20 @@ public final class RDoubleVector extends RVector implements RAbstractDoubleVecto
         return data[i];
     }
 
+    @Override
     public double[] getDataCopy() {
-        double[] copy = new double[data.length];
-        System.arraycopy(data, 0, copy, 0, data.length);
-        return copy;
+        return Arrays.copyOf(data, data.length);
     }
 
     /**
      * Intended for external calls where a copy is not needed. WARNING: think carefully before using
      * this method rather than {@link #getDataCopy()}.
      */
+    @Override
     public double[] getDataWithoutCopying() {
         return data;
     }
 
-    /**
-     * Return vector data (copying if necessary) that's guaranteed not to be shared with any other
-     * vector instance (but maybe non-temporary in terms of vector's sharing mode).
-     *
-     * @return vector data
-     */
-    public double[] getDataNonShared() {
-        return isShared() ? getDataCopy() : getDataWithoutCopying();
-
-    }
-
-    /**
-     * Return vector data (copying if necessary) that's guaranteed to be "fresh" (temporary in terms
-     * of vector sharing mode).
-     *
-     * @return vector data
-     */
-    public double[] getDataTemp() {
-        return isTemporary() ? getDataWithoutCopying() : getDataCopy();
-    }
-
     @Override
     public RDoubleVector copyWithNewDimensions(int[] newDimensions) {
         return RDataFactory.createDoubleVector(data, isComplete(), newDimensions);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java
index 13c33c089a47b82c01249bebe597ba874f444d59..8c434b5af633b287c8aed8345d2e8fe4b6625689 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java
@@ -43,7 +43,7 @@ public class RExpression extends RListBase implements RAbstractVector {
     }
 
     @Override
-    public RVector materialize() {
+    public RVector<?> materialize() {
         return this;
     }
 
@@ -53,14 +53,14 @@ public class RExpression extends RListBase implements RAbstractVector {
     }
 
     @Override
-    protected RVector internalDeepCopy() {
+    protected RExpression internalDeepCopy() {
         // TOOD: only used for nested list updates, but still could be made faster (through a
         // separate AST node?)
         RExpression listCopy = new RExpression(Arrays.copyOf(data, data.length), dimensions, null);
         for (int i = 0; i < listCopy.getLength(); i++) {
             Object el = listCopy.getDataAt(i);
             if (el instanceof RVector) {
-                Object elCopy = ((RVector) el).deepCopy();
+                Object elCopy = ((RVector<?>) el).deepCopy();
                 listCopy.updateDataAt(i, elCopy, null);
             }
         }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java
index 38be9af40f36164d56587af36bcc06e2975c6444..3d7371741262d164a0cdcfba4648e9c701d8d472 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java
@@ -35,7 +35,7 @@ public final class RFactor {
      * Helper method to get 'levels' of a factor. However, all the invocations of this method should
      * be replaced with FactorNodes.GetLevel in the future.
      */
-    public static RVector getLevels(RAbstractIntVector factor) {
+    public static RVector<?> getLevels(RAbstractIntVector factor) {
         return getLevelsImpl(factor.getAttr(RRuntime.LEVELS_ATTR_KEY));
     }
 
@@ -43,12 +43,12 @@ public final class RFactor {
      * Helper method to get 'levels' of a factor with profile. However, all the invocations of this
      * method should be replaced with FactorNodes.GetLevel in the future.
      */
-    public static RVector getLevels(RAttributeProfiles profile, RAbstractIntVector factor) {
+    public static RVector<?> getLevels(RAttributeProfiles profile, RAbstractIntVector factor) {
         return getLevelsImpl(factor.getAttr(profile, RRuntime.LEVELS_ATTR_KEY));
     }
 
-    private static RVector getLevelsImpl(Object attr) {
-        // convert scalar to RVector if necessary
-        return attr instanceof RVector ? (RVector) attr : (RVector) RRuntime.asAbstractVector(attr);
+    private static RVector<?> getLevelsImpl(Object attr) {
+        // convert scalar to RVector<?>if necessary
+        return attr instanceof RVector ? (RVector<?>) attr : (RVector<?>) RRuntime.asAbstractVector(attr);
     }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RIntVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RIntVector.java
index 74e182b9cee2de064c08e037eea0ad49440e66dd..86815064d0156426a33bfeab77b202596f7a532c 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RIntVector.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RIntVector.java
@@ -33,7 +33,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 
-public final class RIntVector extends RVector implements RAbstractIntVector {
+public final class RIntVector extends RVector<int[]> implements RAbstractIntVector {
 
     public static final RStringVector implicitClassHeader = RDataFactory.createStringVectorFromScalar(RType.Integer.getClazz());
 
@@ -129,6 +129,7 @@ public final class RIntVector extends RVector implements RAbstractIntVector {
         return true;
     }
 
+    @Override
     public int[] getDataCopy() {
         return Arrays.copyOf(data, data.length);
     }
@@ -137,31 +138,11 @@ public final class RIntVector extends RVector implements RAbstractIntVector {
      * Intended for external calls where a copy is not needed. WARNING: think carefully before using
      * this method rather than {@link #getDataCopy()}.
      */
+    @Override
     public int[] getDataWithoutCopying() {
         return data;
     }
 
-    /**
-     * Return vector data (copying if necessary) that's guaranteed not to be shared with any other
-     * vector instance (but maybe non-temporary in terms of vector's sharing mode).
-     *
-     * @return vector data
-     */
-    public int[] getDataNonShared() {
-        return isShared() ? getDataCopy() : getDataWithoutCopying();
-
-    }
-
-    /**
-     * Return vector data (copying if necessary) that's guaranteed to be "fresh" (temporary in terms
-     * of vector sharing mode).
-     *
-     * @return vector data
-     */
-    public int[] getDataTemp() {
-        return isTemporary() ? getDataWithoutCopying() : getDataCopy();
-    }
-
     @Override
     public RIntVector copyWithNewDimensions(int[] newDimensions) {
         return RDataFactory.createIntVector(data, isComplete(), newDimensions);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java
index d2ca5dd64ad8f6571761d787cbd185ac630fc30d..dd97f6ea0d42c018c7089d82c5b38b1a1609dddd 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java
@@ -48,14 +48,14 @@ public final class RList extends RListBase implements RAbstractListVector {
     }
 
     @Override
-    protected RVector internalDeepCopy() {
+    protected RList internalDeepCopy() {
         // TOOD: only used for nested list updates, but still could be made faster (through a
         // separate AST node?)
         RList listCopy = new RList(Arrays.copyOf(data, data.length), dimensions, null);
         for (int i = 0; i < listCopy.getLength(); i++) {
             Object el = listCopy.getDataAt(i);
             if (el instanceof RVector) {
-                Object elCopy = ((RVector) el).deepCopy();
+                Object elCopy = ((RVector<?>) el).deepCopy();
                 listCopy.updateDataAt(i, elCopy, null);
             }
         }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RListBase.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RListBase.java
index 8879815c0700b33587e7acb0a108b4acd65f6787..d314603acd206c3a1518bd4b19492fc1005b7648 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RListBase.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RListBase.java
@@ -47,7 +47,7 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck;
  * {@code ExtractListElement}, which is a node that can extract an element of a list or abstract
  * vector and put it in the consistent sharing state.
  */
-public abstract class RListBase extends RVector implements RAbstractListBaseVector {
+public abstract class RListBase extends RVector<Object[]> implements RAbstractListBaseVector {
 
     protected final Object[] data;
 
@@ -99,37 +99,18 @@ public abstract class RListBase extends RVector implements RAbstractListBaseVect
      * Intended for external calls where a copy is not needed. WARNING: think carefully before using
      * this method rather than {@link #getDataCopy()}.
      */
+    @Override
     public final Object[] getDataWithoutCopying() {
         return data;
     }
 
+    @Override
     public final Object[] getDataCopy() {
         Object[] copy = new Object[data.length];
         System.arraycopy(data, 0, copy, 0, data.length);
         return copy;
     }
 
-    /**
-     * Return vector data (copying if necessary) that's guaranteed not to be shared with any other
-     * vector instance (but maybe non-temporary in terms of vector's sharing mode).
-     *
-     * @return vector data
-     */
-    public final Object[] getDataNonShared() {
-        return isShared() ? getDataCopy() : getDataWithoutCopying();
-
-    }
-
-    /**
-     * Return vector data (copying if necessary) that's guaranteed to be "fresh" (temporary in terms
-     * of vector sharing mode).
-     *
-     * @return vector data
-     */
-    public final Object[] getDataTemp() {
-        return isTemporary() ? getDataWithoutCopying() : getDataCopy();
-    }
-
     /**
      * Note: elements inside lists may be in inconsistent state reference counting wise. You may
      * need to put them into consistent state depending on what you use them for, consult the
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLogicalVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLogicalVector.java
index a492093eb77cf75441f3b9218fb7b370fb9fe891..ba99c8c7c13e7ca8ee8ab42b5ac0ecf74117b2d3 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLogicalVector.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLogicalVector.java
@@ -33,7 +33,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 
-public final class RLogicalVector extends RVector implements RAbstractLogicalVector {
+public final class RLogicalVector extends RVector<byte[]> implements RAbstractLogicalVector {
 
     public static final RStringVector implicitClassHeader = RDataFactory.createStringVectorFromScalar(RType.Logical.getClazz());
 
@@ -185,6 +185,7 @@ public final class RLogicalVector extends RVector implements RAbstractLogicalVec
         data[toIndex] = other.getDataAt(fromIndex);
     }
 
+    @Override
     public byte[] getDataCopy() {
         return Arrays.copyOf(data, data.length);
     }
@@ -193,31 +194,11 @@ public final class RLogicalVector extends RVector implements RAbstractLogicalVec
      * Intended for external calls where a copy is not needed. WARNING: think carefully before using
      * this method rather than {@link #getDataCopy()}.
      */
+    @Override
     public byte[] getDataWithoutCopying() {
         return data;
     }
 
-    /**
-     * Return vector data (copying if necessary) that's guaranteed not to be shared with any other
-     * vector instance (but maybe non-temporary in terms of vector's sharing mode).
-     *
-     * @return vector data
-     */
-    public byte[] getDataNonShared() {
-        return isShared() ? getDataCopy() : getDataWithoutCopying();
-
-    }
-
-    /**
-     * Return vector data (copying if necessary) that's guaranteed to be "fresh" (temporary in terms
-     * of vector sharing mode).
-     *
-     * @return vector data
-     */
-    public byte[] getDataTemp() {
-        return isTemporary() ? getDataWithoutCopying() : getDataCopy();
-    }
-
     @Override
     public RLogicalVector copyWithNewDimensions(int[] newDimensions) {
         return RDataFactory.createLogicalVector(data, isComplete(), newDimensions);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RRawVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RRawVector.java
index 01ef62b132ffb705df18b6646b7ca419a06e3da9..f8759c7fcd5f3345f3bdc82e62181f311f506d6e 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RRawVector.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RRawVector.java
@@ -33,7 +33,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
 
-public final class RRawVector extends RVector implements RAbstractRawVector {
+public final class RRawVector extends RVector<byte[]> implements RAbstractRawVector {
 
     public static final RStringVector implicitClassHeader = RDataFactory.createStringVectorFromScalar(RType.Raw.getClazz());
 
@@ -114,41 +114,20 @@ public final class RRawVector extends RVector implements RAbstractRawVector {
         return RDataFactory.createRaw(data[i]);
     }
 
+    @Override
     public byte[] getDataCopy() {
-        byte[] copy = new byte[data.length];
-        System.arraycopy(data, 0, copy, 0, data.length);
-        return copy;
+        return Arrays.copyOf(data, data.length);
     }
 
     /**
      * Intended for external calls where a copy is not needed. WARNING: think carefully before using
      * this method rather than {@link #getDataCopy()}.
      */
+    @Override
     public byte[] getDataWithoutCopying() {
         return data;
     }
 
-    /**
-     * Return vector data (copying if necessary) that's guaranteed not to be shared with any other
-     * vector instance (but maybe non-temporary in terms of vector's sharing mode).
-     *
-     * @return vector data
-     */
-    public byte[] getDataNonShared() {
-        return isShared() ? getDataCopy() : getDataWithoutCopying();
-
-    }
-
-    /**
-     * Return vector data (copying if necessary) that's guaranteed to be "fresh" (temporary in terms
-     * of vector sharing mode).
-     *
-     * @return vector data
-     */
-    public byte[] getDataTemp() {
-        return isTemporary() ? getDataWithoutCopying() : getDataCopy();
-    }
-
     @Override
     public RRawVector copyWithNewDimensions(int[] newDimensions) {
         return RDataFactory.createRawVector(data, newDimensions);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RScalarVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RScalarVector.java
index e12aed17f8fbb58a7789401701ae49a288788850..5019f8fe5220211227b7ca98b675088b54b1804b 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RScalarVector.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RScalarVector.java
@@ -141,8 +141,8 @@ public abstract class RScalarVector extends RScalar implements RAbstractVector {
     }
 
     @Override
-    public RVector copyResized(int size, boolean fillNA) {
-        RVector result = materialize().copyResized(size, fillNA);
+    public RVector<?> copyResized(int size, boolean fillNA) {
+        RVector<?> result = materialize().copyResized(size, fillNA);
         MemoryCopyTracer.reportCopying(this, result);
         return result;
     }
@@ -155,21 +155,21 @@ public abstract class RScalarVector extends RScalar implements RAbstractVector {
     }
 
     @Override
-    public RVector copyResizedWithDimensions(int[] newDimensions, boolean fillNA) {
-        RVector result = materialize().copyResizedWithDimensions(newDimensions, fillNA);
+    public RVector<?> copyResizedWithDimensions(int[] newDimensions, boolean fillNA) {
+        RVector<?> result = materialize().copyResizedWithDimensions(newDimensions, fillNA);
         MemoryCopyTracer.reportCopying(this, result);
         return result;
     }
 
     @Override
     public RAbstractVector copyDropAttributes() {
-        RVector result = materialize().copyDropAttributes();
+        RVector<?> result = materialize().copyDropAttributes();
         MemoryCopyTracer.reportCopying(this, result);
         return result;
     }
 
     @Override
-    public RVector createEmptySameType(int newLength, boolean newIsComplete) {
+    public RVector<?> createEmptySameType(int newLength, boolean newIsComplete) {
         return materialize().createEmptySameType(newLength, newIsComplete);
     }
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RSequence.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RSequence.java
index 75a022269b5c8b5057b02859a0d6f750d412e76b..d60927efc5a4df2f52b7c07f7e76cea6883903cc 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RSequence.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RSequence.java
@@ -79,13 +79,13 @@ public abstract class RSequence implements RAbstractVector {
         throw RInternalError.shouldNotReachHere();
     }
 
-    public final RVector createVector() {
-        RVector result = internalCreateVector();
+    public final RVector<?> createVector() {
+        RVector<?> result = internalCreateVector();
         MemoryCopyTracer.reportCopying(this, result);
         return result;
     }
 
-    protected abstract RVector internalCreateVector();
+    protected abstract RVector<?> internalCreateVector();
 
     @Override
     public final RAbstractVector copy() {
@@ -181,10 +181,10 @@ public abstract class RSequence implements RAbstractVector {
     }
 
     @Override
-    public final RVector copyResizedWithDimensions(int[] newDimensions, boolean fillNA) {
+    public final RVector<?> copyResizedWithDimensions(int[] newDimensions, boolean fillNA) {
         // TODO support for higher dimensions
         assert newDimensions.length == 2;
-        RVector result = copyResized(newDimensions[0] * newDimensions[1], fillNA);
+        RVector<?> result = copyResized(newDimensions[0] * newDimensions[1], fillNA);
         result.setDimensions(newDimensions);
         return result;
     }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RStringVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RStringVector.java
index 53f6667432c8ca54341247372fbab98b5a38f82f..4e14abc37f594f943838ddaf141ae2fc393861c7 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RStringVector.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RStringVector.java
@@ -34,7 +34,7 @@ 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;
 
-public final class RStringVector extends RVector implements RAbstractStringVector {
+public final class RStringVector extends RVector<String[]> implements RAbstractStringVector {
 
     public static final RStringVector implicitClassHeader = RDataFactory.createStringVectorFromScalar(RType.Character.getClazz());
 
@@ -89,6 +89,7 @@ public final class RStringVector extends RVector implements RAbstractStringVecto
         return data.length;
     }
 
+    @Override
     public String[] getDataCopy() {
         String[] copy = new String[data.length];
         System.arraycopy(data, 0, copy, 0, data.length);
@@ -99,31 +100,11 @@ public final class RStringVector extends RVector implements RAbstractStringVecto
      * Intended for external calls where a copy is not needed. WARNING: think carefully before using
      * this method rather than {@link #getDataCopy()}.
      */
+    @Override
     public String[] getDataWithoutCopying() {
         return data;
     }
 
-    /**
-     * Return vector data (copying if necessary) that's guaranteed not to be shared with any other
-     * vector instance (but maybe non-temporary in terms of vector's sharing mode).
-     *
-     * @return vector data
-     */
-    public String[] getDataNonShared() {
-        return isShared() ? getDataCopy() : getDataWithoutCopying();
-
-    }
-
-    /**
-     * Return vector data (copying if necessary) that's guaranteed to be "fresh" (temporary in terms
-     * of vector sharing mode).
-     *
-     * @return vector data
-     */
-    public String[] getDataTemp() {
-        return isTemporary() ? getDataWithoutCopying() : getDataCopy();
-    }
-
     @Override
     public String toString() {
         return toString(i -> getDataAt(i));
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java
index 7891a43ee87de06eb3c2b9c043feca6ecd957aa8..b29519d63f01d76f980ccef8c11ea8dd15e21a08 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java
@@ -54,7 +54,7 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck;
  * - non-shared => shared
  * </pre>
  */
-public abstract class RVector extends RSharingAttributeStorage implements RAbstractVector, RFFIAccess {
+public abstract class RVector<ArrayT> extends RSharingAttributeStorage implements RAbstractVector, RFFIAccess {
 
     private static final RStringVector implicitClassHeaderArray = RDataFactory.createStringVector(new String[]{RType.Array.getName()}, true);
     private static final RStringVector implicitClassHeaderMatrix = RDataFactory.createStringVector(new String[]{RType.Matrix.getName()}, true);
@@ -95,6 +95,37 @@ public abstract class RVector extends RSharingAttributeStorage implements RAbstr
         }
     }
 
+    /**
+     * Intended for external calls where a mutable copy is needed.
+     */
+    public abstract ArrayT getDataCopy();
+
+    /**
+     * Intended for external calls where a copy is not needed. WARNING: think carefully before using
+     * this method rather than {@link #getDataCopy()}.
+     */
+    public abstract ArrayT getDataWithoutCopying();
+
+    /**
+     * Return vector data (copying if necessary) that's guaranteed not to be shared with any other
+     * vector instance (but maybe non-temporary in terms of vector's sharing mode).
+     *
+     * @return vector data
+     */
+    public final ArrayT getDataNonShared() {
+        return isShared() ? getDataCopy() : getDataWithoutCopying();
+    }
+
+    /**
+     * Return vector data (copying if necessary) that's guaranteed to be "fresh" (temporary in terms
+     * of vector sharing mode).
+     *
+     * @return vector data
+     */
+    public final ArrayT getDataTemp() {
+        return isTemporary() ? getDataWithoutCopying() : getDataCopy();
+    }
+
     public final int[] getInternalDimensions() {
         return dimensions;
     }
@@ -499,11 +530,11 @@ public abstract class RVector extends RSharingAttributeStorage implements RAbstr
         return setClassAttrInternal(this, classAttr);
     }
 
-    public static RAbstractContainer setVectorClassAttr(RVector vector, RStringVector classAttr) {
+    public static RAbstractContainer setVectorClassAttr(RVector<?> vector, RStringVector classAttr) {
         return setClassAttrInternal(vector, classAttr);
     }
 
-    private static RAbstractContainer setClassAttrInternal(RVector vector, RStringVector classAttr) {
+    private static RAbstractContainer setClassAttrInternal(RVector<?> vector, RStringVector classAttr) {
         if (vector.attributes == null && classAttr != null && classAttr.getLength() != 0) {
             vector.initAttributes();
         }
@@ -534,7 +565,7 @@ public abstract class RVector extends RSharingAttributeStorage implements RAbstr
         return vector;
     }
 
-    public final void setAttributes(RVector result) {
+    public final void setAttributes(RVector<?> result) {
         result.names = this.names;
         result.dimNames = this.dimNames;
         result.rowNames = this.rowNames;
@@ -547,48 +578,47 @@ public abstract class RVector extends RSharingAttributeStorage implements RAbstr
     // public interface *copy* methods are final and delegate to *internalCopyAndReport* methods
 
     @Override
-    public final RVector copy() {
-        RVector result = internalCopyAndReport();
+    public final RVector<ArrayT> copy() {
+        RVector<ArrayT> result = internalCopyAndReport();
         setAttributes(result);
         result.setTypedValueInfo(getTypedValueInfo());
         return result;
     }
 
     @Override
-    public final RVector copyDropAttributes() {
-        RVector result = internalCopyAndReport();
-        return result;
+    public final RVector<ArrayT> copyDropAttributes() {
+        return internalCopyAndReport();
     }
 
     @Override
-    public final RVector deepCopy() {
-        RVector result = internalDeepCopyAndReport();
+    public final RVector<ArrayT> deepCopy() {
+        RVector<ArrayT> result = internalDeepCopyAndReport();
         setAttributes(result);
         return result;
     }
 
     @Override
-    public final RVector copyResized(int size, boolean fillNA) {
+    public final RVector<ArrayT> copyResized(int size, boolean fillNA) {
         return internalCopyResizedAndReport(size, fillNA);
     }
 
     // *internalCopyAndReport* methods do just the copy and report it to MemoryTracer. These should
     // be used if additional logic in public interface *copy* method is not desired.
 
-    protected final RVector internalCopyAndReport() {
-        RVector result = internalCopy();
+    protected final RVector<ArrayT> internalCopyAndReport() {
+        RVector<ArrayT> result = internalCopy();
         MemoryCopyTracer.reportCopying(this, result);
         return result;
     }
 
-    protected final RVector internalDeepCopyAndReport() {
-        RVector result = internalDeepCopy();
+    protected final RVector<ArrayT> internalDeepCopyAndReport() {
+        RVector<ArrayT> result = internalDeepCopy();
         MemoryCopyTracer.reportCopying(this, result);
         return result;
     }
 
-    protected final RVector internalCopyResizedAndReport(int size, boolean fillNA) {
-        RVector result = internalCopyResized(size, fillNA);
+    protected final RVector<ArrayT> internalCopyResizedAndReport(int size, boolean fillNA) {
+        RVector<ArrayT> result = internalCopyResized(size, fillNA);
         MemoryCopyTracer.reportCopying(this, result);
         return result;
     }
@@ -596,20 +626,20 @@ public abstract class RVector extends RSharingAttributeStorage implements RAbstr
     // *internalCopy* methods should only be overridden, but never invoked from anywhere but
     // *internalCopyAndReport*
 
-    protected abstract RVector internalCopyResized(int size, boolean fillNA);
+    protected abstract RVector<ArrayT> internalCopyResized(int size, boolean fillNA);
 
     // to be overridden by recursive structures
-    protected RVector internalDeepCopy() {
+    protected RVector<ArrayT> internalDeepCopy() {
         return internalCopy();
     }
 
-    protected abstract RVector internalCopy();
+    protected abstract RVector<ArrayT> internalCopy();
 
     @Override
-    public RVector copyResizedWithDimensions(int[] newDimensions, boolean fillNA) {
+    public RVector<ArrayT> copyResizedWithDimensions(int[] newDimensions, boolean fillNA) {
         // TODO support for higher dimensions
         assert newDimensions.length == 2;
-        RVector result = copyResized(newDimensions[0] * newDimensions[1], fillNA);
+        RVector<ArrayT> result = copyResized(newDimensions[0] * newDimensions[1], fillNA);
         result.setDimensions(newDimensions);
         return result;
     }
@@ -631,7 +661,7 @@ public abstract class RVector extends RSharingAttributeStorage implements RAbstr
      * @param naCheck NA check used to change vector's mode in case value is NA
      * @return updated vector
      */
-    public abstract RVector updateDataAtAsObject(int i, Object o, NACheck naCheck);
+    public abstract RVector<ArrayT> updateDataAtAsObject(int i, Object o, NACheck naCheck);
 
     public abstract void transferElementSameType(int toIndex, RAbstractVector fromVector, int fromIndex);
 
@@ -663,7 +693,7 @@ public abstract class RVector extends RSharingAttributeStorage implements RAbstr
      * Internal version without profiles used in a rare (and already slow) case of double-to-int
      * vector conversion when setting class attribute
      */
-    protected final RAttributable copyAttributesFrom(RVector vector) {
+    protected final RAttributable copyAttributesFrom(RVector<?> vector) {
         if (vector.getDimensions() == null || vector.getDimensions().length != 1) {
             this.names = vector.getNames();
         }
@@ -715,7 +745,7 @@ public abstract class RVector extends RSharingAttributeStorage implements RAbstr
     }
 
     @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "all three string constants below are supposed to be used as identities")
-    public final RVector copyRegAttributesFrom(RAbstractContainer vector) {
+    public final RVector<ArrayT> copyRegAttributesFrom(RAbstractContainer vector) {
         RAttributes orgAttributes = vector.getAttributes();
         if (orgAttributes != null) {
             Object newRowNames = null;
@@ -735,13 +765,13 @@ public abstract class RVector extends RSharingAttributeStorage implements RAbstr
     }
 
     @Override
-    public final RVector resize(int size) {
+    public final RVector<ArrayT> resize(int size) {
         return resize(size, true);
     }
 
-    private RVector resize(int size, boolean resetAll) {
+    private RVector<ArrayT> resize(int size, boolean resetAll) {
         this.complete &= getLength() >= size;
-        RVector res = this;
+        RVector<ArrayT> res = this;
         RStringVector oldNames = res.names;
         res = copyResized(size, true);
         if (this.isShared()) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RAbstactVectorToListClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RAbstactVectorToListClosure.java
index 5dcf20f16b109589293423bb8478badef215202a..4d076c044ef7f3d59ad3b6f6ffc59ef547bcac07 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RAbstactVectorToListClosure.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RAbstactVectorToListClosure.java
@@ -64,7 +64,7 @@ final class RAbstactVectorToListClosure extends RToVectorClosure implements RAbs
     }
 
     @Override
-    public RVector createEmptySameType(int newLength, boolean newIsComplete) {
+    public RVector<?> createEmptySameType(int newLength, boolean newIsComplete) {
         return RDataFactory.createList(new Object[newLength]);
     }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RClosures.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RClosures.java
index 0d9694e313d36adbf84fb6ce1624337608f43055..1d75a18aa146d5ad1190a62f10bfa26af0c40fd9 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RClosures.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RClosures.java
@@ -124,7 +124,7 @@ public class RClosures {
         return createFactorToVector(factor, withNames, RFactor.getLevels(attrProfiles, factor));
     }
 
-    public static RAbstractVector createFactorToVector(RAbstractIntVector factor, boolean withNames, RVector levels) {
+    public static RAbstractVector createFactorToVector(RAbstractIntVector factor, boolean withNames, RVector<?> levels) {
         if (levels == null) {
             return new RFactorToStringVectorClosure(factor, null, withNames);
         } else {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToComplexVectorClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToComplexVectorClosure.java
index a8ce9efae4859ce2a4c8ff947d12b6f319bc27c5..e469c8b0d07608030b4d8dc22e2a7f7e305dca14 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToComplexVectorClosure.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToComplexVectorClosure.java
@@ -36,7 +36,7 @@ abstract class RToComplexVectorClosure extends RToVectorClosure implements RAbst
     }
 
     @Override
-    public final RVector createEmptySameType(int newLength, boolean newIsComplete) {
+    public final RVector<?> createEmptySameType(int newLength, boolean newIsComplete) {
         return RDataFactory.createComplexVector(new double[newLength << 1], newIsComplete);
     }
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToDoubleVectorClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToDoubleVectorClosure.java
index e944259d249657ac2748e987aff3858f2309c163..55cc0daa12f45425c6a32fe8a291a56f0b9d5b64 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToDoubleVectorClosure.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToDoubleVectorClosure.java
@@ -35,7 +35,7 @@ abstract class RToDoubleVectorClosure extends RToVectorClosure implements RAbstr
     }
 
     @Override
-    public final RVector createEmptySameType(int newLength, boolean newIsComplete) {
+    public final RVector<?> createEmptySameType(int newLength, boolean newIsComplete) {
         return RDataFactory.createDoubleVector(new double[newLength], newIsComplete);
     }
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToIntVectorClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToIntVectorClosure.java
index 5c8c44c7d7e9ebcb66d6f57e2a8810b00934c449..132946950c1687bf8b1a42f9b3ca342a1f4aba19 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToIntVectorClosure.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToIntVectorClosure.java
@@ -35,7 +35,7 @@ abstract class RToIntVectorClosure extends RToVectorClosure implements RAbstract
     }
 
     @Override
-    public final RVector createEmptySameType(int newLength, boolean newIsComplete) {
+    public final RVector<?> createEmptySameType(int newLength, boolean newIsComplete) {
         return RDataFactory.createIntVector(new int[newLength], newIsComplete);
     }
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToStringVectorClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToStringVectorClosure.java
index d907512a2306025b524026cda648d144a469049a..38d3cbeca01fc6ce77e782bd95ef49b6aef2fbf0 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToStringVectorClosure.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToStringVectorClosure.java
@@ -35,7 +35,7 @@ abstract class RToStringVectorClosure extends RToVectorClosure implements RAbstr
     }
 
     @Override
-    public final RVector createEmptySameType(int newLength, boolean newIsComplete) {
+    public final RVector<?> createEmptySameType(int newLength, boolean newIsComplete) {
         return RDataFactory.createStringVector(new String[newLength], newIsComplete);
     }
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToVectorClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToVectorClosure.java
index 99383ff1a2bf7e9f9c5afd5ed0158a00ffb02835..8c385a8fcc75d1697bd33b8e414738b79957d6fd 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToVectorClosure.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RToVectorClosure.java
@@ -134,17 +134,17 @@ abstract class RToVectorClosure implements RAbstractVector {
     }
 
     @Override
-    public final RVector copyResized(int size, boolean fillNA) {
-        RVector result = vector.copyResized(size, fillNA);
+    public final RVector<?> copyResized(int size, boolean fillNA) {
+        RVector<?> result = vector.copyResized(size, fillNA);
         MemoryCopyTracer.reportCopying(this, result);
         return result;
     }
 
     @Override
-    public final RVector copyResizedWithDimensions(int[] newDimensions, boolean fillNA) {
+    public final RVector<?> copyResizedWithDimensions(int[] newDimensions, boolean fillNA) {
         // TODO support for higher dimensions
         assert newDimensions.length == 2;
-        RVector result = copyResized(newDimensions[0] * newDimensions[1], fillNA);
+        RVector<?> result = copyResized(newDimensions[0] * newDimensions[1], fillNA);
         result.setDimensions(newDimensions);
         return result;
     }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractVector.java
index a9b3eebf0606c05d5a434500e994a5ab907cc38c..a6e9a39c047cdb9a796219423e685ed5345f5f8e 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractVector.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractVector.java
@@ -43,17 +43,17 @@ public interface RAbstractVector extends RAbstractContainer {
         return copy();
     }
 
-    RVector copyResized(int size, boolean fillNA);
+    RVector<?> copyResized(int size, boolean fillNA);
 
     RAbstractVector copyWithNewDimensions(int[] newDimensions);
 
-    RVector copyResizedWithDimensions(int[] newDimensions, boolean fillNA);
+    RVector<?> copyResizedWithDimensions(int[] newDimensions, boolean fillNA);
 
     RAbstractVector copyDropAttributes();
 
-    RVector createEmptySameType(int newLength, boolean newIsComplete);
+    RVector<?> createEmptySameType(int newLength, boolean newIsComplete);
 
-    RVector materialize();
+    RVector<?> materialize();
 
     boolean isMatrix();