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 d84e75629f1a8fbc967095b3a3efc5c1a45f1a93..5aba159019d3194b3c76929e6bd35575d961e451 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
@@ -51,8 +51,11 @@ public final class RComplexVector extends RVector<double[]> implements RAbstract
 
     @Override
     protected RComplexVector internalCopy() {
-        assert data != null;
-        return new RComplexVector(Arrays.copyOf(data, data.length), this.isComplete());
+        if (data != null) {
+            return new RComplexVector(Arrays.copyOf(data, data.length), this.isComplete());
+        } else {
+            return new RComplexVector(NativeDataAccess.copyDoubleNativeData(getNativeMirror()), this.isComplete(), null);
+        }
     }
 
     @Override
@@ -120,20 +123,25 @@ public final class RComplexVector extends RVector<double[]> implements RAbstract
 
     @Override
     public double[] getDataCopy() {
-        assert data != null;
-        return Arrays.copyOf(data, data.length);
+        if (data != null) {
+            return Arrays.copyOf(data, data.length);
+        } else {
+            return NativeDataAccess.copyDoubleNativeData(getNativeMirror());
+        }
     }
 
     @Override
     public double[] getReadonlyData() {
-        assert data != null;
-        return data;
+        if (data != null) {
+            return data;
+        } else {
+            return NativeDataAccess.copyDoubleNativeData(getNativeMirror());
+        }
     }
 
     @Override
     public RComplexVector copyWithNewDimensions(int[] newDimensions) {
-        assert data != null;
-        return RDataFactory.createComplexVector(data, isComplete(), newDimensions);
+        return RDataFactory.createComplexVector(getReadonlyData(), isComplete(), newDimensions);
     }
 
     private RComplexVector updateDataAt(int index, RComplex value, NACheck rightNACheck) {
@@ -152,9 +160,8 @@ public final class RComplexVector extends RVector<double[]> implements RAbstract
     }
 
     private double[] copyResizedData(int size, boolean fillNA) {
-        assert data != null;
         int csize = size << 1;
-        double[] newData = Arrays.copyOf(data, csize);
+        double[] newData = Arrays.copyOf(getReadonlyData(), csize);
         if (csize > this.getLength()) {
             if (fillNA) {
                 for (int i = data.length; i < size; i++) {
@@ -172,8 +179,7 @@ public final class RComplexVector extends RVector<double[]> implements RAbstract
 
     @Override
     protected RComplexVector internalCopyResized(int size, boolean fillNA, int[] dimensions) {
-        assert data != null;
-        boolean isComplete = isComplete() && ((data.length >= size) || !fillNA);
+        boolean isComplete = isComplete() && ((getLength() >= size) || !fillNA);
         return RDataFactory.createComplexVector(copyResizedData(size, fillNA), isComplete, dimensions);
     }
 
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 b14fb519c88aad3e608ee5b598334bd6090f1998..c5bfb51de748e6c643f1ae338c3ff02a26a07935 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
@@ -68,8 +68,7 @@ public final class RDoubleVector extends RVector<double[]> implements RAbstractD
 
     @Override
     protected RDoubleVector internalCopy() {
-        assert data != null;
-        return new RDoubleVector(Arrays.copyOf(data, data.length), this.isComplete());
+        return new RDoubleVector(getDataCopy(), this.isComplete());
     }
 
     @Override
@@ -136,20 +135,25 @@ public final class RDoubleVector extends RVector<double[]> implements RAbstractD
 
     @Override
     public double[] getDataCopy() {
-        assert data != null;
-        return Arrays.copyOf(data, data.length);
+        if (data != null) {
+            return Arrays.copyOf(data, data.length);
+        } else {
+            return NativeDataAccess.copyDoubleNativeData(getNativeMirror());
+        }
     }
 
     @Override
     public double[] getReadonlyData() {
-        assert data != null;
-        return data;
+        if (data != null) {
+            return data;
+        } else {
+            return NativeDataAccess.copyDoubleNativeData(getNativeMirror());
+        }
     }
 
     @Override
     public RDoubleVector copyWithNewDimensions(int[] newDimensions) {
-        assert data != null;
-        return RDataFactory.createDoubleVector(data, isComplete(), newDimensions);
+        return RDataFactory.createDoubleVector(getReadonlyData(), isComplete(), newDimensions);
     }
 
     public RDoubleVector updateDataAt(int index, double value, NACheck valueNACheck) {
@@ -184,15 +188,13 @@ public final class RDoubleVector extends RVector<double[]> implements RAbstractD
     }
 
     private double[] copyResizedData(int size, boolean fillNA) {
-        assert data != null;
-        double[] newData = Arrays.copyOf(data, size);
+        double[] newData = Arrays.copyOf(getReadonlyData(), size);
         return resizeData(newData, this.data, this.getLength(), fillNA);
     }
 
     @Override
     protected RDoubleVector internalCopyResized(int size, boolean fillNA, int[] dimensions) {
-        assert data != null;
-        boolean isComplete = isComplete() && ((data.length >= size) || !fillNA);
+        boolean isComplete = isComplete() && ((getLength() >= size) || !fillNA);
         return RDataFactory.createDoubleVector(copyResizedData(size, fillNA), isComplete, dimensions);
     }
 
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 bb21a383242e321095bbf9ff51512b3a8c19ef0e..a974ca745be12443883289e745d08a044b9efeb2 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
@@ -91,8 +91,11 @@ public final class RIntVector extends RVector<int[]> implements RAbstractIntVect
 
     @Override
     protected RIntVector internalCopy() {
-        assert data != null;
-        return new RIntVector(Arrays.copyOf(data, data.length), isComplete());
+        if (data != null) {
+            return new RIntVector(Arrays.copyOf(data, data.length), isComplete());
+        } else {
+            return new RIntVector(getDataCopy(), isComplete());
+        }
     }
 
     public RIntVector copyResetData(int[] newData) {
@@ -132,8 +135,11 @@ public final class RIntVector extends RVector<int[]> implements RAbstractIntVect
 
     @Override
     public int[] getDataCopy() {
-        assert data != null;
-        return Arrays.copyOf(data, data.length);
+        if (data != null) {
+            return Arrays.copyOf(data, data.length);
+        } else {
+            return NativeDataAccess.copyIntNativeData(getNativeMirror());
+        }
     }
 
     @Override
@@ -143,14 +149,16 @@ public final class RIntVector extends RVector<int[]> implements RAbstractIntVect
 
     @Override
     public int[] getReadonlyData() {
-        assert data != null;
-        return data;
+        if (data != null) {
+            return data;
+        } else {
+            return NativeDataAccess.copyIntNativeData(getNativeMirror());
+        }
     }
 
     @Override
     public RIntVector copyWithNewDimensions(int[] newDimensions) {
-        assert data != null;
-        return RDataFactory.createIntVector(data, isComplete(), newDimensions);
+        return RDataFactory.createIntVector(getReadonlyData(), isComplete(), newDimensions);
     }
 
     public RIntVector updateDataAt(int index, int value, NACheck valueNACheck) {
@@ -185,15 +193,13 @@ public final class RIntVector extends RVector<int[]> implements RAbstractIntVect
     }
 
     private int[] copyResizedData(int size, boolean fillNA) {
-        assert data != null;
-        int[] newData = Arrays.copyOf(data, size);
+        int[] newData = Arrays.copyOf(getReadonlyData(), size);
         return resizeData(newData, this.data, this.getLength(), fillNA);
     }
 
     @Override
     protected RIntVector internalCopyResized(int size, boolean fillNA, int[] dimensions) {
-        assert data != null;
-        boolean isComplete = isComplete() && ((data.length >= size) || !fillNA);
+        boolean isComplete = isComplete() && ((getLength() >= size) || !fillNA);
         return RDataFactory.createIntVector(copyResizedData(size, fillNA), isComplete, dimensions);
     }
 
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 0eee40bd3acf6cad1eb87e06bf94fb9131bcee43..a96573dad51fa7e73df8b3f471c9b3453dfa84f7 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
@@ -93,8 +93,11 @@ public final class RLogicalVector extends RVector<byte[]> implements RAbstractLo
 
     @Override
     protected RLogicalVector internalCopy() {
-        assert data != null;
-        return new RLogicalVector(Arrays.copyOf(data, data.length), isComplete());
+        if (data != null) {
+            return new RLogicalVector(Arrays.copyOf(data, data.length), isComplete());
+        } else {
+            return new RLogicalVector(getNativeDataCopy(), isComplete());
+        }
     }
 
     public RLogicalVector copyResetData(byte[] newData) {
@@ -154,8 +157,7 @@ public final class RLogicalVector extends RVector<byte[]> implements RAbstractLo
     }
 
     private byte[] copyResizedData(int size, boolean fillNA) {
-        assert data != null;
-        byte[] newData = Arrays.copyOf(data, size);
+        byte[] newData = Arrays.copyOf(getReadonlyData(), size);
         if (size > this.getLength()) {
             if (fillNA) {
                 for (int i = data.length; i < size; i++) {
@@ -188,20 +190,25 @@ public final class RLogicalVector extends RVector<byte[]> implements RAbstractLo
 
     @Override
     public byte[] getDataCopy() {
-        assert data != null;
-        return Arrays.copyOf(data, data.length);
+        if (data != null) {
+            return Arrays.copyOf(data, data.length);
+        } else {
+            return getNativeDataCopy();
+        }
     }
 
     @Override
     public byte[] getReadonlyData() {
-        assert data != null;
-        return data;
+        if (data != null) {
+            return data;
+        } else {
+            return getNativeDataCopy();
+        }
     }
 
     @Override
     public RLogicalVector copyWithNewDimensions(int[] newDimensions) {
-        assert data != null;
-        return RDataFactory.createLogicalVector(data, isComplete(), newDimensions);
+        return RDataFactory.createLogicalVector(getReadonlyData(), isComplete(), newDimensions);
     }
 
     @Override
@@ -222,4 +229,14 @@ public final class RLogicalVector extends RVector<byte[]> implements RAbstractLo
             complete = false;
         }
     }
+
+    private byte[] getNativeDataCopy() {
+        assert data == null;
+        int length = getLength();
+        byte[] result = new byte[length];
+        for (int i = 0; i < length; i++) {
+            result[i] = getDataAt(i);
+        }
+        return result;
+    }
 }
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 5771c618e3554fdbe2ce03fc7564a3a2245d9deb..8e12c79aab3b58aa77d22c69cd248f678434a241 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
@@ -73,6 +73,7 @@ public final class RRawVector extends RVector<byte[]> implements RAbstractRawVec
 
     @Override
     public byte[] getInternalStore() {
+        assert data != null;
         return data;
     }
 
@@ -100,8 +101,11 @@ public final class RRawVector extends RVector<byte[]> implements RAbstractRawVec
 
     @Override
     protected RRawVector internalCopy() {
-        assert data != null;
-        return new RRawVector(Arrays.copyOf(data, data.length));
+        if (data != null) {
+            return new RRawVector(Arrays.copyOf(data, data.length));
+        } else {
+            return new RRawVector(NativeDataAccess.copyByteNativeData(getNativeMirror()));
+        }
     }
 
     @Override
@@ -121,20 +125,25 @@ public final class RRawVector extends RVector<byte[]> implements RAbstractRawVec
 
     @Override
     public byte[] getDataCopy() {
-        assert data != null;
-        return Arrays.copyOf(data, data.length);
+        if (data != null) {
+            return Arrays.copyOf(data, data.length);
+        } else {
+            return NativeDataAccess.copyByteNativeData(getNativeMirror());
+        }
     }
 
     @Override
     public byte[] getReadonlyData() {
-        assert data != null;
-        return data;
+        if (data != null) {
+            return data;
+        } else {
+            return NativeDataAccess.copyByteNativeData(getNativeMirror());
+        }
     }
 
     @Override
     public RRawVector copyWithNewDimensions(int[] newDimensions) {
-        assert data != null;
-        return RDataFactory.createRawVector(data, newDimensions);
+        return RDataFactory.createRawVector(getReadonlyData(), newDimensions);
     }
 
     @Override
@@ -154,8 +163,7 @@ public final class RRawVector extends RVector<byte[]> implements RAbstractRawVec
     }
 
     private byte[] copyResizedData(int size, boolean fillNA) {
-        assert data != null;
-        byte[] newData = Arrays.copyOf(data, size);
+        byte[] newData = Arrays.copyOf(getReadonlyData(), size);
         if (!fillNA) {
             // NA is 00 for raw
             for (int i = data.length, j = 0; i < size; ++i, j = Utils.incMod(j, data.length)) {
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 71f6d47c49f979d040449e7f9f0384763c502cab..3237fd6d0a6c2f1cedf69358c78692cbd5a8ea76 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
@@ -45,6 +45,8 @@ public interface RAbstractVector extends RAbstractContainer {
 
     RVector<?> copyResized(int size, boolean fillNA);
 
+    // TODO: this does not say anything about reference counting? It seems that its used wrongly
+    // w.r.t. reference counting.
     RAbstractVector copyWithNewDimensions(int[] newDimensions);
 
     RVector<?> copyResizedWithDimensions(int[] newDimensions, boolean fillNA);