diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
index 402de62792e574b1d89a69ec7b8d5d085fc7a395..aa4d7456088d10aeb2159d5c7b9f980a149a602d 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
@@ -33,11 +33,11 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.api.source.*;
 import com.oracle.truffle.r.library.graphics.*;
 import com.oracle.truffle.r.nodes.*;
 import com.oracle.truffle.r.nodes.builtin.*;
+import com.oracle.truffle.r.nodes.control.*;
 import com.oracle.truffle.r.nodes.function.*;
 import com.oracle.truffle.r.nodes.instrument.*;
 import com.oracle.truffle.r.nodes.runtime.*;
@@ -197,8 +197,10 @@ public final class REngine implements RContext.Engine {
 
     public Object parseAndEvalTest(String rscript, boolean printResult) {
         // We first remove all the definitions from the previous test
-        String rm = "rm(list = ls())";
-        parseAndEvalImpl(new ANTLRStringStream(rm), Source.fromText(rm, "<test_reset>"), REnvironment.globalEnv().getFrame(), printResult, false);
+        MaterializedFrame globalFrame = REnvironment.globalEnv().getFrame();
+        for (FrameSlot slot : globalFrame.getFrameDescriptor().getSlots()) {
+            FrameSlotChangeMonitor.setObjectAndInvalidate(globalFrame, slot, null, true, null);
+        }
         return parseAndEvalImpl(new ANTLRStringStream(rscript), Source.fromText(rscript, "<test_input>"), REnvironment.globalEnv().getFrame(), printResult, false);
     }
 
@@ -404,7 +406,7 @@ public final class REngine implements RContext.Engine {
             } catch (ReturnException ex) {
                 // condition handling can cause a "return" that needs to skip over this call
                 throw ex;
-            } catch (ControlFlowException cfe) {
+            } catch (BreakException | NextException cfe) {
                 throw RError.error(RError.Message.NO_LOOP_FOR_BREAK_NEXT);
             }
             assert checkResult(result);
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java
index 7d444bfd0acad6d048f886c67ad5abeb2ef37e20..27b13c2c98dae9932eadb4a3e930a871461b7173 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java
@@ -152,7 +152,7 @@ public class TypeConvert {
                 }
             }
             RIntVector res = RDataFactory.createIntVector(data, complete);
-            res.setLevels(RDataFactory.createStringVector(levelsArray, RDataFactory.COMPLETE_VECTOR));
+            res.setAttr(RRuntime.LEVELS_ATTR_KEY, RDataFactory.createStringVector(levelsArray, RDataFactory.COMPLETE_VECTOR));
             return RVector.setVectorClassAttr(res, RDataFactory.createStringVector("factor"), null, null);
         }
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java
index 9d5c13dcfe9ae8913ad999c075e9bf081fffe569..63a74e0b054c9a60734a35dd9c2a2edba786e285 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java
@@ -29,8 +29,6 @@ import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.DispatchType;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.NoGenericMethodException;
 import com.oracle.truffle.r.nodes.unary.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
@@ -45,7 +43,7 @@ public abstract class AsCharacter extends RBuiltinNode {
     private static final String NAME = "as.character";
 
     @Child private CastStringNode castStringNode;
-    @Child private DispatchedCallNode dcn;
+    @Child private UseMethodInternalNode dcn;
     private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
     public abstract Object execute(VirtualFrame frame, Object obj);
@@ -149,17 +147,17 @@ public abstract class AsCharacter extends RBuiltinNode {
         controlVisibility();
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(DispatchedCallNode.create(NAME, DispatchType.UseMethod, getSuppliedSignature()));
+            dcn = insert(new UseMethodInternalNode(NAME, getSuppliedSignature()));
         }
         try {
-            return dcn.executeInternal(frame, container.getClassHierarchy(), new Object[]{container});
-        } catch (NoGenericMethodException e) {
+            return dcn.execute(frame, container.getClassHierarchy(), new Object[]{container});
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             return castStringVector(frame, container);
         }
     }
 
     @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "generic name is interned in the interpreted code for faster comparison")
     protected boolean isObject(VirtualFrame frame, RAbstractContainer container) {
-        return container.isObject(attrProfiles) && !(RArguments.hasS3Args(frame) && RArguments.getS3Generic(frame) == NAME);
+        return container.isObject(attrProfiles) && !(RArguments.getS3Args(frame) != null && RArguments.getS3Args(frame).generic == NAME);
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
index 4f495dc9f16e2436798ef63c240f72f84575de98..3e377af3c6f16bb0585b08a59b2722538fe115d0 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
@@ -200,7 +200,7 @@ public abstract class AsVector extends RBuiltinNode {
 
     @Specialization(guards = "modeIsAny(mode)")
     protected RAbstractVector asVector(RFactor x, @SuppressWarnings("unused") String mode) {
-        RVector levels = x.getLevels();
+        RVector levels = x.getLevels(attrProfiles);
         RVector result = levels.createEmptySameType(x.getLength(), RDataFactory.COMPLETE_VECTOR);
         RIntVector factorData = x.getVector();
         for (int i = 0; i < result.getLength(); i++) {
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 cd4c4205231efa5a3522441521d47fcbad80e888..e95708b3a9e909e29cadf74824c9616b64ce476b 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
@@ -34,8 +34,6 @@ import com.oracle.truffle.api.utilities.*;
 import com.oracle.truffle.r.nodes.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.DispatchType;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.NoGenericMethodException;
 import com.oracle.truffle.r.nodes.unary.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
@@ -45,7 +43,7 @@ import com.oracle.truffle.r.runtime.ops.na.*;
 public abstract class Bind extends RPrecedenceBuiltinNode {
 
     @Child private CastToVectorNode castVector;
-    @Child private DispatchedCallNode dcn;
+    @Child private UseMethodInternalNode dcn;
 
     private final ConditionProfile nullNamesProfile = ConditionProfile.createBinaryProfile();
     private final ConditionProfile emptyVectorProfile = ConditionProfile.createBinaryProfile();
@@ -80,11 +78,11 @@ public abstract class Bind extends RPrecedenceBuiltinNode {
     protected Object allDataFrame(VirtualFrame frame, Object deparseLevel, RArgsValuesAndNames args) {
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(DispatchedCallNode.create(getBindType(), DispatchType.UseMethod, SIGNATURE));
+            dcn = insert(new UseMethodInternalNode(getBindType(), SIGNATURE));
         }
         try {
-            return dcn.executeInternal(frame, ((RDataFrame) args.getValues()[0]).getClassHierarchy(), new Object[]{deparseLevel, args});
-        } catch (NoGenericMethodException e) {
+            return dcn.execute(frame, ((RDataFrame) args.getValues()[0]).getClassHierarchy(), new Object[]{deparseLevel, args});
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             throw RInternalError.shouldNotReachHere();
         }
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BitwiseFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BitwiseFunctions.java
index edd19ce8ab148e7de612d8c524f77ea2dff9c9ce..1bc7cb008f9e2842151a55187e45ddd3d13b7042 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BitwiseFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BitwiseFunctions.java
@@ -79,7 +79,7 @@ public class BitwiseFunctions {
                                 ans[i] = RRuntime.INT_NA;
                                 completeVector = false;
                             } else {
-                                ans[i] = aVal >> bVal;
+                                ans[i] = aVal >>> bVal;
                             }
                             break;
                         case SHIFTL:
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ClassHierarchyNode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ClassHierarchyNode.java
index ecf7d55fa8f36806d277e23120eac61747e925cb..100e36045f5d406ceb2d192d206dab1fec97eb56 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ClassHierarchyNode.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ClassHierarchyNode.java
@@ -24,6 +24,7 @@ package com.oracle.truffle.r.nodes.builtin.base;
 
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.r.nodes.builtin.base.S3DispatchFunctions.UseMethod;
 import com.oracle.truffle.r.nodes.unary.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.conn.*;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java
index 0acc08332c2260bd1353bab831acbe51c2481bff..832b669b4daca330c8d4e2aea7c6516e0ea0600c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java
@@ -107,7 +107,7 @@ public class DatePOSIXFunctions {
                 }
             }
             RList result = RDataFactory.createList(data, LT_NAMES_VEC);
-            result.setClassAttr(CLASS_ATTR);
+            result.setClassAttr(CLASS_ATTR, false);
             result.setAttr("tzone", "UTC");
             RStringVector xNames = x.getNames(attrProfiles);
             if (xNames != null) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java
index a458b80f48f29bcfc587993bd249bc27d263aaa9..266d4e48cb48c759de129f74cd641bdfd14a481c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java
@@ -30,8 +30,7 @@ import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.r.nodes.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.DispatchType;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.NoGenericMethodException;
+import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode.NoGenericMethodException;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
@@ -45,7 +44,7 @@ public abstract class Dim extends RBuiltinNode {
     private static final String NAME = "dim";
 
     @Child private ShortRowNames shortRowNames;
-    @Child private DispatchedCallNode dcn;
+    @Child private UseMethodInternalNode dcn;
 
     private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
@@ -98,11 +97,11 @@ public abstract class Dim extends RBuiltinNode {
         controlVisibility();
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(DispatchedCallNode.create(NAME, DispatchType.UseMethod, getSuppliedSignature()));
+            dcn = insert(new UseMethodInternalNode(NAME, getSuppliedSignature()));
         }
         try {
-            return dcn.executeInternal(frame, container.getClassHierarchy(), new Object[]{container});
-        } catch (NoGenericMethodException e) {
+            return dcn.execute(frame, container.getClassHierarchy(), new Object[]{container});
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             return hasDimensions(container) ? dimWithDimensions(frame, container) : RNull.instance;
         }
 
@@ -114,7 +113,7 @@ public abstract class Dim extends RBuiltinNode {
 
     @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "generic name is interned in the interpreted code for faster comparison")
     protected boolean isObject(VirtualFrame frame, RAbstractContainer container) {
-        return container.isObject(attrProfiles) && !(RArguments.hasS3Args(frame) && RArguments.getS3Generic(frame) == NAME);
+        return container.isObject(attrProfiles) && !(RArguments.getS3Args(frame) != null && RArguments.getS3Args(frame).generic == NAME);
     }
 
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java
index a4880dd23caed4b5f7830564447233dd8b159214..08ee66b2485f59a4d4df569b8038e0e81e73c293 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java
@@ -29,7 +29,6 @@ import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
@@ -41,7 +40,7 @@ public abstract class DimNames extends RBuiltinNode {
 
     private static final String NAME = "dimnames";
 
-    @Child private DispatchedCallNode dcn;
+    @Child private UseMethodInternalNode dcn;
 
     private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
@@ -69,11 +68,11 @@ public abstract class DimNames extends RBuiltinNode {
         controlVisibility();
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(DispatchedCallNode.create(NAME, DispatchType.UseMethod, getSuppliedSignature()));
+            dcn = insert(new UseMethodInternalNode(NAME, getSuppliedSignature()));
         }
         try {
-            return dcn.executeInternal(frame, container.getClassHierarchy(), new Object[]{container});
-        } catch (NoGenericMethodException e) {
+            return dcn.execute(frame, container.getClassHierarchy(), new Object[]{container});
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             return isNull(container) ? RNull.instance : container.getDimNames();
         }
     }
@@ -84,7 +83,7 @@ public abstract class DimNames extends RBuiltinNode {
 
     @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "generic name is interned in the interpreted code for faster comparison")
     protected boolean isObject(VirtualFrame frame, RAbstractContainer container) {
-        return container.isObject(attrProfiles) && !(RArguments.hasS3Args(frame) && RArguments.getS3Generic(frame) == NAME);
+        return container.isObject(attrProfiles) && !(RArguments.getS3Args(frame) != null && RArguments.getS3Args(frame).generic == NAME);
     }
 
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java
index 22e697e1b77f39e20b2b7623ecf0f2ec53c3ebf9..c78f3c64104e9877508a8368db35a7ef06dd09ca 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java
@@ -98,7 +98,7 @@ public class DynLoadFunctions {
                 data[i] = dllInfo.toRList();
             }
             RList result = RDataFactory.createList(data, RDataFactory.createStringVector(names, RDataFactory.COMPLETE_VECTOR));
-            result.setClassAttr(RDataFactory.createStringVectorFromScalar(DLLINFOLIST_CLASS));
+            result.setClassAttr(RDataFactory.createStringVectorFromScalar(DLLINFOLIST_CLASS), false);
             return result;
         }
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java
index 5cddf7dc366744b7377f58fa7020d27d6040f930..9e5412f5b562ed11e74ce7b196d37d897304a87f 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java
@@ -194,7 +194,7 @@ public class FileFunctions {
              * the information. The R closure that called the .Internal turns the result into a
              * dataframe and sets the row.names attributes to the paths in vec. It also updates the
              * mtime, ctime, atime fields using .POSIXct.
-             * 
+             *
              * We try to use the JDK classes, even though they provide a more abstract interface
              * than R. In particular there seems to be no way to get the uid/gid values. We might be
              * better off justing using a native call.
@@ -334,7 +334,7 @@ public class FileFunctions {
             switch(column) {
                 case size: return RDataFactory.createDoubleVector((double[]) data, complete);
                 case isdir: return RDataFactory.createLogicalVector((byte[]) data, complete);
-                case mode: RIntVector res = RDataFactory.createIntVector((int[]) data, complete); res.setClassAttr(OCTMODE); return res;
+                case mode: RIntVector res = RDataFactory.createIntVector((int[]) data, complete); res.setClassAttr(OCTMODE, false); return res;
                 case mtime: case ctime: case atime:
                 case uid: case gid: return RDataFactory.createIntVector((int[]) data, complete);
                 case uname: case grname: return RDataFactory.createStringVector((String[]) data, complete);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
index 73fdf88beccf75673f4636f2a07505de0a3db2ae..8e5503825085e903cc07ba21dc00f9ab992d3840 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
@@ -264,7 +264,7 @@ public class HiddenInternalFunctions {
                     symbolData[i] = symbolInfo.createRSymbolObject(rnt, true);
                 }
                 RList symbolDataList = RDataFactory.createList(symbolData);
-                symbolDataList.setClassAttr(NATIVE_ROUTINE_LIST);
+                symbolDataList.setClassAttr(NATIVE_ROUTINE_LIST, false);
                 data[nst.ordinal()] = symbolDataList;
             }
             return RDataFactory.createList(data, NAMES);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/InfixEmulationFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/InfixEmulationFunctions.java
index 27469b2dfe14f63479e62013406eb7a8b07569ae..34c2d01e171b34f667a9b29592badd995f2d3cd7 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/InfixEmulationFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/InfixEmulationFunctions.java
@@ -35,7 +35,6 @@ import com.oracle.truffle.r.nodes.access.array.write.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.builtin.base.InfixEmulationFunctionsFactory.PromiseEvaluatorNodeGen;
 import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
@@ -241,17 +240,17 @@ public class InfixEmulationFunctions {
 
         private static final String NAME = "[";
 
-        @Child private DispatchedCallNode dcn;
+        @Child private UseMethodInternalNode dcn;
 
         @Specialization(guards = {"!noInd(inds)", "isObject(frame, x)"})
         protected Object getObj(VirtualFrame frame, RAbstractContainer x, RArgsValuesAndNames inds, RAbstractLogicalVector dropVec) {
             if (dcn == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                dcn = insert(DispatchedCallNode.create(NAME, DispatchType.UseMethod, SIGNATURE));
+                dcn = insert(new UseMethodInternalNode(NAME, SIGNATURE));
             }
             try {
-                return dcn.executeInternal(frame, x.getClassHierarchy(), new Object[]{x, inds, dropVec});
-            } catch (NoGenericMethodException e) {
+                return dcn.execute(frame, x.getClassHierarchy(), new Object[]{x, inds, dropVec});
+            } catch (S3FunctionLookupNode.NoGenericMethodException e) {
                 return access(frame, x, RRuntime.LOGICAL_FALSE, inds, dropVec, IS_SUBSET);
             }
         }
@@ -273,11 +272,11 @@ public class InfixEmulationFunctions {
 
             if (dcn == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                dcn = insert(DispatchedCallNode.create(NAME, DispatchType.UseMethod, SIGNATURE));
+                dcn = insert(new UseMethodInternalNode(NAME, SIGNATURE));
             }
             try {
-                return dcn.executeInternal(frame, x.getClassHierarchy(), new Object[]{x, inds, drop});
-            } catch (NoGenericMethodException e) {
+                return dcn.execute(frame, x.getClassHierarchy(), new Object[]{x, inds, drop});
+            } catch (S3FunctionLookupNode.NoGenericMethodException e) {
                 return access(frame, x, RRuntime.LOGICAL_FALSE, inds, drop, IS_SUBSET);
             }
         }
@@ -290,7 +289,7 @@ public class InfixEmulationFunctions {
 
         @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "generic name is interned in the interpreted code for faster comparison")
         protected boolean isObject(VirtualFrame frame, RAbstractContainer x) {
-            return x.isObject(attrProfiles) && !(RArguments.hasS3Args(frame) && RArguments.getS3Generic(frame) == NAME);
+            return x.isObject(attrProfiles) && !(RArguments.getS3Args(frame) != null && RArguments.getS3Args(frame).generic == NAME);
         }
 
     }
@@ -347,7 +346,7 @@ public class InfixEmulationFunctions {
 
         private static final String NAME = "[[";
 
-        @Child private DispatchedCallNode dcn;
+        @Child private UseMethodInternalNode dcn;
 
         @Override
         public Object[] getDefaultParameterValues() {
@@ -364,11 +363,11 @@ public class InfixEmulationFunctions {
             }
             if (dcn == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                dcn = insert(DispatchedCallNode.create(NAME, DispatchType.UseMethod, SIGNATURE));
+                dcn = insert(new UseMethodInternalNode(NAME, SIGNATURE));
             }
             try {
-                return dcn.executeInternal(frame, x.getClassHierarchy(), new Object[]{x, inds, exactVec});
-            } catch (NoGenericMethodException e) {
+                return dcn.execute(frame, x.getClassHierarchy(), new Object[]{x, inds, exactVec});
+            } catch (S3FunctionLookupNode.NoGenericMethodException e) {
                 return access(frame, x, exact, inds, RRuntime.LOGICAL_TRUE, IS_SUBSET);
             }
         }
@@ -381,7 +380,7 @@ public class InfixEmulationFunctions {
 
         @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "generic name is interned in the interpreted code for faster comparison")
         protected boolean isObject(VirtualFrame frame, RAbstractContainer x) {
-            return x.isObject(attrProfiles) && !(RArguments.hasS3Args(frame) && RArguments.getS3Generic(frame) == NAME);
+            return x.isObject(attrProfiles) && !(RArguments.getS3Args(frame) != null && RArguments.getS3Args(frame).generic == NAME);
         }
 
     }
@@ -459,17 +458,17 @@ public class InfixEmulationFunctions {
         private static final String NAME = "[<-";
         private static final boolean IS_SUBSET = true;
 
-        @Child private DispatchedCallNode dcn;
+        @Child private UseMethodInternalNode dcn;
 
         @Specialization(guards = {"!noInd(args)", "isObject(frame, x)"})
         protected Object updateObj(VirtualFrame frame, RAbstractContainer x, RArgsValuesAndNames args) {
             if (dcn == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                dcn = insert(DispatchedCallNode.create(NAME, DispatchType.UseMethod, SIGNATURE));
+                dcn = insert(new UseMethodInternalNode(NAME, SIGNATURE));
             }
             try {
-                return dcn.executeInternal(frame, x.getClassHierarchy(), new Object[]{x, args});
-            } catch (NoGenericMethodException e) {
+                return dcn.execute(frame, x.getClassHierarchy(), new Object[]{x, args});
+            } catch (S3FunctionLookupNode.NoGenericMethodException e) {
                 Object value = args.getValues()[args.length() - 1];
                 return update(frame, x, args, value, IS_SUBSET);
             }
@@ -483,7 +482,7 @@ public class InfixEmulationFunctions {
 
         @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "generic name is interned in the interpreted code for faster comparison")
         protected boolean isObject(VirtualFrame frame, RAbstractContainer x) {
-            return x.isObject(attrProfiles) && !(RArguments.hasS3Args(frame) && RArguments.getS3Generic(frame) == NAME);
+            return x.isObject(attrProfiles) && !(RArguments.getS3Args(frame) != null && RArguments.getS3Args(frame).generic == NAME);
         }
     }
 
@@ -493,17 +492,17 @@ public class InfixEmulationFunctions {
         private static final String NAME = "[[<-";
         private static final boolean IS_SUBSET = false;
 
-        @Child private DispatchedCallNode dcn;
+        @Child private UseMethodInternalNode dcn;
 
         @Specialization(guards = {"!noInd(args)", "isObject(frame, x)"})
         protected Object updateObj(VirtualFrame frame, RAbstractContainer x, RArgsValuesAndNames args) {
             if (dcn == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                dcn = insert(DispatchedCallNode.create(NAME, DispatchType.UseMethod, ArgumentsSignature.empty(2)));
+                dcn = insert(new UseMethodInternalNode(NAME, ArgumentsSignature.empty(2)));
             }
             try {
-                return dcn.executeInternal(frame, x.getClassHierarchy(), new Object[]{x, args});
-            } catch (NoGenericMethodException e) {
+                return dcn.execute(frame, x.getClassHierarchy(), new Object[]{x, args});
+            } catch (S3FunctionLookupNode.NoGenericMethodException e) {
                 Object value = args.getValues()[args.length() - 1];
                 return update(frame, x, args, value, IS_SUBSET);
             }
@@ -517,7 +516,7 @@ public class InfixEmulationFunctions {
 
         @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "generic name is interned in the interpreted code for faster comparison")
         protected boolean isObject(VirtualFrame frame, RAbstractContainer x) {
-            return x.isObject(attrProfiles) && !(RArguments.hasS3Args(frame) && RArguments.getS3Generic(frame) == NAME);
+            return x.isObject(attrProfiles) && !(RArguments.getS3Args(frame) != null && RArguments.getS3Args(frame).generic == NAME);
         }
 
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java
index 836ee6b2e69c21ca80575a9d60e4d0000bc93b00..cf976eb0f2b5830f72c253746ec1aeb59f3f1860 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java
@@ -54,6 +54,7 @@ public abstract class Match extends RBuiltinNode {
 
     private final NACheck naCheck = new NACheck();
     private final ConditionProfile bigTableProfile = ConditionProfile.createBinaryProfile();
+    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
     private String castString(VirtualFrame frame, Object operand) {
         if (castString == null) {
@@ -97,7 +98,7 @@ public abstract class Match extends RBuiltinNode {
     protected RIntVector match(VirtualFrame frame, RFactor x, RFactor table, Object nomatchObj, Object incomparables) {
         naCheck.enable(x.getVector());
         naCheck.enable(table.getVector());
-        return matchRecursive(frame, RClosures.createFactorToVector(x, naCheck), RClosures.createFactorToVector(table, naCheck), nomatchObj, incomparables);
+        return matchRecursive(frame, RClosures.createFactorToVector(x, naCheck, attrProfiles), RClosures.createFactorToVector(table, naCheck, attrProfiles), nomatchObj, incomparables);
     }
 
     @Specialization
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 26194b032202a8863a346468bdbba8b1b069a82f..9b7b8e70c57dabb81ad919771f9b3346dfa0d35d 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
@@ -50,7 +50,7 @@ public abstract class Matrix extends RBuiltinNode {
             CompilerDirectives.transferToInterpreterAndInvalidate();
             updateDimNames = insert(UpdateDimNamesFactory.create(new RNode[2], getBuiltin(), getSuppliedSignature()));
         }
-        return updateDimNames.executeList(frame, vector, o);
+        return (RAbstractVector) updateDimNames.executeList(frame, vector, o);
     }
 
     @CreateCast("arguments")
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NextMethod.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NextMethod.java
deleted file mode 100644
index 2954ca86e56f1fdc187c77343e0f42c910572bb4..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NextMethod.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-package com.oracle.truffle.r.nodes.builtin.base;
-
-import static com.oracle.truffle.r.runtime.RBuiltinKind.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.r.nodes.access.variables.*;
-import com.oracle.truffle.r.nodes.builtin.*;
-import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.DispatchType;
-import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.data.*;
-import com.oracle.truffle.r.runtime.data.model.*;
-
-@RBuiltin(name = "NextMethod", kind = SUBSTITUTE, parameterNames = {"generic", "object", "..."})
-// TODO INTERNAL
-public abstract class NextMethod extends RBuiltinNode {
-
-    @Child private DispatchedCallNode dispatchedCallNode;
-    @Child private ReadVariableNode rvnClass;
-    @Child private ReadVariableNode rvnGeneric;
-    @Child private PromiseHelperNode promiseHelper = new PromiseHelperNode();
-    @CompilationFinal private String cachedGeneric;
-
-    private final BranchProfile errorProfile = BranchProfile.create();
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
-
-    @Override
-    public Object[] getDefaultParameterValues() {
-        return new Object[]{RNull.instance, RNull.instance, RArgsValuesAndNames.EMPTY};
-    }
-
-    protected Object nextMethod(VirtualFrame frame, String generic, @SuppressWarnings("unused") Object obj, Object[] args, ArgumentsSignature signature) {
-        controlVisibility();
-        RStringVector type = readType(frame);
-
-        if (dispatchedCallNode == null || (cachedGeneric != generic && !cachedGeneric.equals(generic))) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            cachedGeneric = generic;
-            RFunction enclosingFunction = RArguments.getFunction(frame);
-            String enclosingFunctionName = null;
-            if (!RArguments.hasS3Args(frame)) {
-                enclosingFunctionName = enclosingFunction.getRootNode().toString();
-            }
-            DispatchedCallNode newDispatched = DispatchedCallNode.create(generic.intern(), enclosingFunctionName, DispatchType.NextMethod, args, signature);
-            if (dispatchedCallNode == null) {
-                dispatchedCallNode = insert(newDispatched);
-            } else {
-                /*
-                 * The generic name may have changed. This is very unlikely, and therefore
-                 * implemented very inefficiently. Output a warning in case this really happens.
-                 */
-                RError.performanceWarning("non-constant generic parameter in NextMethod");
-                dispatchedCallNode.replace(newDispatched);
-            }
-        }
-        return dispatchedCallNode.execute(frame, type);
-    }
-
-    @Specialization
-    protected Object nextMethod(VirtualFrame frame, @SuppressWarnings("unused") RNull generic, Object obj, RArgsValuesAndNames args) {
-        controlVisibility();
-        String genericName = RArguments.getS3Generic(frame);
-        if (genericName == null || genericName.isEmpty()) {
-            errorProfile.enter();
-            throw RError.error(getEncapsulatingSourceSection(), RError.Message.GEN_FUNCTION_NOT_SPECIFIED);
-        }
-        return nextMethod(frame, genericName, obj, args.getValues(), args.getSignature());
-    }
-
-    @Specialization
-    protected Object nextMethod(VirtualFrame frame, String generic, Object obj, RArgsValuesAndNames args) {
-        controlVisibility();
-        return nextMethod(frame, generic, obj, args.getValues(), args.getSignature());
-    }
-
-    private RStringVector getAlternateClassHr(VirtualFrame frame) {
-        if (RArguments.getArgumentsLength(frame) == 0 || RArguments.getArgument(frame, 0) == null ||
-                        (!(RArguments.getArgument(frame, 0) instanceof RAbstractVector) && !(RArguments.getArgument(frame, 0) instanceof RPromise))) {
-            errorProfile.enter();
-            throw RError.error(getEncapsulatingSourceSection(), RError.Message.OBJECT_NOT_SPECIFIED);
-        }
-        Object arg = RArguments.getArgument(frame, 0);
-        if (arg instanceof RPromise) {
-            arg = promiseHelper.evaluate(frame, (RPromise) arg);
-        }
-        RAbstractContainer enclosingArg = (RAbstractContainer) arg;
-        if (!enclosingArg.isObject(attrProfiles)) {
-            errorProfile.enter();
-            throw RError.error(getEncapsulatingSourceSection(), RError.Message.OBJECT_NOT_SPECIFIED);
-        }
-        return enclosingArg.getClassHierarchy();
-    }
-
-    private RStringVector readType(VirtualFrame frame) {
-        final RStringVector storedClass = RArguments.getS3Class(frame);
-        if (storedClass == null) {
-            return getAlternateClassHr(frame);
-        }
-        return storedClass;
-    }
-}
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrettyPrinterNode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrettyPrinterNode.java
index 534946f916a700d0ef490d902bd8835a8c0d26ee..cbdcfece832c08edc7d29c880d5f2f4adc35e49f 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrettyPrinterNode.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrettyPrinterNode.java
@@ -1030,6 +1030,8 @@ public abstract class PrettyPrinterNode extends RNode {
         @Child private PrettyPrinterNode prettyPrinter;
         @Child private CastStringNode castStringNode;
 
+        private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
+
         private final NACheck naCheck = NACheck.create();
 
         private void initCast(Object listElementName) {
@@ -1155,7 +1157,7 @@ public abstract class PrettyPrinterNode extends RNode {
         // TODO: this should be handled by an S3 function
         @Specialization
         protected String prettyPrintListElement(VirtualFrame frame, RFactor operand, Object listElementName, byte quote, byte right) {
-            RVector vec = operand.getLevels();
+            RVector vec = operand.getLevels(attrProfiles);
             String[] strings;
             if (vec == null) {
                 strings = new String[0];
@@ -1171,7 +1173,7 @@ public abstract class PrettyPrinterNode extends RNode {
 
         @TruffleBoundary
         private String formatLevelStrings(RFactor operand, Object listElementName, byte right, RVector vec, String[] strings) {
-            StringBuilder sb = new StringBuilder(prettyPrintSingleElement(RClosures.createFactorToVector(operand, naCheck), listElementName, RRuntime.LOGICAL_FALSE, right));
+            StringBuilder sb = new StringBuilder(prettyPrintSingleElement(RClosures.createFactorToVector(operand, naCheck, attrProfiles), listElementName, RRuntime.LOGICAL_FALSE, right));
             sb.append("\nLevels:");
             if (vec != null) {
                 for (int i = 0; i < vec.getLength(); i++) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ProcTime.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ProcTime.java
index f4aa4e48ce4b97770b82e315b62d4b3b66f3eb82..b0f6c5fa3948fc1c1a394bd2aaedef14db90b37f 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ProcTime.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ProcTime.java
@@ -64,7 +64,7 @@ public abstract class ProcTime extends RBuiltinNode {
             RNAMES = RDataFactory.createStringVector(NAMES, RDataFactory.COMPLETE_VECTOR);
         }
         RDoubleVector result = RDataFactory.createDoubleVector(data, complete, RNAMES);
-        result.setClassAttr(PROC_TIME_CLASS);
+        result.setClassAttr(PROC_TIME_CLASS, false);
         return result;
     }
 
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 ab8466edafb4fc67ff32e9a3c90c51e7f3d6ee3d..3c5f2155f9bf682073f0d8a65e1f2eeb35ffedff 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
@@ -160,7 +160,7 @@ public abstract class Repeat extends RBuiltinNode {
     @Specialization
     public RAbstractContainer rep(VirtualFrame frame, RFactor x, RAbstractIntVector times, int lengthOut, int each) {
         RVector vec = (RVector) repeatRecursive(frame, x.getVector(), times, lengthOut, each);
-        vec.setLevels(x.getLevels());
+        vec.setAttr(RRuntime.LEVELS_ATTR_KEY, x.getLevels(attrProfiles));
         return RVector.setVectorClassAttr(vec, x.getClassAttr(attrProfiles), null, null);
     }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/S3DispatchFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/S3DispatchFunctions.java
new file mode 100644
index 0000000000000000000000000000000000000000..2620a949d05fbb07570a484a054f37af5ee535fa
--- /dev/null
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/S3DispatchFunctions.java
@@ -0,0 +1,254 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 2014, Purdue University
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.nodes.builtin.base;
+
+import static com.oracle.truffle.r.runtime.RBuiltinKind.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.utilities.*;
+import com.oracle.truffle.r.nodes.access.variables.*;
+import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode.ReadKind;
+import com.oracle.truffle.r.nodes.builtin.*;
+import com.oracle.truffle.r.nodes.function.*;
+import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseCheckHelperNode;
+import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode.Result;
+import com.oracle.truffle.r.nodes.function.signature.*;
+import com.oracle.truffle.r.runtime.*;
+import com.oracle.truffle.r.runtime.RArguments.S3Args;
+import com.oracle.truffle.r.runtime.data.*;
+import com.oracle.truffle.r.runtime.data.model.*;
+
+public abstract class S3DispatchFunctions extends RBuiltinNode {
+
+    @Child private S3FunctionLookupNode methodLookup;
+    @Child private CallMatcherNode callMatcher;
+
+    private final ConditionProfile callerFrameSlowPath = ConditionProfile.createBinaryProfile();
+    private final ConditionProfile topLevelFrameProfile = ConditionProfile.createBinaryProfile();
+
+    protected S3DispatchFunctions(boolean nextMethod) {
+        methodLookup = S3FunctionLookupNode.create(true, nextMethod);
+        callMatcher = CallMatcherNode.create(nextMethod, false);
+    }
+
+    protected MaterializedFrame getCallerFrame(VirtualFrame frame) {
+        MaterializedFrame funFrame = RArguments.getCallerFrame(frame);
+        if (callerFrameSlowPath.profile(funFrame == null)) {
+            funFrame = Utils.getCallerFrame(frame, FrameAccess.MATERIALIZE).materialize();
+            RError.performanceWarning("slow caller frame access in UseMethod dispatch");
+        }
+        // S3 method can be dispatched from top-level where there is no caller frame
+        return topLevelFrameProfile.profile(funFrame == null) ? frame.materialize() : funFrame;
+    }
+
+    protected Object dispatch(VirtualFrame frame, String generic, RStringVector type, String group, MaterializedFrame callerFrame, MaterializedFrame genericDefFrame,
+                    ArgumentsSignature suppliedSignature, Object[] suppliedArguments) {
+        Result lookupResult = methodLookup.execute(frame, generic, type, group, callerFrame, genericDefFrame);
+
+        S3Args s3Args = new S3Args(lookupResult.generic, lookupResult.clazz, lookupResult.targetFunctionName, callerFrame, genericDefFrame, group);
+        Object result = callMatcher.execute(frame, suppliedSignature, suppliedArguments, lookupResult.function, s3Args);
+        return result;
+    }
+
+    @RBuiltin(name = "UseMethod", kind = PRIMITIVE, parameterNames = {"generic", "object"})
+    public abstract static class UseMethod extends S3DispatchFunctions {
+
+        /*
+         * TODO: If more than two parameters are passed to UseMethod the extra parameters are
+         * ignored and a warning is generated.
+         */
+
+        @Child private ClassHierarchyNode classHierarchyNode = ClassHierarchyNodeGen.create(null);
+        @Child private PromiseCheckHelperNode promiseCheckHelper;
+
+        private final BranchProfile errorProfile = BranchProfile.create();
+        private final ConditionProfile argMissingProfile = ConditionProfile.createBinaryProfile();
+        private final ConditionProfile argsValueAndNamesProfile = ConditionProfile.createBinaryProfile();
+
+        protected UseMethod() {
+            super(false);
+        }
+
+        @Specialization
+        protected Object execute(VirtualFrame frame, String generic, Object arg) {
+            controlVisibility();
+
+            Object dispatchedObject;
+            if (argMissingProfile.profile(arg == RMissing.instance)) {
+                // For S3Dispatch, we have to evaluate the the first argument
+                dispatchedObject = getEnclosingArg(frame, generic);
+            } else {
+                dispatchedObject = arg;
+            }
+
+            RStringVector type = classHierarchyNode.execute(frame, dispatchedObject);
+            MaterializedFrame callerFrame = getCallerFrame(frame);
+            MaterializedFrame genericDefFrame = RArguments.getEnclosingFrame(frame);
+
+            ArgumentsSignature suppliedSignature = RArguments.getSignature(frame);
+            Object[] suppliedArguments = RArguments.getArguments(frame);
+            Object result = dispatch(frame, generic, type, null, callerFrame, genericDefFrame, suppliedSignature, suppliedArguments);
+            throw new ReturnException(result, null);
+        }
+
+        /**
+         * Get the first (logical) argument in the frame, and handle {@link RPromise}s and
+         * {@link RArgsValuesAndNames}.
+         */
+        private Object getEnclosingArg(VirtualFrame frame, String generic) {
+            if (RArguments.getArgumentsLength(frame) == 0 || RArguments.getArgument(frame, 0) == null) {
+                errorProfile.enter();
+                throw RError.error(getEncapsulatingSourceSection(), RError.Message.UNKNOWN_FUNCTION_USE_METHOD, generic, RRuntime.toString(RNull.instance));
+            }
+            Object enclosingArg = RArguments.getArgument(frame, 0);
+            if (argsValueAndNamesProfile.profile(enclosingArg instanceof RArgsValuesAndNames)) {
+                // The GnuR "1. argument" might be hidden inside a "..."! Unwrap for proper dispatch
+                RArgsValuesAndNames varArgs = (RArgsValuesAndNames) enclosingArg;
+                if (varArgs.length() == 0) {
+                    errorProfile.enter();
+                    throw RError.error(getEncapsulatingSourceSection(), RError.Message.UNKNOWN_FUNCTION_USE_METHOD, generic, RRuntime.toString(RNull.instance));
+                }
+                enclosingArg = varArgs.getValues()[0];
+            }
+            if (promiseCheckHelper == null) {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                promiseCheckHelper = insert(new PromiseCheckHelperNode());
+            }
+            return promiseCheckHelper.checkEvaluate(frame, enclosingArg);
+        }
+    }
+
+    @RBuiltin(name = "NextMethod", kind = SUBSTITUTE, parameterNames = {"generic", "object", "..."})
+    public abstract static class NextMethod extends S3DispatchFunctions {
+
+        @Child private ReadVariableNode rvnGroup = ReadVariableNode.create(RRuntime.RDotGroup, RType.Character, ReadKind.SilentLocal);
+        @Child private ReadVariableNode rvnClass = ReadVariableNode.create(RRuntime.RDotClass, RType.Character, ReadKind.SilentLocal);
+        @Child private ReadVariableNode rvnGeneric = ReadVariableNode.create(RRuntime.RDotGeneric, RType.Character, ReadKind.SilentLocal);
+        @Child private ReadVariableNode rvnCall = ReadVariableNode.create(RRuntime.RDotGenericCallEnv, RType.Any, ReadKind.SilentLocal);
+        @Child private ReadVariableNode rvnDef = ReadVariableNode.create(RRuntime.RDotGenericDefEnv, RType.Any, ReadKind.SilentLocal);
+
+        @Child private CombineSignaturesNode combineSignatures;
+
+        @CompilationFinal private RAttributeProfiles attrProfiles;
+        @Child private PromiseHelperNode promiseHelper;
+
+        private final BranchProfile errorProfile = BranchProfile.create();
+        private final ConditionProfile emptyArgsProfile = ConditionProfile.createBinaryProfile();
+        private final ConditionProfile genericCallFrameNullProfile = ConditionProfile.createBinaryProfile();
+        private final ConditionProfile genericDefFrameNullProfile = ConditionProfile.createBinaryProfile();
+        private final ConditionProfile alternateClassHeaderProfile = ConditionProfile.createBinaryProfile();
+
+        private final ValueProfile parameterSignatureProfile = ValueProfile.createIdentityProfile();
+
+        protected NextMethod() {
+            super(true);
+        }
+
+        @Override
+        public Object[] getDefaultParameterValues() {
+            return new Object[]{RNull.instance, RNull.instance, RArgsValuesAndNames.EMPTY};
+        }
+
+        @Specialization
+        protected Object nextMethod(VirtualFrame frame, @SuppressWarnings("unused") RNull nullGeneric, Object obj, RArgsValuesAndNames args) {
+            String generic = (String) rvnGeneric.execute(frame);
+            if (generic == null || generic.isEmpty()) {
+                errorProfile.enter();
+                throw RError.error(getEncapsulatingSourceSection(), RError.Message.GEN_FUNCTION_NOT_SPECIFIED);
+            }
+            return nextMethod(frame, generic, obj, args);
+        }
+
+        @SuppressWarnings("unused")
+        @Specialization
+        protected Object nextMethod(VirtualFrame frame, String generic, Object obj, RArgsValuesAndNames args) {
+            controlVisibility();
+            MaterializedFrame genericCallFrame = getCallFrame(frame);
+            MaterializedFrame genericDefFrame = getDefFrame(frame);
+            String group = (String) rvnGroup.execute(frame);
+
+            ArgumentsSignature suppliedSignature;
+            Object[] suppliedArguments;
+            ArgumentsSignature parameterSignature = parameterSignatureProfile.profile(RArguments.getSignature(frame));
+            if (emptyArgsProfile.profile(args == RArgsValuesAndNames.EMPTY)) {
+                suppliedSignature = parameterSignature;
+                suppliedArguments = RArguments.getArguments(frame);
+            } else {
+                if (combineSignatures == null) {
+                    CompilerDirectives.transferToInterpreterAndInvalidate();
+                    combineSignatures = insert(CombineSignaturesNodeGen.create(null, null));
+                }
+                suppliedSignature = combineSignatures.execute(parameterSignature, args.getSignature());
+
+                suppliedArguments = new Object[suppliedSignature.getLength()];
+                for (int i = 0; i < parameterSignature.getLength(); i++) {
+                    suppliedArguments[i] = RArguments.getArgument(frame, i);
+                }
+                for (int i = 0; i < args.getSignature().getLength(); i++) {
+                    suppliedArguments[parameterSignature.getLength() + i] = args.getValues()[i];
+                }
+            }
+            return dispatch(frame, generic, readType(frame), group, genericCallFrame, genericDefFrame, suppliedSignature, suppliedArguments);
+        }
+
+        private MaterializedFrame getDefFrame(VirtualFrame frame) {
+            MaterializedFrame genericDefFrame = (MaterializedFrame) rvnDef.execute(frame);
+            if (genericDefFrameNullProfile.profile(genericDefFrame == null)) {
+                genericDefFrame = RArguments.getEnclosingFrame(frame);
+            }
+            return genericDefFrame;
+        }
+
+        private MaterializedFrame getCallFrame(VirtualFrame frame) {
+            MaterializedFrame genericCallFrame = (MaterializedFrame) rvnCall.execute(frame);
+            if (genericCallFrameNullProfile.profile(genericCallFrame == null)) {
+                genericCallFrame = frame.materialize();
+            }
+            return genericCallFrame;
+        }
+
+        private RStringVector readType(VirtualFrame frame) {
+            Object storedClass = rvnClass.execute(frame);
+            if (alternateClassHeaderProfile.profile(storedClass == null || storedClass == RNull.instance)) {
+                return getAlternateClassHr(frame);
+            } else {
+                return (RStringVector) storedClass;
+            }
+        }
+
+        private RStringVector getAlternateClassHr(VirtualFrame frame) {
+            if (promiseHelper == null) {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                attrProfiles = RAttributeProfiles.create();
+                promiseHelper = insert(new PromiseHelperNode());
+            }
+            if (RArguments.getArgumentsLength(frame) == 0 || RArguments.getArgument(frame, 0) == null ||
+                            (!(RArguments.getArgument(frame, 0) instanceof RAbstractVector) && !(RArguments.getArgument(frame, 0) instanceof RPromise))) {
+                errorProfile.enter();
+                throw RError.error(getEncapsulatingSourceSection(), RError.Message.OBJECT_NOT_SPECIFIED);
+            }
+            Object arg = RArguments.getArgument(frame, 0);
+            if (arg instanceof RPromise) {
+                arg = promiseHelper.evaluate(frame, (RPromise) arg);
+            }
+            RAbstractContainer enclosingArg = (RAbstractContainer) arg;
+            if (!enclosingArg.isObject(attrProfiles)) {
+                errorProfile.enter();
+                throw RError.error(getEncapsulatingSourceSection(), RError.Message.OBJECT_NOT_SPECIFIED);
+            }
+            return enclosingArg.getClassHierarchy();
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Split.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Split.java
index 22a87fbd1801d7a4bd22bf7dad7eb6d634779b8a..955f9da4ad610ebdd15fc3e319b735ede8c74d0b 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Split.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Split.java
@@ -48,6 +48,7 @@ public abstract class Split extends RBuiltinNode {
     @Child private CastStringNode castString;
 
     private final ConditionProfile noStringLevels = ConditionProfile.createBinaryProfile();
+    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
     private static final int INITIAL_SIZE = 5;
     private static final int SCALE_FACTOR = 2;
@@ -55,7 +56,7 @@ public abstract class Split extends RBuiltinNode {
     @Specialization
     protected RList split(VirtualFrame frame, RAbstractIntVector x, RFactor f) {
         int[] factor = f.getVector().getDataWithoutCopying();
-        final int nLevels = f.getNLevels();
+        final int nLevels = f.getNLevels(attrProfiles);
 
         // initialise result arrays
         int[][] collectResults = new int[nLevels][];
@@ -87,7 +88,7 @@ public abstract class Split extends RBuiltinNode {
     @Specialization
     protected RList split(VirtualFrame frame, RAbstractDoubleVector x, RFactor f) {
         int[] factor = f.getVector().getDataWithoutCopying();
-        final int nLevels = f.getNLevels();
+        final int nLevels = f.getNLevels(attrProfiles);
 
         // initialise result arrays
         double[][] collectResults = new double[nLevels][];
@@ -119,7 +120,7 @@ public abstract class Split extends RBuiltinNode {
     @Specialization
     protected RList split(VirtualFrame frame, RAbstractStringVector x, RFactor f) {
         int[] factor = f.getVector().getDataWithoutCopying();
-        final int nLevels = f.getNLevels();
+        final int nLevels = f.getNLevels(attrProfiles);
 
         // initialise result arrays
         String[][] collectResults = new String[nLevels][];
@@ -151,7 +152,7 @@ public abstract class Split extends RBuiltinNode {
     @Specialization
     protected RList split(VirtualFrame frame, RAbstractLogicalVector x, RFactor f) {
         int[] factor = f.getVector().getDataWithoutCopying();
-        final int nLevels = f.getNLevels();
+        final int nLevels = f.getNLevels(attrProfiles);
 
         // initialise result arrays
         byte[][] collectResults = new byte[nLevels][];
@@ -181,13 +182,13 @@ public abstract class Split extends RBuiltinNode {
     }
 
     private RStringVector makeNames(VirtualFrame frame, RFactor f) {
-        RVector levels = f.getLevels();
+        RVector levels = f.getLevels(attrProfiles);
         if (noStringLevels.profile(!(levels instanceof RStringVector))) {
             if (castString == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
                 castString = insert(CastStringNodeGen.create(null, false, false, false, false));
             }
-            RStringVector slevels = (RStringVector) castString.executeString(frame, f.getLevels());
+            RStringVector slevels = (RStringVector) castString.executeString(frame, f.getLevels(attrProfiles));
             return RDataFactory.createStringVector(slevels.getDataWithoutCopying(), RDataFactory.COMPLETE_VECTOR);
         } else {
             return RDataFactory.createStringVector(((RStringVector) levels).getDataCopy(), RDataFactory.COMPLETE_VECTOR);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Structure.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Structure.java
index 97bb076eaab1b5f22c369dd9852efa95e76993f6..12bb462dd83dc76500adfcc642e1c247b116683c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Structure.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Structure.java
@@ -86,9 +86,9 @@ public abstract class Structure extends RBuiltinNode {
             String attrName = fixupAttrName(signature.getName(i + 1));
             if (attrName.equals(RRuntime.CLASS_ATTR_KEY)) {
                 if (value == RNull.instance) {
-                    res = (RAbstractContainer) res.setClassAttr(null);
+                    res = (RAbstractContainer) res.setClassAttr(null, true);
                 } else {
-                    res = (RAbstractContainer) res.setClassAttr((RStringVector) value);
+                    res = (RAbstractContainer) res.setClassAttr((RStringVector) value, true);
                 }
             } else {
                 if (value == RNull.instance) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java
index e597e6c1944f94af78ed541d052bdc28a3163c69..78377245d4c1bf850e283e7aca7517601394ece0 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java
@@ -58,20 +58,20 @@ public abstract class UpdateAttr extends RInvisibleBuiltinNode {
     @CompilationFinal private String cachedName = "";
     @CompilationFinal private String cachedInternedName = "";
 
-    private RAbstractVector updateNames(VirtualFrame frame, RAbstractVector vector, Object o) {
+    private RAbstractContainer updateNames(VirtualFrame frame, RAbstractContainer container, Object o) {
         if (updateNames == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
             updateNames = insert(UpdateNamesFactory.create(new RNode[2], getBuiltin(), getSuppliedSignature()));
         }
-        return (RAbstractVector) updateNames.executeStringVector(frame, vector, o);
+        return (RAbstractContainer) updateNames.executeStringVector(frame, container, o);
     }
 
-    private RAbstractVector updateDimNames(VirtualFrame frame, RAbstractVector vector, Object o) {
+    private RAbstractContainer updateDimNames(VirtualFrame frame, RAbstractContainer container, Object o) {
         if (updateDimNames == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
             updateDimNames = insert(UpdateDimNamesFactory.create(new RNode[2], getBuiltin(), getSuppliedSignature()));
         }
-        return updateDimNames.executeList(frame, vector, o);
+        return updateDimNames.executeList(frame, container, o);
     }
 
     private RAbstractIntVector castInteger(VirtualFrame frame, RAbstractVector vector) {
@@ -124,45 +124,40 @@ public abstract class UpdateAttr extends RInvisibleBuiltinNode {
     protected RAbstractContainer updateAttr(VirtualFrame frame, RAbstractContainer container, String name, RNull value) {
         controlVisibility();
         String internedName = intern(name);
-        RVector resultVector = container.materializeNonSharedVector();
+        RAbstractContainer result = container.materializeNonShared();
         // the name is interned, so identity comparison is sufficient
         if (internedName == RRuntime.DIM_ATTR_KEY) {
-            resultVector.setDimensions(null, getEncapsulatingSourceSection());
+            result.setDimensions(null);
         } else if (internedName == RRuntime.NAMES_ATTR_KEY) {
-            return updateNames(frame, resultVector, value);
+            return updateNames(frame, result, value);
         } else if (internedName == RRuntime.DIMNAMES_ATTR_KEY) {
-            return updateDimNames(frame, resultVector, value);
+            return updateDimNames(frame, result, value);
         } else if (internedName == RRuntime.CLASS_ATTR_KEY) {
-            return RVector.setVectorClassAttr(resultVector, null, container.getElementClass() == RDataFrame.class ? container : null, container.getElementClass() == RFactor.class ? container : null);
+            return (RAbstractContainer) result.setClassAttr(null, false);
         } else if (internedName == RRuntime.ROWNAMES_ATTR_KEY) {
-            resultVector.setRowNames(null);
-        } else if (internedName == RRuntime.LEVELS_ATTR_KEY) {
-            resultVector.setLevels(null);
-        } else if (resultVector.getAttributes() != null) {
-            resultVector.getAttributes().remove(internedName);
+            result.setRowNames(null);
+        } else if (result.getAttributes() != null) {
+            result.removeAttr(attrProfiles, internedName);
         }
-        // return frame or factor if it's one, otherwise return the vector
-        return container.getElementClass() == RDataFrame.class || container.getElementClass() == RFactor.class ? container : resultVector;
+        return result;
     }
 
     @TruffleBoundary
-    public static RAbstractContainer setClassAttrFromObject(RVector resultVector, RAbstractContainer container, Object value, SourceSection sourceSection) {
+    public static RStringVector convertClassAttrFromObject(Object value) {
         if (value instanceof RStringVector) {
-            return RVector.setVectorClassAttr(resultVector, (RStringVector) value, container.getElementClass() == RDataFrame.class ? container : null,
-                            container.getElementClass() == RFactor.class ? container : null);
-        }
-        if (value instanceof String) {
-            return RVector.setVectorClassAttr(resultVector, RDataFactory.createStringVector((String) value), container.getElementClass() == RDataFrame.class ? container : null,
-                            container.getElementClass() == RFactor.class ? container : null);
+            return (RStringVector) value;
+        } else if (value instanceof String) {
+            return RDataFactory.createStringVector((String) value);
+        } else {
+            throw RError.error(RError.Message.SET_INVALID_CLASS_ATTR);
         }
-        throw RError.error(sourceSection, RError.Message.SET_INVALID_CLASS_ATTR);
     }
 
     @Specialization(guards = "!nullValue(value)")
     protected RAbstractContainer updateAttr(VirtualFrame frame, RAbstractContainer container, String name, Object value) {
         controlVisibility();
         String internedName = intern(name);
-        RVector resultVector = container.materializeNonSharedVector();
+        RAbstractContainer result = container.materializeNonShared();
         // the name is interned, so identity comparison is sufficient
         if (internedName == RRuntime.DIM_ATTR_KEY) {
             RAbstractIntVector dimsVector = castInteger(frame, castVector(frame, value));
@@ -170,23 +165,21 @@ public abstract class UpdateAttr extends RInvisibleBuiltinNode {
                 errorProfile.enter();
                 throw RError.error(getEncapsulatingSourceSection(), RError.Message.LENGTH_ZERO_DIM_INVALID);
             }
-            resultVector.setDimensions(dimsVector.materialize().getDataCopy(), getEncapsulatingSourceSection());
+            result.setDimensions(dimsVector.materialize().getDataCopy());
         } else if (internedName == RRuntime.NAMES_ATTR_KEY) {
-            return updateNames(frame, resultVector, value);
+            return updateNames(frame, result, value);
         } else if (internedName == RRuntime.DIMNAMES_ATTR_KEY) {
-            return updateDimNames(frame, resultVector, value);
+            return updateDimNames(frame, result, value);
         } else if (internedName == RRuntime.CLASS_ATTR_KEY) {
-            return setClassAttrFromObject(resultVector, container, value, getEncapsulatingSourceSection());
+            return (RAbstractContainer) result.setClassAttr(convertClassAttrFromObject(value), false);
         } else if (internedName == RRuntime.ROWNAMES_ATTR_KEY) {
-            resultVector.setRowNames(castVector(frame, value));
-        } else if (internedName == RRuntime.LEVELS_ATTR_KEY) {
-            resultVector.setLevels(castVector(frame, value));
+            result.setRowNames(castVector(frame, value));
         } else {
             // generic attribute
-            resultVector.setAttr(internedName, value);
+            result.setAttr(internedName, value);
         }
-        // return frame or factor if it's one, otherwise return the vector
-        return container.getElementClass() == RDataFrame.class || container.getElementClass() == RFactor.class ? container : resultVector;
+
+        return result;
     }
 
     @Specialization(guards = "!nullValue(value)")
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java
index 98cfc1fa231b6f448da65321d7a0a2071298c697..1a0914c19077400b8d6efba352b9eb92c9e148bc 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java
@@ -49,12 +49,12 @@ public abstract class UpdateAttributes extends RInvisibleBuiltinNode {
     @Child private CastToVectorNode castVector;
     @Child private CastListNode castList;
 
-    private void updateNamesStringVector(VirtualFrame frame, RAbstractVector vector, Object o) {
+    private void updateNamesStringVector(VirtualFrame frame, RAbstractContainer container, Object o) {
         if (updateNames == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
             updateNames = insert(UpdateNamesFactory.create(new RNode[2], getBuiltin(), getSuppliedSignature()));
         }
-        updateNames.executeStringVector(frame, vector, o);
+        updateNames.executeStringVector(frame, container, o);
     }
 
     private RAbstractIntVector castInteger(VirtualFrame frame, RAbstractVector vector) {
@@ -97,12 +97,11 @@ public abstract class UpdateAttributes extends RInvisibleBuiltinNode {
             throw RError.error(getEncapsulatingSourceSection(), RError.Message.ATTRIBUTES_NAMED);
         }
         RStringVector listNames = (RStringVector) listNamesObject;
-        RVector resultVector = container.materializeNonSharedVector();
-        RAbstractContainer res = resultVector;
+        RAbstractContainer result = container.materializeNonShared();
         if (numAttributesProfile.profile(list.getLength() == 0)) {
-            resultVector.resetAllAttributes(true);
+            result.resetAllAttributes(true);
         } else {
-            resultVector.resetAllAttributes(false);
+            result.resetAllAttributes(false);
             // error checking is a little weird - seems easier to separate it than weave it into the
             // update loop
             if (listNames.getLength() > 1) {
@@ -113,11 +112,11 @@ public abstract class UpdateAttributes extends RInvisibleBuiltinNode {
                 throw RError.error(getEncapsulatingSourceSection(), RError.Message.ZERO_LENGTH_VARIABLE);
             }
             // set the dim attribute first
-            setDimAttribute(frame, resultVector, list);
+            setDimAttribute(frame, result, list);
             // set the remaining attributes in order
-            res = setRemainingAttributes(frame, container, resultVector, list);
+            result = setRemainingAttributes(frame, container, result, list);
         }
-        return res;
+        return result;
     }
 
     @TruffleBoundary
@@ -135,7 +134,7 @@ public abstract class UpdateAttributes extends RInvisibleBuiltinNode {
     }
 
     @ExplodeLoop
-    private void setDimAttribute(VirtualFrame virtualFrame, RVector resultVector, RList sourceList) {
+    private void setDimAttribute(VirtualFrame virtualFrame, RAbstractContainer result, RList sourceList) {
         RStringVector listNames = sourceList.getNames(attrProfiles);
         int length = sourceList.getLength();
         assert length > 0 : "Length should be > 0 for ExplodeLoop";
@@ -144,53 +143,50 @@ public abstract class UpdateAttributes extends RInvisibleBuiltinNode {
             String attrName = listNames.getDataAt(i);
             if (attrName.equals(RRuntime.DIM_ATTR_KEY)) {
                 if (value == RNull.instance) {
-                    resultVector.setDimensions(null, getEncapsulatingSourceSection());
+                    result.setDimensions(null);
                 } else {
                     RAbstractIntVector dimsVector = castInteger(virtualFrame, castVector(virtualFrame, value));
                     if (dimsVector.getLength() == 0) {
                         throw RError.error(getEncapsulatingSourceSection(), RError.Message.LENGTH_ZERO_DIM_INVALID);
                     }
-                    resultVector.setDimensions(dimsVector.materialize().getDataCopy(), getEncapsulatingSourceSection());
+                    result.setDimensions(dimsVector.materialize().getDataCopy());
                 }
             }
         }
     }
 
     @ExplodeLoop
-    private RAbstractContainer setRemainingAttributes(VirtualFrame virtualFrame, RAbstractContainer container, RVector resultVector, RList sourceList) {
+    private RAbstractContainer setRemainingAttributes(VirtualFrame virtualFrame, RAbstractContainer container, RAbstractContainer result, RList sourceList) {
         RStringVector listNames = sourceList.getNames(attrProfiles);
         int length = sourceList.getLength();
         assert length > 0 : "Length should be > 0 for ExplodeLoop";
-        RAbstractContainer res = resultVector;
+        RAbstractContainer res = result;
         for (int i = 0; i < sourceList.getLength(); i++) {
             Object value = sourceList.getDataAt(i);
             String attrName = listNames.getDataAt(i);
             if (attrName.equals(RRuntime.DIM_ATTR_KEY)) {
                 continue;
             } else if (attrName.equals(RRuntime.NAMES_ATTR_KEY)) {
-                updateNamesStringVector(virtualFrame, resultVector, value);
+                updateNamesStringVector(virtualFrame, res, value);
             } else if (attrName.equals(RRuntime.DIMNAMES_ATTR_KEY)) {
                 if (value == RNull.instance) {
-                    resultVector.setDimNames(null, getEncapsulatingSourceSection());
+                    res.setDimNames(null);
                 } else {
-                    resultVector.setDimNames(castList(virtualFrame, value), getEncapsulatingSourceSection());
+                    res.setDimNames(castList(virtualFrame, value));
                 }
             } else if (attrName.equals(RRuntime.CLASS_ATTR_KEY)) {
                 if (value == RNull.instance) {
-                    res = RVector.setVectorClassAttr(resultVector, null, container.getElementClass() == RDataFrame.class ? container : null, container.getElementClass() == RFactor.class ? container
-                                    : null);
+                    res = (RAbstractContainer) result.setClassAttr(null, false);
                 } else {
-                    res = UpdateAttr.setClassAttrFromObject(resultVector, container, value, getEncapsulatingSourceSection());
+                    res = (RAbstractContainer) result.setClassAttr(UpdateAttr.convertClassAttrFromObject(value), false);
                 }
             } else if (attrName.equals(RRuntime.ROWNAMES_ATTR_KEY)) {
-                resultVector.setRowNames(castVector(virtualFrame, value));
-            } else if (attrName.equals(RRuntime.LEVELS_ATTR_KEY)) {
-                resultVector.setLevels(castVector(virtualFrame, value));
+                res.setRowNames(castVector(virtualFrame, value));
             } else {
                 if (value == RNull.instance) {
-                    resultVector.removeAttr(attrProfiles, attrName);
+                    res.removeAttr(attrProfiles, attrName);
                 } else {
-                    resultVector.setAttr(attrName, value);
+                    res.setAttr(attrName, value);
                 }
             }
         }
@@ -208,7 +204,7 @@ public abstract class UpdateAttributes extends RInvisibleBuiltinNode {
             RAttributable attrObj = (RAttributable) obj;
             attrObj.removeAllAttributes();
             if (operand == RNull.instance) {
-                attrObj.setClassAttr(null);
+                attrObj.setClassAttr(null, false);
             } else if (operand instanceof RList) {
                 RList list = (RList) operand;
                 RStringVector listNames = list.getNames(attrProfiles);
@@ -225,7 +221,7 @@ public abstract class UpdateAttributes extends RInvisibleBuiltinNode {
                         if (attrValue == null) {
                             throw RError.error(getEncapsulatingSourceSection(), RError.Message.SET_INVALID_CLASS_ATTR);
                         }
-                        attrObj.setClassAttr(RDataFactory.createStringVectorFromScalar((String) attrValue));
+                        attrObj.setClassAttr(RDataFactory.createStringVectorFromScalar((String) attrValue), false);
                     } else {
                         attrObj.setAttr(attrName, list.getDataAt(i));
                     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java
index 170d8355bb8ec36ff04959b5d14fbbdd98e45e3b..4ea8eccefc88da60ed779ecd844f5ada948f6ebf 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java
@@ -61,8 +61,9 @@ public abstract class UpdateClass extends RBuiltinNode {
     @TruffleBoundary
     protected Object setClass(RAbstractContainer arg, @SuppressWarnings("unused") RNull className) {
         controlVisibility();
-        RVector resultVector = arg.materializeNonSharedVector();
-        return RVector.setVectorClassAttr(resultVector, null, arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg : null);
+
+        RAbstractContainer result = arg.materializeNonShared();
+        return result.setClassAttr(null, false);
     }
 
     @Specialization
@@ -84,90 +85,92 @@ public abstract class UpdateClass extends RBuiltinNode {
                 return setClass((RAbstractVector) result, RNull.instance);
             }
         }
-        RVector resultVector = arg.materializeNonSharedVector();
-        if (RType.Matrix.getName().equals(className)) {
-            if (resultVector.isMatrix()) {
-                return setClass(resultVector, RNull.instance);
-            }
-            final int[] dimensions = resultVector.getDimensions();
-            int dimLength = 0;
-            if (dimensions != null) {
-                dimLength = dimensions.length;
+        RAbstractContainer result = arg.materializeNonShared();
+        if (result instanceof RAbstractVector) {
+            RAbstractVector resultVector = (RAbstractVector) result;
+            if (RType.Matrix.getName().equals(className)) {
+                if (resultVector.isMatrix()) {
+                    return setClass(resultVector, RNull.instance);
+                }
+                final int[] dimensions = resultVector.getDimensions();
+                int dimLength = 0;
+                if (dimensions != null) {
+                    dimLength = dimensions.length;
+                }
+                throw RError.error(getEncapsulatingSourceSection(), RError.Message.NOT_A_MATRIX_UPDATE_CLASS, dimLength);
             }
-            throw RError.error(getEncapsulatingSourceSection(), RError.Message.NOT_A_MATRIX_UPDATE_CLASS, dimLength);
-        }
-        if (RType.Array.getName().equals(className)) {
-            if (resultVector.isArray()) {
-                return setClass(resultVector, RNull.instance);
+            if (RType.Array.getName().equals(className)) {
+                if (resultVector.isArray()) {
+                    return setClass(resultVector, RNull.instance);
+                }
+                throw RError.error(getEncapsulatingSourceSection(), RError.Message.NOT_ARRAY_UPDATE_CLASS);
             }
-            throw RError.error(getEncapsulatingSourceSection(), RError.Message.NOT_ARRAY_UPDATE_CLASS);
         }
 
-        return RVector.setVectorClassAttr(resultVector, RDataFactory.createStringVector(className), arg.getElementClass() == RDataFrame.class ? arg : null,
-                        arg.getElementClass() == RFactor.class ? arg : null);
+        return result.setClassAttr(RDataFactory.createStringVector(className), false);
     }
 
     @Specialization
     @TruffleBoundary
     protected Object setClass(RAbstractContainer arg, RStringVector className) {
         controlVisibility();
-        RVector resultVector = arg.materializeNonSharedVector();
-        return RVector.setVectorClassAttr(resultVector, className, arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg : null);
+        RAbstractContainer result = arg.materializeNonShared();
+        return result.setClassAttr(className, false);
     }
 
     @Specialization
     public Object setClass(RFunction arg, RAbstractStringVector className) {
         controlVisibility();
-        arg.setClassAttr(className.materialize());
+        arg.setClassAttr(className.materialize(), false);
         return arg;
     }
 
     @Specialization
     public Object setClass(RFunction arg, @SuppressWarnings("unused") RNull className) {
         controlVisibility();
-        arg.setClassAttr(null);
+        arg.setClassAttr(null, false);
         return arg;
     }
 
     @Specialization
     public Object setClass(REnvironment arg, RAbstractStringVector className) {
         controlVisibility();
-        arg.setClassAttr(className.materialize());
+        arg.setClassAttr(className.materialize(), false);
         return arg;
     }
 
     @Specialization
     public Object setClass(REnvironment arg, @SuppressWarnings("unused") RNull className) {
         controlVisibility();
-        arg.setClassAttr(null);
+        arg.setClassAttr(null, false);
         return arg;
     }
 
     @Specialization
     public Object setClass(RSymbol arg, RAbstractStringVector className) {
         controlVisibility();
-        arg.setClassAttr(className.materialize());
+        arg.setClassAttr(className.materialize(), false);
         return arg;
     }
 
     @Specialization
     public Object setClass(RSymbol arg, @SuppressWarnings("unused") RNull className) {
         controlVisibility();
-        arg.setClassAttr(null);
+        arg.setClassAttr(null, false);
         return arg;
     }
 
     @Specialization
     public Object setClass(RExternalPtr arg, RAbstractStringVector className) {
         controlVisibility();
-        arg.setClassAttr(className.materialize());
+        arg.setClassAttr(className.materialize(), false);
         return arg;
     }
 
     @Specialization
     public Object setClass(RExternalPtr arg, @SuppressWarnings("unused") RNull className) {
         controlVisibility();
-        arg.setClassAttr(null);
+        arg.setClassAttr(null, false);
         return arg;
     }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDiag.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDiag.java
index a3db17b7eaec037ccfe426fc88aa95f2eb119bc4..5369afde2d09bad324549ad30f4839c8e07bfdd0 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDiag.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDiag.java
@@ -74,11 +74,7 @@ public abstract class UpdateDiag extends RInvisibleBuiltinNode {
     @TruffleBoundary
     protected RAbstractIntVector updateDiag(RIntVector vector, RAbstractIntVector valueVector) {
         controlVisibility();
-        RIntVector resultVector = vector;
-        if (vector.isShared()) {
-            resultVector = (RIntVector) vector.copy();
-            resultVector.markNonTemporary();
-        }
+        RIntVector resultVector = (RIntVector) vector.materializeNonShared();
         int nrow = resultVector.getDimensions()[0];
         int size = Math.min(nrow, resultVector.getDimensions()[1]);
         int pos = 0;
@@ -94,11 +90,7 @@ public abstract class UpdateDiag extends RInvisibleBuiltinNode {
     @TruffleBoundary
     protected RAbstractDoubleVector updateDiag(RDoubleVector vector, RAbstractDoubleVector valueVector) {
         controlVisibility();
-        RDoubleVector resultVector = vector;
-        if (vector.isShared()) {
-            resultVector = (RDoubleVector) vector.copy();
-            resultVector.markNonTemporary();
-        }
+        RDoubleVector resultVector = (RDoubleVector) vector.materializeNonShared();
         int size = Math.min(resultVector.getDimensions()[0], resultVector.getDimensions()[1]);
         int nrow = resultVector.getDimensions()[0];
         int pos = 0;
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 0a1be0632f2f3dd045fa462674c5891503284c82..30dab531e163b154dee26aadaf93384136fde0e0 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
@@ -55,10 +55,9 @@ public abstract class UpdateDim extends RInvisibleBuiltinNode {
     }
 
     @Specialization
-    @TruffleBoundary
     protected RAbstractVector updateDim(RAbstractVector vector, RNull dimensions) {
         controlVisibility();
-        RVector result = vector.materialize();
+        RVector result = (RVector) vector.materializeNonShared();
         result.resetDimensions(null);
         return result;
     }
@@ -72,7 +71,7 @@ public abstract class UpdateDim extends RInvisibleBuiltinNode {
         }
         int[] dimsData = castInteger(frame, dimensions).materialize().getDataCopy();
         vector.verifyDimensions(dimsData, getEncapsulatingSourceSection());
-        RVector result = vector.materialize();
+        RVector result = (RVector) vector.materializeNonShared();
         result.resetDimensions(dimsData);
         return result;
     }
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 07680c3652fc5b421de8594d6e7c5fac828d7171..0865a21d74c398a459fd45caf4884ed0c0d2a75d 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
@@ -67,7 +67,7 @@ public abstract class UpdateDimNames extends RInvisibleBuiltinNode {
         }
     }
 
-    public abstract RAbstractVector executeList(VirtualFrame frame, RAbstractVector vector, Object o);
+    public abstract RAbstractContainer executeList(VirtualFrame frame, RAbstractContainer container, Object o);
 
     public RList convertToListOfStrings(VirtualFrame frame, RList oldList) {
         RList list = oldList;
@@ -86,46 +86,46 @@ public abstract class UpdateDimNames extends RInvisibleBuiltinNode {
 
     @Specialization
     @TruffleBoundary
-    protected RAbstractVector updateDimnames(RAbstractVector vector, RNull list) {
-        RVector v = vector.materialize();
-        v.setDimNames(null, getEncapsulatingSourceSection());
+    protected RAbstractContainer updateDimnames(RAbstractContainer container, RNull list) {
+        RAbstractContainer result = container.materializeNonShared();
+        container.setDimNames(null);
         controlVisibility();
-        return v;
+        return container;
     }
 
     @Specialization(guards = "isZeroLength(list)")
     @TruffleBoundary
-    protected RAbstractVector updateDimnamesEmpty(RAbstractVector vector, RList list) {
-        RVector v = vector.materialize();
-        v.setDimNames(null, getEncapsulatingSourceSection());
+    protected RAbstractContainer updateDimnamesEmpty(RAbstractContainer container, RList list) {
+        RAbstractContainer result = container.materializeNonShared();
+        container.setDimNames(null);
         controlVisibility();
-        return v;
+        return container;
     }
 
     @Specialization(guards = "!isZeroLength(list)")
-    protected RAbstractVector updateDimnames(VirtualFrame frame, RAbstractVector vector, RList list) {
-        RVector v = vector.materialize();
-        v.setDimNames(convertToListOfStrings(frame, list), getEncapsulatingSourceSection());
+    protected RAbstractContainer updateDimnames(VirtualFrame frame, RAbstractContainer container, RList list) {
+        RAbstractContainer result = container.materializeNonShared();
+        container.setDimNames(convertToListOfStrings(frame, list));
         controlVisibility();
-        return v;
+        return container;
     }
 
-    @Specialization(guards = "!isVectorList(v)")
-    protected RAbstractVector updateDimnamesError(RAbstractVector vector, RAbstractVector v) {
+    @Specialization(guards = "!isContainerList(c)")
+    protected RAbstractContainer updateDimnamesError(RAbstractContainer container, RAbstractContainer c) {
         controlVisibility();
         CompilerDirectives.transferToInterpreter();
         throw RError.error(getEncapsulatingSourceSection(), RError.Message.DIMNAMES_LIST);
     }
 
     @Specialization
-    protected RAbstractVector updateDimnamesError(RAbstractVector vector, RFunction v) {
+    protected RAbstractContainer updateDimnamesError(RAbstractContainer container, RFunction v) {
         controlVisibility();
         CompilerDirectives.transferToInterpreter();
         throw RError.error(getEncapsulatingSourceSection(), RError.Message.DIMNAMES_LIST);
     }
 
-    protected boolean isVectorList(RAbstractVector v) {
-        return v instanceof RList;
+    protected boolean isContainerList(RAbstractContainer c) {
+        return c instanceof RList;
     }
 
     protected boolean isZeroLength(RList list) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLength.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLength.java
index 500429f2f618dc8fb607c5092b2aca63d73e098d..3a6f867400c59f53b68905152c0969ba38431d1d 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLength.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLength.java
@@ -30,7 +30,6 @@ import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.r.nodes.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.*;
 import com.oracle.truffle.r.nodes.unary.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
@@ -40,7 +39,7 @@ import com.oracle.truffle.r.runtime.data.model.*;
 // 2nd parameter is "value", but should not be matched against, so ""
 public abstract class UpdateLength extends RInvisibleBuiltinNode {
 
-    @Child private DispatchedCallNode dcn;
+    @Child private UseMethodInternalNode dcn;
 
     private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
@@ -55,11 +54,11 @@ public abstract class UpdateLength extends RInvisibleBuiltinNode {
     protected Object updateLengthObject(VirtualFrame frame, RAbstractContainer container, RAbstractIntVector lengthVector) {
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(DispatchedCallNode.create("length<-", DispatchType.UseMethod, getSuppliedSignature()));
+            dcn = insert(new UseMethodInternalNode("length<-", getSuppliedSignature()));
         }
         try {
-            return dcn.executeInternal(frame, container.getClassHierarchy(), new Object[]{container, lengthVector});
-        } catch (NoGenericMethodException e) {
+            return dcn.execute(frame, container.getClassHierarchy(), new Object[]{container, lengthVector});
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             return updateLength(frame, container, lengthVector);
         }
 
@@ -69,10 +68,7 @@ public abstract class UpdateLength extends RInvisibleBuiltinNode {
     protected RAbstractContainer updateLength(@SuppressWarnings("unused") VirtualFrame frame, RAbstractContainer container, RAbstractIntVector lengthVector) {
         controlVisibility();
         int length = lengthVector.getDataAt(0);
-        // TODO: we can potentially avoid making a copy during materialization and then during
-        // resizing but is it worth it for that case?
-        RVector vector = container.materializeNonSharedVector();
-        return (RAbstractContainer) vector.resize(length, true);
+        return container.resize(length);
     }
 
     @SuppressWarnings("unused")
@@ -97,7 +93,7 @@ public abstract class UpdateLength extends RInvisibleBuiltinNode {
 
     protected boolean isObject(VirtualFrame frame, RAbstractContainer container) {
         // if execution got here via S3 dispatch, treat objects as non-objects
-        return container.isObject(attrProfiles) && !RArguments.hasS3Args(frame);
+        return container.isObject(attrProfiles) && RArguments.getS3Args(frame) == null;
     }
 
 }
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 b83605291ada1cf310e613837ec5973766818f32..afcae7cb6de479c586046e8682202613d1f78120 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
@@ -27,6 +27,8 @@ public abstract class UpdateLevels extends RInvisibleBuiltinNode {
     @Child private CastToVectorNode castVector;
     @Child private CastStringNode castString;
 
+    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
+
     private RAbstractVector castVector(VirtualFrame frame, Object value) {
         if (castVector == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -46,30 +48,34 @@ public abstract class UpdateLevels extends RInvisibleBuiltinNode {
     @Specialization
     protected RAbstractVector updateLevels(RAbstractVector vector, @SuppressWarnings("unused") RNull levels) {
         controlVisibility();
-        RVector v = vector.materialize();
-        v.setLevels(null);
+        RVector v = (RVector) vector.materializeNonShared();
+        v.removeAttr(attrProfiles, RRuntime.LEVELS_ATTR_KEY);
         return v;
     }
 
-    @Specialization
+    @Specialization(guards = "levelsNotNull(levels)")
     protected RAbstractVector updateLevels(VirtualFrame frame, RAbstractVector vector, Object levels) {
         controlVisibility();
-        RVector v = vector.materialize();
-        v.setLevels(castVector(frame, levels));
+        RVector v = (RVector) vector.materializeNonShared();
+        v.setAttr(RRuntime.LEVELS_ATTR_KEY, castVector(frame, levels));
         return v;
     }
 
     @Specialization
     protected RFactor updateLevels(RFactor factor, @SuppressWarnings("unused") RNull levels) {
         controlVisibility();
-        factor.getVector().setLevels(null);
+        factor.getVector().removeAttr(attrProfiles, RRuntime.LEVELS_ATTR_KEY);
         return factor;
     }
 
-    @Specialization
+    @Specialization(guards = "levelsNotNull(levels)")
     protected RFactor updateLevels(VirtualFrame frame, RFactor factor, Object levels) {
         controlVisibility();
-        factor.getVector().setLevels(castString(frame, castVector(frame, levels)));
+        factor.getVector().setAttr(RRuntime.LEVELS_ATTR_KEY, castString(frame, castVector(frame, levels)));
         return factor;
     }
+
+    protected boolean levelsNotNull(Object levels) {
+        return levels != RNull.instance;
+    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateNames.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateNames.java
index 63811416bc3480297e94ecb56acab75f9349b31d..c44e9b7da2db9e395acf64517d9b2d9b12264aa6 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateNames.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateNames.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,68 +51,51 @@ public abstract class UpdateNames extends RInvisibleBuiltinNode {
         return castStringNode.executeString(frame, o);
     }
 
-    public abstract Object executeStringVector(VirtualFrame frame, RAbstractVector vector, Object o);
+    public abstract Object executeStringVector(VirtualFrame frame, RAbstractContainer container, Object o);
 
     @Specialization
     @TruffleBoundary
-    protected RAbstractVector updateNames(RAbstractVector vector, @SuppressWarnings("unused") RNull names) {
+    protected RAbstractContainer updateNames(RAbstractContainer container, @SuppressWarnings("unused") RNull names) {
         controlVisibility();
-        RVector v = vector.materialize();
-        v.setNames(null, getEncapsulatingSourceSection());
-        return v;
+        RAbstractContainer result = container.materializeNonShared();
+        result.setNames(null);
+        return result;
     }
 
     @Specialization
     @TruffleBoundary
-    protected RAbstractVector updateNames(RAbstractVector vector, RStringVector names) {
+    protected RAbstractContainer updateNames(RAbstractContainer container, RStringVector names) {
         controlVisibility();
-        RVector v = vector.materialize();
+        RAbstractContainer result = container.materializeNonShared();
         RStringVector namesVector = names;
-        if (names.getLength() < v.getLength()) {
-            namesVector = names.copyResized(v.getLength(), true);
+        if (names.getLength() < result.getLength()) {
+            namesVector = names.copyResized(result.getLength(), true);
         }
-        v.setNames(namesVector, getEncapsulatingSourceSection());
-        return v;
+        result.setNames(namesVector);
+        return result;
     }
 
     @Specialization
     @TruffleBoundary
-    protected RAbstractVector updateNames(RAbstractVector vector, String name) {
+    protected RAbstractContainer updateNames(RAbstractContainer container, String name) {
         controlVisibility();
-        RVector v = vector.materialize();
-        String[] names = new String[v.getLength()];
+        RAbstractContainer result = container.materializeNonShared();
+        String[] names = new String[result.getLength()];
         Arrays.fill(names, RRuntime.STRING_NA);
         names[0] = name;
         RStringVector namesVector = RDataFactory.createStringVector(names, names.length <= 1);
-        v.setNames(namesVector, getEncapsulatingSourceSection());
-        return v;
+        result.setNames(namesVector);
+        return result;
     }
 
     @Specialization
-    protected RAbstractVector updateNames(VirtualFrame frame, RAbstractVector vector, Object names) {
+    protected RAbstractContainer updateNames(VirtualFrame frame, RAbstractContainer container, Object names) {
         controlVisibility();
         if (names instanceof RAbstractVector) {
-            return updateNames(vector, (RStringVector) castString(frame, names));
+            return updateNames(container, (RStringVector) castString(frame, names));
         } else {
-            return updateNames(vector, (String) castString(frame, names));
+            return updateNames(container, (String) castString(frame, names));
         }
     }
 
-    @Specialization
-    @TruffleBoundary
-    protected RAbstractVector updateNames(RDataFrame dataFrame, RStringVector names) {
-        return updateNames(dataFrame.getVector(), names);
-    }
-
-    @Specialization
-    @TruffleBoundary
-    protected RAbstractVector updateNames(RDataFrame dataFrame, String names) {
-        return updateNames(dataFrame.getVector(), names);
-    }
-
-    @Specialization
-    protected RAbstractVector updateNames(VirtualFrame frame, RDataFrame dataFrame, Object names) {
-        return updateNames(frame, dataFrame.getVector(), names);
-    }
-
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java
index 2e6c69ab060fcf0166e42a7c083bbeb9b2d43738..b0934d6801e78d3d80b39bdc6314f8125eb7495d 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java
@@ -74,16 +74,16 @@ public abstract class UpdateOldClass extends RInvisibleBuiltinNode {
     @TruffleBoundary
     protected Object setOldClass(RAbstractContainer arg, RStringVector className) {
         controlVisibility();
-        RVector resultVector = arg.materializeNonSharedVector();
-        return RVector.setVectorClassAttr(resultVector, className, arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg : null);
+        RAbstractContainer result = arg.materializeNonShared();
+        return result.setClassAttr(className, false);
     }
 
     @Specialization
     @TruffleBoundary
     protected Object setOldClass(RAbstractContainer arg, @SuppressWarnings("unused") RNull className) {
         controlVisibility();
-        RVector resultVector = arg.materializeNonSharedVector();
-        return RVector.setVectorClassAttr(resultVector, null, arg.getElementClass() == RDataFrame.class ? arg : null, arg.getElementClass() == RFactor.class ? arg : null);
+        RAbstractContainer result = arg.materializeNonShared();
+        return result.setClassAttr(null, false);
     }
 
     protected boolean isStringVector(RAbstractVector className) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java
index 330df16e52d73bc82f68bc83051e1a70e8e1b015..9d0a62b058d6cfb72c141e982c3b4537dfc0c486 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java
@@ -23,6 +23,7 @@ import com.oracle.truffle.r.nodes.unary.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.RAttributes.RAttribute;
+import com.oracle.truffle.r.runtime.data.model.*;
 
 @RBuiltin(name = "storage.mode<-", kind = PRIMITIVE, parameterNames = {"x", ""})
 // 2nd parameter is "value", but should not be matched against, so ""
@@ -57,24 +58,25 @@ public abstract class UpdateStorageMode extends RBuiltinNode {
         if (mode != null) {
             Object result = castTypeNode.execute(frame, x, mode);
             if (result != null) {
-                if (x instanceof RAttributable && result instanceof RAttributable) {
+                if (x instanceof RAttributable && result instanceof RAbstractContainer) {
                     RAttributable rx = (RAttributable) x;
                     RAttributes attrs = rx.getAttributes();
                     if (attrs != null) {
-                        RAttributable rresult = (RAttributable) result;
+                        RAbstractContainer rresult = (RAbstractContainer) result;
                         for (RAttribute attr : attrs) {
                             String attrName = attr.getName();
                             Object v = attr.getValue();
                             if (attrName.equals(RRuntime.CLASS_ATTR_KEY)) {
                                 if (v == RNull.instance) {
-                                    rresult = rresult.setClassAttr(null);
+                                    rresult = (RAbstractContainer) rresult.setClassAttr(null, false);
                                 } else {
-                                    rresult = rresult.setClassAttr((RStringVector) v);
+                                    rresult = (RAbstractContainer) rresult.setClassAttr((RStringVector) v, false);
                                 }
                             } else {
                                 rresult.setAttr(attrName.intern(), v);
                             }
                         }
+                        return rresult;
                     }
                 }
                 return result;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UseMethod.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UseMethod.java
deleted file mode 100644
index 1607a5bdd444e9eed1b80ba2596fb0ff9ddeef8e..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UseMethod.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-package com.oracle.truffle.r.nodes.builtin.base;
-
-import static com.oracle.truffle.r.runtime.RBuiltinKind.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.r.nodes.builtin.*;
-import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.DispatchType;
-import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseCheckHelperNode;
-import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.data.*;
-
-@RBuiltin(name = "UseMethod", kind = PRIMITIVE, parameterNames = {"generic", "object"})
-public abstract class UseMethod extends RBuiltinNode {
-
-    /*
-     * TODO: If more than two parameters are passed to UseMethod the extra parameters are ignored
-     * and a warning is generated.
-     */
-
-    @Child private DispatchedCallNode dispatchedCallNode;
-    @Child protected ClassHierarchyNode classHierarchyNode = ClassHierarchyNodeGen.create(null);
-    @Child private PromiseCheckHelperNode promiseCheckHelper;
-
-    @CompilationFinal private String cachedGeneric;
-    private final BranchProfile errorProfile = BranchProfile.create();
-    private final ConditionProfile argMissingProfile = ConditionProfile.createBinaryProfile();
-    private final ConditionProfile argsValueAndNamesProfile = ConditionProfile.createBinaryProfile();
-
-    @Specialization
-    protected Object execute(VirtualFrame frame, String generic, Object arg) {
-        controlVisibility();
-        if (dispatchedCallNode == null || (cachedGeneric != generic && !cachedGeneric.equals(generic))) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            cachedGeneric = generic;
-            DispatchedCallNode newDispatched = DispatchedCallNode.create(generic.intern(), DispatchType.UseMethod, getSuppliedSignature());
-            if (dispatchedCallNode == null) {
-                dispatchedCallNode = insert(newDispatched);
-            } else {
-                /*
-                 * The generic name may have changed. This is very unlikely, and therefore
-                 * implemented very inefficiently. Output a warning in case this really happens.
-                 */
-                RError.performanceWarning("non-constant generic parameter in UseMethod");
-                dispatchedCallNode.replace(newDispatched);
-            }
-        }
-
-        Object dispatchedObject;
-        if (argMissingProfile.profile(arg == RMissing.instance)) {
-            // For S3Dispatch, we have to evaluate the the first argument
-            dispatchedObject = getEnclosingArg(frame);
-        } else {
-            dispatchedObject = arg;
-        }
-        throw new ReturnException(dispatchedCallNode.execute(frame, classHierarchyNode.execute(frame, dispatchedObject)), null);
-    }
-
-    /**
-     * Get the first (logical) argument in the frame, and handle {@link RPromise}s and
-     * {@link RArgsValuesAndNames}.
-     */
-    private Object getEnclosingArg(VirtualFrame frame) {
-        if (RArguments.getArgumentsLength(frame) == 0 || RArguments.getArgument(frame, 0) == null) {
-            errorProfile.enter();
-            throw RError.error(getEncapsulatingSourceSection(), RError.Message.UNKNOWN_FUNCTION_USE_METHOD, cachedGeneric, RRuntime.toString(RNull.instance));
-        }
-        Object enclosingArg = RArguments.getArgument(frame, 0);
-        if (argsValueAndNamesProfile.profile(enclosingArg instanceof RArgsValuesAndNames)) {
-            // The GnuR "1. argument" might be hidden inside a "..."! Unwrap for proper dispatch
-            RArgsValuesAndNames varArgs = (RArgsValuesAndNames) enclosingArg;
-            if (varArgs.length() == 0) {
-                errorProfile.enter();
-                throw RError.error(getEncapsulatingSourceSection(), RError.Message.UNKNOWN_FUNCTION_USE_METHOD, cachedGeneric, RRuntime.toString(RNull.instance));
-            }
-            enclosingArg = varArgs.getValues()[0];
-        }
-        if (promiseCheckHelper == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            promiseCheckHelper = insert(new PromiseCheckHelperNode());
-        }
-        return promiseCheckHelper.checkEvaluate(frame, enclosingArg);
-    }
-}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java
index 8f4f5953ce4a286383c8064f2385159f1dafeaca..c0b9b05c5910a7b08eab389f8a146ef8a9373c21 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java
@@ -191,9 +191,9 @@ public class RASTUtils {
             return RCallNode.createCall(null, RASTUtils.createReadVariableNode(((String) fn)), callArgsNode, null);
         } else if (fn instanceof ReadVariableNode) {
             return RCallNode.createCall(null, (ReadVariableNode) fn, callArgsNode, null);
-        } else if (fn instanceof GroupDispatchCallNode) {
-            GroupDispatchCallNode gdcn = (GroupDispatchCallNode) fn;
-            return GroupDispatchCallNode.create(gdcn.getGenericName(), gdcn.getGroupName(), callArgsNode, gdcn.getCallSrc());
+        } else if (fn instanceof GroupDispatchNode) {
+            GroupDispatchNode gdcn = (GroupDispatchNode) fn;
+            return GroupDispatchNode.create(gdcn.getGenericName(), gdcn.getGroup(), callArgsNode, gdcn.getCallSrc());
         } else {
             RFunction rfn = (RFunction) fn;
             return RCallNode.createCall(null, ConstantNode.create(rfn), callArgsNode, null);
@@ -201,7 +201,7 @@ public class RASTUtils {
     }
 
     /**
-     * Really should not be necessary, but things like '+' ({@link DispatchedCallNode}) have a
+     * Really should not be necessary, but things like '+' ({@link GroupDispatchNode}) have a
      * different AST structure from normal calls.
      */
     private static class CallArgsNodeFinder implements NodeVisitor {
@@ -234,7 +234,7 @@ public class RASTUtils {
 
     /**
      * Returns the name (as an {@link RSymbol} or the function associated with an {@link RCallNode}
-     * or {@link DispatchedCallNode}.
+     * or {@link GroupDispatchNode}.
      *
      * @param escape Add escape characters to non-standard names
      */
@@ -248,8 +248,8 @@ public class RASTUtils {
                 name = escapeName(name);
             }
             return RDataFactory.createSymbol(name);
-        } else if (child instanceof GroupDispatchCallNode) {
-            GroupDispatchCallNode groupDispatchNode = (GroupDispatchCallNode) child;
+        } else if (child instanceof GroupDispatchNode) {
+            GroupDispatchNode groupDispatchNode = (GroupDispatchNode) child;
             String gname = groupDispatchNode.getGenericName();
             if (escape) {
                 gname = escapeName(gname);
@@ -274,12 +274,12 @@ public class RASTUtils {
 
     /**
      * Returns the {@link ReadVariableNode} associated with a {@link RCallNode} or the
-     * {@link GroupDispatchCallNode} .
+     * {@link GroupDispatchNode} .
      */
     public static RNode findFunctionNode(Node node) {
         if (node instanceof RCallNode) {
             return ((RCallNode) node).getFunctionNode();
-        } else if (node instanceof GroupDispatchCallNode) {
+        } else if (node instanceof GroupDispatchNode) {
             return (RNode) node;
         }
         assert false;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RRootNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RRootNode.java
index 461160b746614e94c71d80c7a348b4459996f239..1206fbb6064cc8f556f7081e250fe8c47bdc55ab 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RRootNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RRootNode.java
@@ -22,8 +22,8 @@
  */
 package com.oracle.truffle.r.nodes;
 
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.*;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.api.source.*;
@@ -39,11 +39,9 @@ import com.oracle.truffle.r.runtime.env.frame.*;
  */
 public abstract class RRootNode extends RootNode implements HasSignature {
 
-    @CompilationFinal private StableValue<MaterializedFrame> enclosingFrameAssumption;
-    @CompilationFinal private StableValue<FrameDescriptor> enclosingFrameDescriptorAssumption;
-    private final ValueProfile enclosingFrameProfile = ValueProfile.createClassProfile();
     @CompilationFinal protected boolean checkSingletonFrame = true;
     private final ValueProfile functionProfile = ValueProfile.createIdentityProfile();
+    private final ValueProfile irregularFrameProfile = ValueProfile.createPrimitiveProfile();
 
     /**
      * The formal arguments this function is supposed to take.
@@ -53,48 +51,15 @@ public abstract class RRootNode extends RootNode implements HasSignature {
     protected RRootNode(SourceSection src, FormalArguments formalArguments, FrameDescriptor frameDescriptor) {
         super(src, frameDescriptor);
         this.formalArguments = formalArguments;
-        this.enclosingFrameAssumption = FrameSlotChangeMonitor.getEnclosingFrameAssumption(frameDescriptor);
-        this.enclosingFrameDescriptorAssumption = FrameSlotChangeMonitor.getEnclosingFrameDescriptorAssumption(frameDescriptor);
     }
 
     protected void verifyEnclosingAssumptions(VirtualFrame vf) {
         RArguments.setFunction(vf, functionProfile.profile(RArguments.getFunction(vf)));
+        RArguments.setIsIrregular(vf, irregularFrameProfile.profile(RArguments.getIsIrregular(vf)));
 
         if (checkSingletonFrame) {
             checkSingletonFrame = FrameSlotChangeMonitor.checkSingletonFrame(vf);
         }
-        if (enclosingFrameAssumption != null) {
-            try {
-                enclosingFrameAssumption.getAssumption().check();
-            } catch (InvalidAssumptionException e) {
-                enclosingFrameAssumption = FrameSlotChangeMonitor.getEnclosingFrameAssumption(getFrameDescriptor());
-            }
-            if (enclosingFrameAssumption != null) {
-                MaterializedFrame enclosingFrame = RArguments.getEnclosingFrame(vf);
-                if (enclosingFrameAssumption != null) {
-                    if (enclosingFrameAssumption.getValue() != enclosingFrame) {
-                        CompilerDirectives.transferToInterpreterAndInvalidate();
-                        enclosingFrameAssumption = FrameSlotChangeMonitor.getOrInitializeEnclosingFrameAssumption(vf.materialize(), getFrameDescriptor(), enclosingFrameAssumption, enclosingFrame);
-                    }
-                }
-            }
-        }
-        if (enclosingFrameDescriptorAssumption != null) {
-            try {
-                enclosingFrameDescriptorAssumption.getAssumption().check();
-            } catch (InvalidAssumptionException e) {
-                enclosingFrameDescriptorAssumption = FrameSlotChangeMonitor.getEnclosingFrameDescriptorAssumption(getFrameDescriptor());
-            }
-            if (enclosingFrameDescriptorAssumption != null) {
-                MaterializedFrame enclosingFrame = RArguments.getEnclosingFrame(vf);
-                FrameDescriptor enclosingFrameDescriptor = enclosingFrame == null ? null : enclosingFrameProfile.profile(enclosingFrame).getFrameDescriptor();
-                if (enclosingFrameDescriptorAssumption.getValue() != enclosingFrameDescriptor) {
-                    CompilerDirectives.transferToInterpreterAndInvalidate();
-                    enclosingFrameDescriptorAssumption = FrameSlotChangeMonitor.getOrInitializeEnclosingFrameDescriptorAssumption(vf, getFrameDescriptor(), enclosingFrameDescriptorAssumption,
-                                    enclosingFrameDescriptor);
-                }
-            }
-        }
     }
 
     /**
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java
index 3ec710818f91cdc339bcb29b73882e55fc4b5b76..7b0b3614e38203fbe553c500915bd1198c4ea918 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java
@@ -118,7 +118,7 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
         if (callName != null) {
             String functionName = callName;
             if (!FastROptions.DisableGroupGenerics.getValue() && RGroupGenerics.isGroupGeneric(functionName)) {
-                return GroupDispatchCallNode.create(functionName, RGroupGenerics.getGroup(functionName), aCallArgNode, callSource);
+                return GroupDispatchNode.create(functionName, RGroupGenerics.getGroup(functionName), aCallArgNode, callSource);
             }
             return RCallNode.createCall(callSource, ReadVariableNode.createForced(functionName, RType.Function), aCallArgNode, callParam);
         } else {
@@ -212,7 +212,8 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
         String functionName = op.getOperator().getName();
         CallArgumentsNode aCallArgNode = CallArgumentsNode.createUnnamed(false, true, operand);
         if (!FastROptions.DisableGroupGenerics.getValue() && RGroupGenerics.isGroupGeneric(functionName)) {
-            return GroupDispatchCallNode.create(functionName, RGroupGenerics.GROUP_OPS, aCallArgNode, op.getSource());
+            assert RGroupGenerics.getGroup(functionName) == RGroupGenerics.Ops;
+            return GroupDispatchNode.create(functionName, RGroupGenerics.Ops, aCallArgNode, op.getSource());
         }
         return RCallNode.createStaticCall(op.getSource(), functionName, aCallArgNode, op);
     }
@@ -227,7 +228,7 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
             String functionName = op.getOperator().getName();
             CallArgumentsNode aCallArgNode = CallArgumentsNode.createUnnamed(false, true, left, right);
             if (!FastROptions.DisableGroupGenerics.getValue() && RGroupGenerics.isGroupGeneric(functionName)) {
-                return GroupDispatchCallNode.create(functionName, RGroupGenerics.getGroup(functionName), aCallArgNode, op.getSource());
+                return GroupDispatchNode.create(functionName, RGroupGenerics.getGroup(functionName), aCallArgNode, op.getSource());
             }
             return RCallNode.createStaticCall(op.getSource(), functionName, aCallArgNode, op);
         }
@@ -355,9 +356,7 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
         return new RNode[5];
     }
 
-    private static final String varSymbol = "*tmp*";
-
-    private static String constructReplacementPrefix(RNode[] seq, RNode rhs, RNode replacementArg, WriteVariableNode.Mode rhsWriteMode) {
+    private static String constructReplacementPrefix(RNode[] seq, RNode rhs, RNode replacementArg, WriteVariableNode.Mode rhsWriteMode, String tmpSymbol) {
         //@formatter:off
         // store a - need to use temporary, otherwise there is a failure in case multiple calls to
         // the replacement form are chained:
@@ -365,8 +364,8 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
         //@formatter:on
         final String rhsSymbol = new Object().toString();
 
-        WriteVariableNode rhsAssign = WriteVariableNode.create(rhsSymbol.toString(), rhs, false, false, rhsWriteMode);
-        WriteVariableNode varAssign = WriteVariableNode.create(varSymbol, replacementArg, false, false, WriteVariableNode.Mode.TEMP);
+        WriteVariableNode rhsAssign = WriteVariableNode.create(rhsSymbol, rhs, false, false, rhsWriteMode);
+        WriteVariableNode varAssign = WriteVariableNode.create(tmpSymbol, replacementArg, false, false, WriteVariableNode.Mode.INVISIBLE);
 
         seq[0] = rhsAssign;
         seq[1] = varAssign;
@@ -374,9 +373,9 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
         return rhsSymbol;
     }
 
-    private static ReplacementNode constructReplacementSuffix(RNode[] seq, RNode assignFromTemp, Object rhsSymbol, SourceSection source) {
+    private static ReplacementNode constructReplacementSuffix(RNode[] seq, RNode assignFromTemp, Object tmpSymbol, Object rhsSymbol, SourceSection source) {
         // remove var and rhs, returning rhs' value
-        RemoveAndAnswerNode rmVar = RemoveAndAnswerNode.create(varSymbol);
+        RemoveAndAnswerNode rmVar = RemoveAndAnswerNode.create(tmpSymbol);
         RemoveAndAnswerNode rmRhs = RemoveAndAnswerNode.create(rhsSymbol);
 
         // assemble
@@ -440,17 +439,18 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
             SimpleAccessVariable varAST = (SimpleAccessVariable) a.getVector();
             String vSymbol = varAST.getVariable();
 
+            final String tmpSymbol = new Object().toString();
             RNode[] seq = createReplacementSequence();
             ReadVariableNode v = isSuper ? ReadVariableNode.createSuperLookup(varAST.getSource(), vSymbol) : ReadVariableNode.create(varAST.getSource(), vSymbol, varAST.shouldCopyValue());
-            final Object rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE);
+            final Object rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
             String rhsSymbolString = RRuntime.toString(rhsSymbol);
             RNode rhsAccess = ReadVariableNode.create(rhsSymbolString, false);
-            RNode tmpVarAccess = ReadVariableNode.create(varSymbol, false);
+            RNode tmpVarAccess = ReadVariableNode.create(tmpSymbol, false);
 
             CoerceVector coerceVector = CoerceVectorNodeGen.create(null, null, null);
             RNode updateOp = createPositions(a.getArguments(), argLength, a.isSubset(), null, tmpVarAccess, rhsAccess, coerceVector, true);
-            RNode assignFromTemp = WriteVariableNode.create(vSymbol, updateOp, false, isSuper, WriteVariableNode.Mode.TEMP);
-            return constructReplacementSuffix(seq, assignFromTemp, rhsSymbol, source);
+            RNode assignFromTemp = WriteVariableNode.create(vSymbol, updateOp, false, isSuper, WriteVariableNode.Mode.INVISIBLE);
+            return constructReplacementSuffix(seq, assignFromTemp, tmpSymbol, rhsSymbol, source);
         } else if (a.getVector() instanceof AccessVector) {
             // assign value to the outermost dimension and then the result (recursively) to
             // appropriate position in the lower dimension
@@ -459,15 +459,16 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
             AccessVector vecAST = (AccessVector) a.getVector();
             SimpleAccessVariable varAST = getVectorVariable(vecAST);
             RNode[] seq = new RNode[3];
+            final String tmpSymbol = new Object().toString();
             String rhsSymbol;
             if (varAST != null) {
                 String vSymbol = varAST.getVariable();
 
                 ReadVariableNode v = isSuper ? ReadVariableNode.createSuperLookup(varAST.getSource(), vSymbol) : ReadVariableNode.create(varAST.getSource(), vSymbol, varAST.shouldCopyValue());
-                rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE);
+                rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
 
             } else {
-                rhsSymbol = constructReplacementPrefix(seq, rhs, vecAST.getVector().accept(this), WriteVariableNode.Mode.INVISIBLE);
+                rhsSymbol = constructReplacementPrefix(seq, rhs, vecAST.getVector().accept(this), WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
             }
             RNode rhsAccess = AccessVariable.create(null, rhsSymbol).accept(this);
             CoerceVector coerceVector = CoerceVectorNodeGen.create(null, null, null);
@@ -479,12 +480,13 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
 
             RNode[] seq = new RNode[3];
             String rhsSymbol;
+            final String tmpSymbol = new Object().toString();
             if (varAST != null) {
                 String vSymbol = varAST.getVariable();
                 ReadVariableNode v = isSuper ? ReadVariableNode.createSuperLookup(varAST.getSource(), vSymbol) : ReadVariableNode.create(varAST.getSource(), vSymbol, varAST.shouldCopyValue());
-                rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE);
+                rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
             } else {
-                rhsSymbol = constructReplacementPrefix(seq, rhs, accessAST.getLhs().accept(this), WriteVariableNode.Mode.INVISIBLE);
+                rhsSymbol = constructReplacementPrefix(seq, rhs, accessAST.getLhs().accept(this), WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
             }
             RNode rhsAccess = AccessVariable.create(null, rhsSymbol).accept(this);
 
@@ -515,10 +517,10 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
         return WriteVariableNode.create(n.getSource(), n.getVariable(), expression, false, n.isSuper());
     }
 
-    private RCallNode prepareReplacementCall(FunctionCall f, List<ArgNode> args, String rhsSymbol, boolean simpleReplacement) {
+    private RCallNode prepareReplacementCall(FunctionCall f, List<ArgNode> args, String tmpSymbol, String rhsSymbol, boolean simpleReplacement) {
         // massage arguments to replacement function call (replace v with tmp, append a)
         List<ArgNode> rfArgs = new ArrayList<>();
-        rfArgs.add(ArgNode.create(null, null, AccessVariable.create(null, varSymbol, false)));
+        rfArgs.add(ArgNode.create(null, null, AccessVariable.create(null, tmpSymbol, false)));
         if (args.size() > 1) {
             for (int i = 1; i < args.size(); ++i) {
                 rfArgs.add(args.get(i));
@@ -555,33 +557,34 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
         FunctionCall f = replacement.getReplacementFunctionCall();
         List<ArgNode> args = f.getArguments();
         ASTNode val = args.get(0).getValue();
+        final String tmpSymbol = new Object().toString();
         if (val instanceof SimpleAccessVariable) {
             SimpleAccessVariable callArg = (SimpleAccessVariable) val;
             String vSymbol = callArg.getVariable();
             RNode[] seq = createReplacementSequence();
             ReadVariableNode replacementCallArg = createReplacementForVariableUsing(callArg, vSymbol, replacement);
-            String rhsSymbol = constructReplacementPrefix(seq, rhs, replacementCallArg, WriteVariableNode.Mode.COPY);
-            RNode replacementCall = prepareReplacementCall(f, args, rhsSymbol, true);
-            RNode assignFromTemp = WriteVariableNode.create(vSymbol, replacementCall, false, replacement.isSuper(), WriteVariableNode.Mode.TEMP);
-            return constructReplacementSuffix(seq, assignFromTemp, rhsSymbol, replacement.getSource());
+            String rhsSymbol = constructReplacementPrefix(seq, rhs, replacementCallArg, WriteVariableNode.Mode.COPY, tmpSymbol);
+            RNode replacementCall = prepareReplacementCall(f, args, tmpSymbol, rhsSymbol, true);
+            RNode assignFromTemp = WriteVariableNode.create(vSymbol, replacementCall, false, replacement.isSuper(), WriteVariableNode.Mode.INVISIBLE);
+            return constructReplacementSuffix(seq, assignFromTemp, tmpSymbol, rhsSymbol, replacement.getSource());
         } else if (val instanceof AccessVector) {
             AccessVector callArgAst = (AccessVector) val;
             RNode replacementArg = callArgAst.accept(this);
             RNode[] seq = createReplacementSequence();
-            String rhsSymbol = constructReplacementPrefix(seq, rhs, replacementArg, WriteVariableNode.Mode.COPY);
-            RNode replacementCall = prepareReplacementCall(f, args, rhsSymbol, false);
+            String rhsSymbol = constructReplacementPrefix(seq, rhs, replacementArg, WriteVariableNode.Mode.COPY, tmpSymbol);
+            RNode replacementCall = prepareReplacementCall(f, args, tmpSymbol, rhsSymbol, false);
             // see AssignVariable.writeVector (number of args must match)
             callArgAst.getArguments().add(ArgNode.create(rhsAst.getSource(), "value", rhsAst));
             RNode assignFromTemp = createVectorUpdate(callArgAst, replacementCall, replacement.isSuper(), replacement.getSource(), false);
-            return constructReplacementSuffix(seq, assignFromTemp, rhsSymbol, replacement.getSource());
+            return constructReplacementSuffix(seq, assignFromTemp, tmpSymbol, rhsSymbol, replacement.getSource());
         } else {
             FieldAccess callArgAst = (FieldAccess) val;
             RNode replacementArg = callArgAst.accept(this);
             RNode[] seq = createReplacementSequence();
-            String rhsSymbol = constructReplacementPrefix(seq, rhs, replacementArg, WriteVariableNode.Mode.COPY);
-            RNode replacementCall = prepareReplacementCall(f, args, rhsSymbol, false);
+            String rhsSymbol = constructReplacementPrefix(seq, rhs, replacementArg, WriteVariableNode.Mode.COPY, tmpSymbol);
+            RNode replacementCall = prepareReplacementCall(f, args, tmpSymbol, rhsSymbol, false);
             RNode assignFromTemp = createFieldUpdate(callArgAst, replacementCall, replacement.isSuper(), replacement.getSource());
-            return constructReplacementSuffix(seq, assignFromTemp, rhsSymbol, replacement.getSource());
+            return constructReplacementSuffix(seq, assignFromTemp, tmpSymbol, rhsSymbol, replacement.getSource());
         }
     }
 
@@ -670,25 +673,27 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
 
             RNode[] seq = createReplacementSequence();
             ReadVariableNode v = isSuper ? ReadVariableNode.createSuperLookup(varAST.getSource(), vSymbol) : ReadVariableNode.create(varAST.getSource(), vSymbol, varAST.shouldCopyValue());
-            final Object rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE);
+            final String tmpSymbol = new Object().toString();
+            final Object rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
             String rhsSymbolString = RRuntime.toString(rhsSymbol);
             RNode rhsAccess = ReadVariableNode.create(rhsSymbolString, false);
-            RNode tmpVarAccess = ReadVariableNode.create(varSymbol, false);
+            RNode tmpVarAccess = ReadVariableNode.create(tmpSymbol, false);
             UpdateFieldNode ufn = UpdateFieldNodeGen.create(tmpVarAccess, rhsAccess, a.getFieldName());
-            RNode assignFromTemp = WriteVariableNode.create(vSymbol, ufn, false, isSuper, WriteVariableNode.Mode.TEMP);
-            return constructReplacementSuffix(seq, assignFromTemp, rhsSymbol, source);
+            RNode assignFromTemp = WriteVariableNode.create(vSymbol, ufn, false, isSuper, WriteVariableNode.Mode.INVISIBLE);
+            return constructReplacementSuffix(seq, assignFromTemp, tmpSymbol, rhsSymbol, source);
         } else if (a.getLhs() instanceof AccessVector) {
             AccessVector vecAST = (AccessVector) a.getLhs();
             SimpleAccessVariable varAST = getVectorVariable(vecAST);
             RNode[] seq = new RNode[3];
+            final String tmpSymbol = new Object().toString();
             String rhsSymbol;
             if (varAST != null) {
                 String vSymbol = varAST.getVariable();
 
                 ReadVariableNode v = isSuper ? ReadVariableNode.createSuperLookup(varAST.getSource(), vSymbol) : ReadVariableNode.create(varAST.getSource(), vSymbol, varAST.shouldCopyValue());
-                rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE);
+                rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
             } else {
-                rhsSymbol = constructReplacementPrefix(seq, rhs, vecAST.getVector().accept(this), WriteVariableNode.Mode.INVISIBLE);
+                rhsSymbol = constructReplacementPrefix(seq, rhs, vecAST.getVector().accept(this), WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
             }
 
             RNode rhsAccess = AccessVariable.create(null, rhsSymbol).accept(this);
@@ -705,7 +710,8 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
             String vSymbol = varAST.getVariable();
             RNode[] seq = new RNode[3];
             ReadVariableNode v = isSuper ? ReadVariableNode.createSuperLookup(varAST.getSource(), vSymbol) : ReadVariableNode.create(varAST.getSource(), vSymbol, varAST.shouldCopyValue());
-            String rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE);
+            final String tmpSymbol = new Object().toString();
+            String rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE, tmpSymbol);
             RNode rhsAccess = AccessVariable.create(null, rhsSymbol).accept(this);
             UpdateFieldNode ufn = UpdateFieldNodeGen.create(accessAST.accept(this), rhsAccess, a.getFieldName());
             return constructRecursiveFieldUpdateSuffix(seq, ufn, accessAST, source, isSuper);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessArgumentNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessArgumentNode.java
index 033997b1fcacab57a9814b1cbccbc073d6b8abb2..daf546e131e97c3f1c7b9410306afbd8bb15eed1 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessArgumentNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessArgumentNode.java
@@ -31,6 +31,7 @@ import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.r.nodes.*;
 import com.oracle.truffle.r.nodes.access.variables.*;
+import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.function.*;
 import com.oracle.truffle.r.nodes.function.opt.*;
 import com.oracle.truffle.r.runtime.*;
@@ -93,6 +94,7 @@ public abstract class AccessArgumentNode extends RNode {
 
     @Specialization(guards = {"hasDefaultArg()"})
     protected Object doArgumentDefaultArg(VirtualFrame frame, @SuppressWarnings("unused") RMissing argMissing) {
+        assert !(getRootNode() instanceof RBuiltinRootNode) : getRootNode();
         Object result;
         if (canBeOptimized()) {
             // Insert default value
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java
index 40ec9b1990f3e00fe43e80dbb26d6588f0a0f779..61f6bcb6e06361532824e959ec004bff863a1a51 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java
@@ -51,8 +51,7 @@ public abstract class WriteVariableNode extends RNode implements VisibilityContr
 
         REGULAR,
         COPY,
-        INVISIBLE,
-        TEMP
+        INVISIBLE
     }
 
     public abstract boolean isArgWrite();
@@ -94,8 +93,14 @@ public abstract class WriteVariableNode extends RNode implements VisibilityContr
     protected final Object shareObjectValue(Frame frame, FrameSlot frameSlot, Object value, Mode mode, boolean isSuper) {
         Object newValue = value;
         if (!isArgWrite()) {
-            // for the meaning of INVISIBLE mode see the comment preceding the current method
-            if (mode != Mode.INVISIBLE && !isCurrentProfile.profile(isCurrentValue(frame, frameSlot, value))) {
+            // for the meaning of INVISIBLE mode see the comment preceding the current method;
+            // also change state when assigning to the enclosing frame as there must
+            // be a distinction between variables with the same name defined in
+            // different scopes, for example to correctly support:
+            // x<-1:3; f<-function() { x[2]<-10; x[2]<<-100; x[2]<-1000 }; f()
+            // or
+            // x<-c(1); f<-function() { x[[1]]<<-x[[1]] + 1; x }; a<-f(); b<-f(); c(a,b)
+            if ((mode != Mode.INVISIBLE || isSuper) && !isCurrentProfile.profile(isCurrentValue(frame, frameSlot, value))) {
                 if (isShareableProfile.profile(value instanceof RShareable)) {
                     RShareable rShareable = (RShareable) value;
                     if (isTemporaryProfile.profile(rShareable.isTemporary())) {
@@ -115,12 +120,7 @@ public abstract class WriteVariableNode extends RNode implements VisibilityContr
                         if (mode == Mode.COPY) {
                             RShareable shareableCopy = rShareable.copy();
                             newValue = shareableCopy;
-                        } else if (mode != Mode.TEMP || isSuper) {
-                            // mark shared when assigning to the enclosing frame as there must
-                            // be a distinction between variables with the same name defined in
-                            // different scopes, for example to correctly support:
-                            // x<-1:3; f<-function() { x[2]<-10; x[2]<<-100; x[2]<-1000 } ; f()
-
+                        } else {
                             rShareable.makeShared();
                         }
                     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/read/AccessArrayNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/read/AccessArrayNode.java
index 2327237e17274b7cdcd9dda39d8e375fbead3803..c14c9a32b06fac79b6c7d67ff1bbeb116867a960 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/read/AccessArrayNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/read/AccessArrayNode.java
@@ -34,8 +34,6 @@ import com.oracle.truffle.r.nodes.access.array.*;
 import com.oracle.truffle.r.nodes.access.array.ArrayPositionCast.OperatorConverterNode;
 import com.oracle.truffle.r.nodes.access.array.ArrayPositionCastNodeGen.OperatorConverterNodeGen;
 import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.DispatchType;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.NoGenericMethodException;
 import com.oracle.truffle.r.nodes.unary.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.RDeparse.State;
@@ -78,8 +76,8 @@ public abstract class AccessArrayNode extends RNode {
     @Child private GetNamesNode getNamesNode;
     @Child private GetDimNamesNode getDimNamesNode;
 
-    @Child private DispatchedCallNode dcn;
-    @Child private DispatchedCallNode dcnDrop;
+    @Child private UseMethodInternalNode dcn;
+    @Child private UseMethodInternalNode dcnDrop;
 
     public abstract RNode getVector();
 
@@ -253,17 +251,17 @@ public abstract class AccessArrayNode extends RNode {
             if (dropDim != RMissing.instance) {
                 if (dcnDrop == null) {
                     CompilerDirectives.transferToInterpreterAndInvalidate();
-                    dcnDrop = insert(DispatchedCallNode.create("[", DispatchType.UseMethod, DROP_SIGNATURE));
+                    dcnDrop = insert(new UseMethodInternalNode("[", DROP_SIGNATURE));
                 }
-                return dcnDrop.executeInternal(frame, container.getClassHierarchy(), new Object[]{container, inds, dropDim});
+                return dcnDrop.execute(frame, container.getClassHierarchy(), new Object[]{container, inds, dropDim});
             } else {
                 if (dcn == null) {
                     CompilerDirectives.transferToInterpreterAndInvalidate();
-                    dcn = insert(DispatchedCallNode.create("[", DispatchType.UseMethod, SIGNATURE));
+                    dcn = insert(new UseMethodInternalNode("[", SIGNATURE));
                 }
-                return dcn.executeInternal(frame, container.getClassHierarchy(), new Object[]{container, inds});
+                return dcn.execute(frame, container.getClassHierarchy(), new Object[]{container, inds});
             }
-        } catch (NoGenericMethodException e) {
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             return accessRecursive(frame, container, exact, position, recLevel, dropDim);
         }
     }
@@ -272,12 +270,12 @@ public abstract class AccessArrayNode extends RNode {
     protected Object accessObject(VirtualFrame frame, RAbstractContainer container, Object exact, int recLevel, Object position, Object dropDim) {
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(DispatchedCallNode.create("[[", DispatchType.UseMethod, EXACT_SIGNATURE));
+            dcn = insert(new UseMethodInternalNode("[[", EXACT_SIGNATURE));
         }
         try {
             Object inds = position instanceof Object[] ? new RArgsValuesAndNames((Object[]) position, ArgumentsSignature.empty(((Object[]) position).length)) : position;
-            return dcn.executeInternal(frame, container.getClassHierarchy(), new Object[]{container, inds, exact});
-        } catch (NoGenericMethodException e) {
+            return dcn.execute(frame, container.getClassHierarchy(), new Object[]{container, inds, exact});
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             return accessRecursive(frame, container, exact, position, recLevel, dropDim);
         }
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/write/UpdateArrayHelperNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/write/UpdateArrayHelperNode.java
index 564db41f365d05422087ce10c4e47391329fe455..7bb262c5da4691f200136fab2b11e14654673ce2 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/write/UpdateArrayHelperNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/write/UpdateArrayHelperNode.java
@@ -29,7 +29,6 @@ import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.Node.*;
 import com.oracle.truffle.api.source.*;
 import com.oracle.truffle.api.utilities.*;
 import com.oracle.truffle.r.nodes.*;
@@ -38,7 +37,6 @@ import com.oracle.truffle.r.nodes.access.array.ArrayPositionCast.OperatorConvert
 import com.oracle.truffle.r.nodes.access.array.ArrayPositionCastNodeGen.OperatorConverterNodeGen;
 import com.oracle.truffle.r.nodes.access.array.read.*;
 import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.*;
 import com.oracle.truffle.r.nodes.unary.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.RDeparse.State;
@@ -79,7 +77,7 @@ public abstract class UpdateArrayHelperNode extends RNode {
     @Child private OperatorConverterNode operatorConverter;
     @Child private SetMultiDimDataNode setMultiDimData;
 
-    @Child private DispatchedCallNode dcn;
+    @Child private UseMethodInternalNode dcn;
 
     private final BranchProfile error = BranchProfile.create();
     private final BranchProfile warning = BranchProfile.create();
@@ -118,8 +116,8 @@ public abstract class UpdateArrayHelperNode extends RNode {
         if (resultVector.isShared()) {
             vectorShared.enter();
             resultVector = (RIntVector) vector.copy();
-            resultVector.markNonTemporary();
         }
+        resultVector.markNonTemporary();
         int[] srcDimensions = resultVector.getDimensions();
         int numSrcDimensions = srcDimensions.length;
         int srcDimSize = srcDimensions[numSrcDimensions - 1];
@@ -252,12 +250,12 @@ public abstract class UpdateArrayHelperNode extends RNode {
     protected Object updateObjectSubset(VirtualFrame frame, Object v, Object value, int recLevel, Object positions, RAbstractContainer container) {
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(DispatchedCallNode.create("[<-", DispatchType.UseMethod, VALUE_SIGNATURE));
+            dcn = insert(new UseMethodInternalNode("[<-", VALUE_SIGNATURE));
         }
         try {
             Object inds = positions instanceof Object[] ? new RArgsValuesAndNames((Object[]) positions, ArgumentsSignature.empty(((Object[]) positions).length)) : positions;
-            return dcn.executeInternal(frame, container.getClassHierarchy(), new Object[]{container, inds, value});
-        } catch (NoGenericMethodException e) {
+            return dcn.execute(frame, container.getClassHierarchy(), new Object[]{container, inds, value});
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             return updateRecursive(frame, v, value, container, positions, recLevel);
         }
     }
@@ -266,12 +264,12 @@ public abstract class UpdateArrayHelperNode extends RNode {
     protected Object updateObject(VirtualFrame frame, Object v, Object value, int recLevel, Object positions, RAbstractContainer container) {
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(DispatchedCallNode.create("[[<-", DispatchType.UseMethod, VALUE_SIGNATURE));
+            dcn = insert(new UseMethodInternalNode("[[<-", VALUE_SIGNATURE));
         }
         try {
             Object inds = positions instanceof Object[] ? new RArgsValuesAndNames((Object[]) positions, ArgumentsSignature.empty(((Object[]) positions).length)) : positions;
-            return dcn.executeInternal(frame, container.getClassHierarchy(), new Object[]{container, inds, value});
-        } catch (NoGenericMethodException e) {
+            return dcn.execute(frame, container.getClassHierarchy(), new Object[]{container, inds, value});
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             return updateRecursive(frame, v, value, container, positions, recLevel);
         }
     }
@@ -1102,8 +1100,8 @@ public abstract class UpdateArrayHelperNode extends RNode {
         } else if (resultVector.isShared()) {
             vectorShared.enter();
             resultVector = (RIntVector) vector.copy();
-            resultVector.markNonTemporary();
         }
+        resultVector.markNonTemporary();
         return resultVector;
     }
 
@@ -1242,8 +1240,8 @@ public abstract class UpdateArrayHelperNode extends RNode {
         if (resultVector.isShared()) {
             vectorShared.enter();
             resultVector = (RDoubleVector) vector.copy();
-            resultVector.markNonTemporary();
         }
+        resultVector.markNonTemporary();
         int[] srcDimensions = resultVector.getDimensions();
         int numSrcDimensions = srcDimensions.length;
         int srcDimSize = srcDimensions[numSrcDimensions - 1];
@@ -1273,8 +1271,8 @@ public abstract class UpdateArrayHelperNode extends RNode {
         } else if (resultVector.isShared()) {
             vectorShared.enter();
             resultVector = (RDoubleVector) vector.copy();
-            resultVector.markNonTemporary();
         }
+        resultVector.markNonTemporary();
         return resultVector;
     }
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java
index 2c8ae235fd9227cdc0764afccf4ba4209248aab6..d686d7053fd83461922bf2c782482fe97a076f83 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/ReadVariableNode.java
@@ -174,20 +174,23 @@ public class ReadVariableNode extends RNode implements VisibilityController {
         controlVisibility();
 
         Object result;
-        while (true) {
-            if (read == null) {
-                CompilerDirectives.transferToInterpreterAndInvalidate();
-                read = initialize(frame, variableFrame);
-                needsCopying = kind == ReadKind.Copying && !(read instanceof Match || read instanceof DescriptorStableMatch);
-            }
+        if (read == null) {
+            initializeRead(frame, variableFrame);
+        }
+        try {
+            result = read.execute(frame, variableFrame);
+        } catch (InvalidAssumptionException | LayoutChangedException | FrameSlotTypeException e) {
+            initializeRead(frame, variableFrame);
             try {
                 result = read.execute(frame, variableFrame);
-            } catch (InvalidAssumptionException | LayoutChangedException | FrameSlotTypeException e) {
-                CompilerDirectives.transferToInterpreterAndInvalidate();
-                read = null;
-                continue;
+            } catch (InvalidAssumptionException | LayoutChangedException | FrameSlotTypeException e2) {
+                /*
+                 * This could be written a bit simpler using a loop, but partial evaluation will not
+                 * see that it never actually loops in compiled code, and thus create suboptimal
+                 * code.
+                 */
+                throw RInternalError.shouldNotReachHere("read initialization problem");
             }
-            break;
         }
         if (needsCopying && copyProfile.profile(result instanceof RAbstractVector)) {
             result = ((RAbstractVector) result).copy();
@@ -202,6 +205,12 @@ public class ReadVariableNode extends RNode implements VisibilityController {
         return result;
     }
 
+    private void initializeRead(VirtualFrame frame, Frame variableFrame) {
+        CompilerDirectives.transferToInterpreterAndInvalidate();
+        read = initialize(frame, variableFrame);
+        needsCopying = kind == ReadKind.Copying && !(read instanceof Match || read instanceof DescriptorStableMatch);
+    }
+
     private static final class LayoutChangedException extends SlowPathException {
         private static final long serialVersionUID = 3380913774357492013L;
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java
index 2e6271e738f7927223194bccb81fd882a04405a8..a307a54f1e3f0a4e71c1a1d250b289291b978573 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java
@@ -1094,17 +1094,17 @@ public abstract class BinaryBooleanNode extends RBuiltinNode {
 
     @Specialization(guards = "meaningfulOp(left, right)")
     protected Object doFactorOp(VirtualFrame frame, RFactor left, RFactor right) {
-        return recursiveOp(frame, RClosures.createFactorToVector(left, leftNACheck), RClosures.createFactorToVector(right, rightNACheck));
+        return recursiveOp(frame, RClosures.createFactorToVector(left, leftNACheck, attrProfiles), RClosures.createFactorToVector(right, rightNACheck, attrProfiles));
     }
 
     @Specialization(guards = {"meaningfulOp(left)", "!isFactor(right)"})
     protected Object doFactorOp(VirtualFrame frame, RFactor left, RAbstractContainer right) {
-        return recursiveOp(frame, RClosures.createFactorToVector(left, leftNACheck), right);
+        return recursiveOp(frame, RClosures.createFactorToVector(left, leftNACheck, attrProfiles), right);
     }
 
     @Specialization(guards = {"meaningfulOp(right)", "!isFactor(right)"})
     protected Object doFactorOp(VirtualFrame frame, RAbstractContainer left, RFactor right) {
-        return recursiveOp(frame, left, RClosures.createFactorToVector(right, rightNACheck));
+        return recursiveOp(frame, left, RClosures.createFactorToVector(right, rightNACheck, attrProfiles));
     }
 
     @Specialization(guards = "!meaningfulOp(left, right)")
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentMatcher.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentMatcher.java
index f549f6bb6fdd7c579fb64d3412a771e29c586fc3..206dac08414f5c7b860a87745e0ae820fa74541a 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentMatcher.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentMatcher.java
@@ -143,16 +143,19 @@ public class ArgumentMatcher {
         return new InlinedArguments(wrappedArgs, suppliedArgs.getSignature());
     }
 
-    public static MatchPermutation matchArguments(RFunction function, ArgumentsSignature suppliedSignature, SourceSection callSrc, boolean forNextMethod) {
+    public static MatchPermutation matchArguments(ArgumentsSignature suppliedSignature, ArgumentsSignature formalSignature, SourceSection callSrc, boolean forNextMethod) {
         CompilerAsserts.neverPartOfCompilation();
-        RRootNode rootNode = (RRootNode) function.getTarget().getRootNode();
-        FormalArguments formals = rootNode.getFormalArguments();
-        MatchPermutation match = permuteArguments(suppliedSignature, formals, callSrc, null, forNextMethod, index -> {
+        MatchPermutation match = permuteArguments(suppliedSignature, formalSignature, callSrc, null, forNextMethod, index -> {
             throw Utils.nyi("S3Dispatch should not have arg length mismatch");
         }, index -> suppliedSignature.getName(index));
         return match;
     }
 
+    public static ArgumentsSignature getFunctionSignature(RFunction function) {
+        RRootNode rootNode = (RRootNode) function.getTarget().getRootNode();
+        return rootNode.getFormalArguments().getSignature();
+    }
+
     public static Object[] matchArgumentsEvaluated(MatchPermutation match, Object[] evaluatedArgs, FormalArguments formals) {
         Object[] evaledArgs = new Object[match.resultPermutation.length];
         permuteArguments(formals, match, evaluatedArgs, evaledArgs);
@@ -183,6 +186,7 @@ public class ArgumentMatcher {
 
     @ExplodeLoop
     private static boolean permuteVarArgs(MatchPermutation match, Object[] evaluatedArgs, int varArgsLen, Object[] newVarArgs) {
+        CompilerAsserts.compilationConstant(varArgsLen);
         boolean nonNull = false;
         for (int i = 0; i < varArgsLen; i++) {
             newVarArgs[i] = evaluatedArgs[match.varargsPermutation[i]];
@@ -207,7 +211,7 @@ public class ArgumentMatcher {
     public static EvaluatedArguments matchArgumentsEvaluated(RFunction function, EvaluatedArguments evaluatedArgs, SourceSection callSrc, boolean forNextMethod) {
         RRootNode rootNode = (RRootNode) function.getTarget().getRootNode();
         FormalArguments formals = rootNode.getFormalArguments();
-        MatchPermutation match = permuteArguments(evaluatedArgs.getSignature(), formals, callSrc, null, forNextMethod, index -> {
+        MatchPermutation match = permuteArguments(evaluatedArgs.getSignature(), formals.getSignature(), callSrc, null, forNextMethod, index -> {
             throw Utils.nyi("S3Dispatch should not have arg length mismatch");
         }, index -> evaluatedArgs.getSignature().getName(index));
 
@@ -239,15 +243,6 @@ public class ArgumentMatcher {
         return new EvaluatedArguments(evaledArgs, formals.getSignature());
     }
 
-    public static void evaluatePromises(VirtualFrame frame, PromiseHelperNode promiseHelper, Object[] args) {
-        for (int i = 0; i < args.length; i++) {
-            Object arg = args[i];
-            if (arg instanceof RPromise) {
-                args[i] = promiseHelper.evaluate(frame, (RPromise) arg);
-            }
-        }
-    }
-
     private static String getErrorForArgument(RNode[] suppliedArgs, int index) {
         RNode node = suppliedArgs[index];
         if (node instanceof VarArgNode) {
@@ -288,8 +283,8 @@ public class ArgumentMatcher {
         FormalArguments formals = ((RRootNode) function.getTarget().getRootNode()).getFormalArguments();
 
         // Rearrange arguments
-        MatchPermutation match = permuteArguments(suppliedSignature, formals, callSrc, argsSrc, false, index -> ArgumentsSignature.VARARG_NAME.equals(RMissingHelper.unwrapName(suppliedArgs[index])),
-                        index -> getErrorForArgument(suppliedArgs, index));
+        MatchPermutation match = permuteArguments(suppliedSignature, formals.getSignature(), callSrc, argsSrc, false,
+                        index -> ArgumentsSignature.VARARG_NAME.equals(RMissingHelper.unwrapName(suppliedArgs[index])), index -> getErrorForArgument(suppliedArgs, index));
 
         RNode[] resArgs = new RNode[match.resultPermutation.length];
 
@@ -426,7 +421,7 @@ public class ArgumentMatcher {
      * also handling varargs.
      *
      * @param signature The signature (==names) of the supplied arguments
-     * @param formals The {@link FormalArguments} this function has
+     * @param formalSignature The signature (==names) of the formal arguments
      * @param callSrc The source of the function call currently executed
      * @param argsSrc The source code encapsulating the arguments, for debugging purposes
      * @param forNextMethod matching when evaluating NextMethod
@@ -434,16 +429,16 @@ public class ArgumentMatcher {
      * @return An array of type <T> with the supplied arguments in the correct order
      */
     @TruffleBoundary
-    private static MatchPermutation permuteArguments(ArgumentsSignature signature, FormalArguments formals, SourceSection callSrc, SourceSection argsSrc, boolean forNextMethod,
+    private static MatchPermutation permuteArguments(ArgumentsSignature signature, ArgumentsSignature formalSignature, SourceSection callSrc, SourceSection argsSrc, boolean forNextMethod,
                     IntPredicate isVarSuppliedVarargs, IntFunction<String> errorString) {
         // assert Arrays.stream(suppliedNames).allMatch(name -> name == null || !name.isEmpty());
 
         // Preparations
-        int varArgIndex = formals.getSignature().getVarArgIndex();
+        int varArgIndex = formalSignature.getVarArgIndex();
         boolean hasVarArgs = varArgIndex != ArgumentsSignature.NO_VARARG;
 
         // MATCH by exact name
-        int[] resultPermutation = new int[formals.getSignature().getLength()];
+        int[] resultPermutation = new int[formalSignature.getLength()];
         Arrays.fill(resultPermutation, MatchPermutation.UNMATCHED);
 
         boolean[] matchedSuppliedArgs = new boolean[signature.getLength()];
@@ -453,8 +448,8 @@ public class ArgumentMatcher {
             }
 
             // Search for argument name inside formal arguments
-            int formalIndex = findParameterPosition(formals.getSignature(), signature.getName(suppliedIndex), resultPermutation, suppliedIndex, hasVarArgs, callSrc, argsSrc, varArgIndex,
-                            forNextMethod, errorString);
+            int formalIndex = findParameterPosition(formalSignature, signature.getName(suppliedIndex), resultPermutation, suppliedIndex, hasVarArgs, callSrc, argsSrc, varArgIndex, forNextMethod,
+                            errorString);
             if (formalIndex != MatchPermutation.UNMATCHED) {
                 resultPermutation[formalIndex] = suppliedIndex;
                 matchedSuppliedArgs[suppliedIndex] = true;
@@ -465,7 +460,7 @@ public class ArgumentMatcher {
 
         // MATCH by position
         int suppliedIndex = -1;
-        int regularArgumentCount = hasVarArgs ? varArgIndex : formals.getSignature().getLength();
+        int regularArgumentCount = hasVarArgs ? varArgIndex : formalSignature.getLength();
         outer: for (int formalIndex = 0; formalIndex < regularArgumentCount; formalIndex++) {
             // Unmatched?
             if (resultPermutation[formalIndex] == MatchPermutation.UNMATCHED) {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentsNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentsNode.java
index b7ff42f2f045915eddb2efc5aa241325f8a67da1..1079a1da36b494dd702e75f6ad4fc8707a29458f 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentsNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentsNode.java
@@ -47,6 +47,7 @@ public abstract class ArgumentsNode extends RNode implements ArgumentsTrait {
         assert signature != null && signature.getLength() == arguments.length : Arrays.toString(arguments) + " " + signature;
         this.arguments = arguments;
         this.signature = signature;
+        assert signature != null;
     }
 
     @CreateWrapper
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/BinaryOpsGroupDispatchNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/BinaryOpsGroupDispatchNode.java
deleted file mode 100644
index 4e7782eca33ae03ab60e73eae55492dfd58ba403..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/BinaryOpsGroupDispatchNode.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 2014-2015, Purdue University
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-package com.oracle.truffle.r.nodes.function;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.source.*;
-import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.data.*;
-
-public class BinaryOpsGroupDispatchNode extends GroupDispatchNode {
-
-    private String targetFunctionNameR;
-    protected RFunction targetFunctionR;
-    private RStringVector klassR;
-    private RStringVector typeL;
-    private RStringVector typeR;
-    private boolean writeGroupR;
-    protected boolean isBuiltinCalled;
-
-    public BinaryOpsGroupDispatchNode(final String aGenericName, boolean hasVararg, SourceSection callSrc, SourceSection argSrc) {
-        super(aGenericName, RGroupGenerics.GROUP_OPS, hasVararg, callSrc, argSrc);
-    }
-
-    private void initDispatchTypes(final Object[] evaluatedArgs) {
-        // This is kind of tricky. We want to evaluate args before we know the function for which
-        // arguments should be matched. But as OpsGroupDispatchNode is for BinaryOperators, we can
-        // assume that arguments are in correct order!
-        this.typeL = getArgClass(evaluatedArgs[0]);
-        this.typeR = getArgClass(evaluatedArgs[1]);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame, final RArgsValuesAndNames argAndNames) {
-        Object[] evaluatedArgs = argAndNames.getValues();
-        ArgumentsSignature signature = argAndNames.getSignature();
-        if (!isExecuted) {
-            isExecuted = true;
-            executeNoCache(frame, evaluatedArgs);
-        }
-        if (isBuiltinCalled || (targetFunctionR == null && targetFunction == null)) {
-            return callBuiltin(frame, evaluatedArgs, signature);
-        }
-        return executeHelper(frame, evaluatedArgs, signature);
-    }
-
-    @Override
-    public boolean isSameType(Object[] args) {
-        return !isExecuted || isEqualType(getArgClass(args[0]), this.typeL) && isEqualType(getArgClass(args[1]), this.typeR);
-    }
-
-    protected void executeNoCache(VirtualFrame frame, Object[] evaluatedArgs) {
-        initDispatchTypes(evaluatedArgs);
-        if (this.typeR != null) {
-            this.type = this.typeR;
-            findTargetFunction(frame);
-            targetFunctionNameR = targetFunctionName;
-            targetFunctionR = targetFunction;
-            klassR = klass;
-            writeGroupR = writeGroup;
-        } else {
-            targetFunctionR = null;
-        }
-        if (this.typeL != null) {
-            this.type = this.typeL;
-            findTargetFunction(frame);
-        } else {
-            targetFunction = null;
-        }
-        if (targetFunctionR == null && targetFunction == null) {
-            isBuiltinCalled = true;
-            return;
-        }
-        if (targetFunctionR != targetFunction) {
-            if (targetFunctionR != null && targetFunction != null) {
-                if (targetFunctionName.equals("Ops.difftime") && targetFunctionNameR.equals("+.POSIXt") && targetFunctionNameR.equals("+.Date")) {
-                    targetFunction = null;
-                } else if (!(targetFunctionNameR.equals("Ops.difftime") && targetFunctionName.equals("+.POSIXt") && targetFunctionName.equals("-.POSIXt") && targetFunctionNameR.equals("+.Date") && targetFunctionNameR.equals("-.Date"))) {
-                    /*
-                     * TODO: throw warning
-                     * "Incompatible methods (\"%s\", \"%s\") for \"%s\""),lname,rname, generic
-                     */
-                    isBuiltinCalled = true;
-                    return;
-                }
-            }
-            if (targetFunction == null) {
-                targetFunction = targetFunctionR;
-                targetFunctionName = targetFunctionNameR;
-                klass = klassR;
-                writeGroup = writeGroupR;
-                this.type = this.typeR;
-            }
-        }
-        String[] methods = new String[evaluatedArgs.length];
-        for (int i = 0; i < methods.length; ++i) {
-            methods[i] = "";
-            RStringVector classHr = getArgClass(evaluatedArgs[i]);
-            if (classHr == null) {
-                continue;
-            }
-            for (int j = 0; j < classHr.getLength(); ++j) {
-                if (classHr.getDataAt(j).equals(klass.getDataAt(0))) {
-                    methods[i] = targetFunctionName;
-                    break;
-                }
-            }
-        }
-        dotMethod = RDataFactory.createStringVector(methods, true);
-    }
-}
-
-class GenericBinarysOpsGroupDispatchNode extends BinaryOpsGroupDispatchNode {
-
-    public GenericBinarysOpsGroupDispatchNode(String aGenericName, boolean hasVararg, SourceSection callSrc, SourceSection argSrc) {
-        super(aGenericName, hasVararg, callSrc, argSrc);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame, final RArgsValuesAndNames argAndNames) {
-        Object[] evaluatedArgs = argAndNames.getValues();
-        executeNoCache(frame, evaluatedArgs);
-        if (isBuiltinCalled || (targetFunctionR == null && targetFunction == null)) {
-            return callBuiltin(frame, evaluatedArgs, argAndNames.getSignature());
-        }
-        return executeHelper(frame, evaluatedArgs, argAndNames.getSignature());
-    }
-
-}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java
index 6563d5ff14b00b1b3899d3b6261c946d615f18b8..f9e95e8bb92acae2f2e48f40d9867f2dda1cd760 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java
@@ -25,19 +25,21 @@ package com.oracle.truffle.r.nodes.function;
 import java.util.*;
 
 import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.*;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.r.nodes.instrument.CreateWrapper;
-import com.oracle.truffle.api.instrument.ProbeNode;
+import com.oracle.truffle.api.instrument.*;
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.api.source.*;
 import com.oracle.truffle.r.nodes.*;
 import com.oracle.truffle.r.nodes.access.*;
 import com.oracle.truffle.r.nodes.access.variables.*;
+import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseCheckHelperNode;
+import com.oracle.truffle.r.nodes.instrument.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.RPromise.Closure;
-import com.oracle.truffle.r.runtime.env.REnvironment;
+import com.oracle.truffle.r.runtime.env.*;
 
 /**
  * This class denotes a list of {@link #getArguments()} together with their names given to a
@@ -52,6 +54,7 @@ import com.oracle.truffle.r.runtime.env.REnvironment;
 public class CallArgumentsNode extends ArgumentsNode implements UnmatchedArguments {
 
     @Child private FrameSlotNode varArgsSlotNode;
+    @Child private PromiseCheckHelperNode promiseHelper;
 
     /**
      * If a supplied argument is a {@link ReadVariableNode} whose name is "...", this field contains
@@ -282,6 +285,54 @@ public class CallArgumentsNode extends ArgumentsNode implements UnmatchedArgumen
         }
     }
 
+    @ExplodeLoop
+    public RArgsValuesAndNames evaluateFlatten(VirtualFrame frame) {
+        int size = arguments.length;
+        RArgsValuesAndNames varArgInfo = null;
+        ArgumentsSignature resultSignature = null;
+        String[] names = null;
+        if (containsVarArgsSymbol()) {
+            varArgInfo = getVarargsAndNames(frame);
+            size += (varArgInfo.length() - 1) * varArgsSymbolIndices.length;
+            names = new String[size];
+        } else {
+            resultSignature = signature;
+        }
+        Object[] values = new Object[size];
+        int vargsSymbolsIndex = 0;
+        int index = 0;
+        for (int i = 0; i < arguments.length; i++) {
+            if (vargsSymbolsIndex < varArgsSymbolIndices.length && varArgsSymbolIndices[vargsSymbolsIndex] == i) {
+                index = flattenVarArgs(frame, varArgInfo, names, values, index);
+                vargsSymbolsIndex++;
+            } else {
+                values[index] = arguments[i] == null ? RMissing.instance : arguments[i].execute(frame);
+                if (names != null) {
+                    names[index] = signature.getName(i);
+                }
+                index++;
+            }
+        }
+        if (resultSignature == null) {
+            resultSignature = ArgumentsSignature.get(names);
+        }
+        return new RArgsValuesAndNames(values, resultSignature);
+    }
+
+    private int flattenVarArgs(VirtualFrame frame, RArgsValuesAndNames varArgInfo, String[] names, Object[] values, int startIndex) {
+        int index = startIndex;
+        for (int j = 0; j < varArgInfo.length(); j++) {
+            if (promiseHelper == null) {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                promiseHelper = insert(new PromiseCheckHelperNode());
+            }
+            values[index] = promiseHelper.checkEvaluate(frame, varArgInfo.getValues()[j]);
+            names[index] = varArgInfo.getSignature().getName(j);
+            index++;
+        }
+        return index;
+    }
+
     @TruffleBoundary
     public static RNode wrapVarArgValue(Object varArgValue, int varArgIndex) {
         if (varArgValue instanceof RPromise) {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..09427823c7f3195b1ca0daaa2b90750018d0326c
--- /dev/null
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java
@@ -0,0 +1,289 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 2014, Purdue University
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+
+package com.oracle.truffle.r.nodes.function;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.source.*;
+import com.oracle.truffle.api.utilities.*;
+import com.oracle.truffle.r.nodes.*;
+import com.oracle.truffle.r.nodes.function.ArgumentMatcher.MatchPermutation;
+import com.oracle.truffle.r.runtime.*;
+import com.oracle.truffle.r.runtime.RArguments.*;
+import com.oracle.truffle.r.runtime.data.*;
+
+public abstract class CallMatcherNode extends Node {
+
+    protected final boolean forNextMethod;
+    protected final boolean argsAreEvaluated;
+
+    @Child private PromiseHelperNode promiseHelper;
+
+    public CallMatcherNode(boolean forNextMethod, boolean argsAreEvaluated) {
+        this.forNextMethod = forNextMethod;
+        this.argsAreEvaluated = argsAreEvaluated;
+    }
+
+    protected static final int MAX_CACHE_DEPTH = 3;
+
+    public static CallMatcherNode create(boolean forNextMethod, boolean argsAreEvaluated) {
+        return new CallMatcherUninitializedNode(forNextMethod, argsAreEvaluated);
+    }
+
+    public abstract Object execute(VirtualFrame frame, ArgumentsSignature suppliedSignature, Object[] suppliedArguments, RFunction function, S3Args s3Args);
+
+    private static CallMatcherCachedNode specialize(ArgumentsSignature suppliedSignature, Object[] suppliedArguments, RFunction function, SourceSection source, boolean forNextMethod,
+                    boolean argsAreEvaluated, CallMatcherNode next) {
+
+        int argCount = suppliedArguments.length;
+        int argListSize = argCount;
+
+        // extract vararg signatures from the arguments
+        ArgumentsSignature[] varArgSignatures = null;
+        for (int i = 0; i < suppliedArguments.length; i++) {
+            Object arg = suppliedArguments[i];
+            if (arg instanceof RArgsValuesAndNames) {
+                if (varArgSignatures == null) {
+                    varArgSignatures = new ArgumentsSignature[suppliedArguments.length];
+                }
+                varArgSignatures[i] = ((RArgsValuesAndNames) arg).getSignature();
+                argListSize += ((RArgsValuesAndNames) arg).length() - 1;
+            }
+        }
+
+        long[] preparePermutation;
+        ArgumentsSignature resultSignature;
+        if (varArgSignatures != null) {
+            resultSignature = ArgumentsSignature.flattenNames(suppliedSignature, varArgSignatures, argListSize);
+            preparePermutation = ArgumentsSignature.flattenIndexes(varArgSignatures, argListSize);
+        } else {
+            preparePermutation = new long[argCount];
+            for (int i = 0; i < argCount; i++) {
+                preparePermutation[i] = i;
+            }
+            resultSignature = suppliedSignature;
+        }
+
+        assert resultSignature != null;
+        ArgumentsSignature formalSignature = ArgumentMatcher.getFunctionSignature(function);
+        MatchPermutation permutation = ArgumentMatcher.matchArguments(resultSignature, formalSignature, source, forNextMethod);
+
+        CallMatcherCachedNode cachedNode = new CallMatcherCachedNode(suppliedSignature, varArgSignatures, function, preparePermutation, permutation, forNextMethod, argsAreEvaluated, next);
+        return cachedNode;
+    }
+
+    protected final Object[] prepareArguments(VirtualFrame frame, Object[] reorderedArgs, ArgumentsSignature reorderedSignature, RFunction function, S3Args s3Args) {
+        Object[] argObject = RArguments.create(function, getSourceSection(), null, RArguments.getDepth(frame) + 1, reorderedArgs, reorderedSignature);
+        RArguments.setS3Args(argObject, s3Args);
+        return argObject;
+    }
+
+    protected final void evaluatePromises(VirtualFrame frame, RFunction function, Object[] args) {
+        if (function.isBuiltin()) {
+            if (!argsAreEvaluated) {
+                for (int i = 0; i < args.length; i++) {
+                    Object arg = args[i];
+                    if (arg instanceof RPromise) {
+                        if (promiseHelper == null) {
+                            CompilerDirectives.transferToInterpreterAndInvalidate();
+                            promiseHelper = insert(new PromiseHelperNode());
+                        }
+                        args[i] = promiseHelper.evaluate(frame, (RPromise) arg);
+                    }
+                }
+            }
+            FormalArguments formals = ((RRootNode) function.getRootNode()).getFormalArguments();
+            for (int i = 0; i < args.length; i++) {
+                Object arg = args[i];
+                if (arg == RMissing.instance) {
+                    args[i] = formals.getInternalDefaultArgumentAt(i);
+                }
+            }
+        }
+    }
+
+    @NodeInfo(cost = NodeCost.UNINITIALIZED)
+    private static final class CallMatcherUninitializedNode extends CallMatcherNode {
+        public CallMatcherUninitializedNode(boolean forNextMethod, boolean argsAreEvaluated) {
+            super(forNextMethod, argsAreEvaluated);
+        }
+
+        private int depth;
+
+        @Override
+        public Object execute(VirtualFrame frame, ArgumentsSignature suppliedSignature, Object[] suppliedArguments, RFunction function, S3Args s3Args) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            if (++depth > MAX_CACHE_DEPTH) {
+                return replace(new CallMatcherGenericNode(forNextMethod, argsAreEvaluated)).execute(frame, suppliedSignature, suppliedArguments, function, s3Args);
+            } else {
+                CallMatcherCachedNode cachedNode = replace(specialize(suppliedSignature, suppliedArguments, function, getEncapsulatingSourceSection(), forNextMethod, argsAreEvaluated, this));
+                return cachedNode.execute(frame, suppliedSignature, suppliedArguments, function, s3Args);
+            }
+        }
+    }
+
+    private static final class CallMatcherCachedNode extends CallMatcherNode {
+
+        @Child private CallMatcherNode next;
+
+        @Child private DirectCallNode call;
+
+        private final ArgumentsSignature cachedSuppliedSignature;
+        private final ArgumentsSignature[] cachedVarArgSignatures;
+        private final RFunction cachedFunction;
+        private final RootCallTarget cachedCallTarget;
+        @CompilationFinal private final long[] preparePermutation;
+        private final MatchPermutation permutation;
+
+        public CallMatcherCachedNode(ArgumentsSignature suppliedSignature, ArgumentsSignature[] varArgSignatures, RFunction function, long[] preparePermutation, MatchPermutation permutation,
+                        boolean forNextMethod, boolean argsAreEvaluated, CallMatcherNode next) {
+            super(forNextMethod, argsAreEvaluated);
+            this.cachedSuppliedSignature = suppliedSignature;
+            this.cachedVarArgSignatures = varArgSignatures;
+            this.cachedFunction = function;
+            this.cachedCallTarget = function.getTarget();
+            this.preparePermutation = preparePermutation;
+            this.permutation = permutation;
+            this.next = next;
+
+            this.call = Truffle.getRuntime().createDirectCallNode(cachedCallTarget);
+        }
+
+        @Override
+        public Object execute(VirtualFrame frame, ArgumentsSignature suppliedSignature, Object[] suppliedArguments, RFunction function, S3Args s3Args) {
+            if (suppliedSignature == cachedSuppliedSignature && function == cachedFunction && checkLastArgSignature(cachedSuppliedSignature, suppliedArguments)) {
+
+                Object[] preparedArguments = prepareSuppliedArgument(preparePermutation, suppliedArguments);
+
+                FormalArguments formals = ((RRootNode) function.getRootNode()).getFormalArguments();
+                Object[] reorderedArgs = ArgumentMatcher.matchArgumentsEvaluated(permutation, preparedArguments, formals);
+                evaluatePromises(frame, function, reorderedArgs);
+                Object[] arguments = prepareArguments(frame, reorderedArgs, formals.getSignature(), function, s3Args);
+                return call.call(frame, arguments);
+            } else {
+                return next.execute(frame, suppliedSignature, suppliedArguments, function, s3Args);
+            }
+        }
+
+        @ExplodeLoop
+        private boolean checkLastArgSignature(ArgumentsSignature cachedSuppliedSignature2, Object[] arguments) {
+            for (int i = 0; i < cachedSuppliedSignature2.getLength(); i++) {
+                Object arg = arguments[i];
+                if (arg instanceof RArgsValuesAndNames) {
+                    if (cachedVarArgSignatures == null || cachedVarArgSignatures[i] != ((RArgsValuesAndNames) arg).getSignature()) {
+                        return false;
+                    }
+                } else {
+                    if (cachedVarArgSignatures != null && cachedVarArgSignatures[i] != null) {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+
+        @ExplodeLoop
+        private static Object[] prepareSuppliedArgument(long[] preparePermutation, Object[] arguments) {
+            Object[] result = new Object[preparePermutation.length];
+            for (int i = 0; i < result.length; i++) {
+                long source = preparePermutation[i];
+                if (source >= 0) {
+                    result[i] = arguments[(int) source];
+                } else {
+                    source = -source;
+                    result[i] = ((RArgsValuesAndNames) arguments[(int) (source >> 32)]).getValues()[(int) source];
+                }
+            }
+            return result;
+        }
+    }
+
+    private static final class CallMatcherGenericNode extends CallMatcherNode {
+
+        public CallMatcherGenericNode(boolean forNextMethod, boolean argsAreEvaluated) {
+            super(forNextMethod, argsAreEvaluated);
+        }
+
+        @Child private PromiseHelperNode promiseHelper;
+        @Child private IndirectCallNode call = Truffle.getRuntime().createIndirectCallNode();
+
+        private final ConditionProfile hasVarArgsProfile = ConditionProfile.createBinaryProfile();
+
+        @Override
+        public Object execute(VirtualFrame frame, ArgumentsSignature suppliedSignature, Object[] suppliedArguments, RFunction function, S3Args s3Args) {
+            EvaluatedArguments reorderedArgs = reorderArguments(suppliedArguments, function, suppliedSignature, getEncapsulatingSourceSection());
+            evaluatePromises(frame, function, reorderedArgs.arguments);
+            Object[] arguments = prepareArguments(frame, reorderedArgs.arguments, reorderedArgs.signature, function, s3Args);
+            return call.call(frame, function.getTarget(), arguments);
+        }
+
+        @TruffleBoundary
+        protected EvaluatedArguments reorderArguments(Object[] args, RFunction function, ArgumentsSignature paramSignature, SourceSection errorSourceSection) {
+            assert paramSignature.getLength() == args.length;
+
+            int argCount = args.length;
+            int argListSize = argCount;
+
+            boolean hasVarArgs = false;
+            for (int fi = 0; fi < argCount; ++fi) {
+                Object arg = args[fi];
+                if (hasVarArgsProfile.profile(arg instanceof RArgsValuesAndNames)) {
+                    hasVarArgs = true;
+                    argListSize += ((RArgsValuesAndNames) arg).length() - 1;
+                }
+            }
+            Object[] argValues;
+            ArgumentsSignature signature;
+            if (hasVarArgs) {
+                argValues = new Object[argListSize];
+                String[] argNames = new String[argListSize];
+                int index = 0;
+                for (int fi = 0; fi < argCount; ++fi) {
+                    Object arg = args[fi];
+                    if (arg instanceof RArgsValuesAndNames) {
+                        RArgsValuesAndNames varArgs = (RArgsValuesAndNames) arg;
+                        Object[] varArgValues = varArgs.getValues();
+                        ArgumentsSignature varArgSignature = varArgs.getSignature();
+                        for (int i = 0; i < varArgs.length(); i++) {
+                            argNames[index] = varArgSignature.getName(i);
+                            argValues[index++] = checkMissing(varArgValues[i]);
+                        }
+                    } else {
+                        argNames[index] = paramSignature.getName(fi);
+                        argValues[index++] = checkMissing(arg);
+                    }
+                }
+                signature = ArgumentsSignature.get(argNames);
+            } else {
+                argValues = new Object[argCount];
+                for (int i = 0; i < argCount; i++) {
+                    argValues[i] = checkMissing(args[i]);
+                }
+                signature = paramSignature;
+            }
+
+            // ...and use them as 'supplied' arguments...
+            EvaluatedArguments evaledArgs = EvaluatedArguments.create(argValues, signature);
+
+            // ...to match them against the chosen function's formal arguments
+            EvaluatedArguments evaluated = ArgumentMatcher.matchArgumentsEvaluated(function, evaledArgs, errorSourceSection, forNextMethod);
+            return evaluated;
+        }
+
+        protected static Object checkMissing(Object value) {
+            return RMissingHelper.isMissing(value) || (value instanceof RPromise && RMissingHelper.isMissingName((RPromise) value)) ? null : value;
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/DispatchNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/DispatchNode.java
deleted file mode 100644
index 49a53598905c27b1ec65dca129ca28e2b65ecf33..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/DispatchNode.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-
-package com.oracle.truffle.r.nodes.function;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.r.nodes.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.*;
-import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.data.*;
-
-public abstract class DispatchNode extends RNode {
-
-    protected final String genericName;
-
-    protected DispatchNode(String genericName) {
-        this.genericName = genericName;
-    }
-
-    public abstract Object executeGeneric(VirtualFrame frame, RStringVector aType);
-
-    @SuppressWarnings("unused")
-    public Object executeInternalGeneric(VirtualFrame frame, RStringVector aType, Object[] args) throws NoGenericMethodException {
-        throw RInternalError.shouldNotReachHere();
-    }
-
-    @SuppressWarnings("unused")
-    public Object executeInternal(VirtualFrame frame, Object[] args) throws NoGenericMethodException {
-        throw RInternalError.shouldNotReachHere();
-    }
-
-    public String getGenericName() {
-        return genericName;
-    }
-}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/DispatchedCallNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/DispatchedCallNode.java
deleted file mode 100644
index 6a83bc2121e4973f032d87540d835d81cfaf100a..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/DispatchedCallNode.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-
-package com.oracle.truffle.r.nodes.function;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.r.nodes.*;
-import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.data.*;
-
-public abstract class DispatchedCallNode extends RNode {
-
-    public static final class NoGenericMethodException extends ControlFlowException {
-        private static final long serialVersionUID = 344198853147758435L;
-    }
-
-    public static enum DispatchType {
-        UseMethod,
-        NextMethod
-    }
-
-    private static final int INLINE_CACHE_SIZE = 4;
-
-    public static DispatchedCallNode create(String genericName, DispatchType dispatchType, ArgumentsSignature signature) {
-        return new UninitializedDispatchedCallNode(genericName, dispatchType, signature);
-    }
-
-    public static DispatchedCallNode create(String genericName, String enclosingName, DispatchType dispatchType, Object[] args, ArgumentsSignature signature) {
-        return new UninitializedDispatchedCallNode(genericName, enclosingName, dispatchType, args, signature);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        throw RInternalError.shouldNotReachHere();
-    }
-
-    public abstract Object execute(VirtualFrame frame, RStringVector type);
-
-    public abstract Object executeInternal(VirtualFrame frame, RStringVector type, Object[] args) throws NoGenericMethodException;
-
-    @Override
-    public boolean isSyntax() {
-        return true;
-    }
-
-    @NodeInfo(cost = NodeCost.UNINITIALIZED)
-    private static final class UninitializedDispatchedCallNode extends DispatchedCallNode {
-        private final int depth;
-        private final String genericName;
-        private final String enclosingName;
-        private final DispatchType dispatchType;
-        @CompilationFinal private final Object[] args;
-        private final ArgumentsSignature signature;
-
-        private UninitializedDispatchedCallNode(String genericName, String enclosingName, DispatchType dispatchType, Object[] args, ArgumentsSignature signature) {
-            this.genericName = genericName;
-            this.enclosingName = enclosingName;
-            this.signature = signature;
-            this.depth = 0;
-            this.dispatchType = dispatchType;
-            this.args = args;
-        }
-
-        public UninitializedDispatchedCallNode(String genericName, DispatchType dispatchType, ArgumentsSignature signature) {
-            this(genericName, null, dispatchType, null, signature);
-        }
-
-        private UninitializedDispatchedCallNode(UninitializedDispatchedCallNode copy, int depth) {
-            this.depth = depth;
-            this.genericName = copy.genericName;
-            this.enclosingName = copy.enclosingName;
-            this.dispatchType = copy.dispatchType;
-            this.signature = copy.signature;
-            this.args = null;
-        }
-
-        @Override
-        public Object execute(VirtualFrame frame, RStringVector type) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            return specialize(type).execute(frame, type);
-        }
-
-        @Override
-        public Object executeInternal(VirtualFrame frame, RStringVector type, @SuppressWarnings("hiding") Object[] args) throws NoGenericMethodException {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            return specialize(type).executeInternal(frame, type, args);
-        }
-
-        private DispatchedCallNode specialize(RStringVector type) {
-            CompilerAsserts.neverPartOfCompilation();
-            if (depth < INLINE_CACHE_SIZE) {
-                DispatchNode current = createCurrentNode(type, true);
-                return replace(new CachedNode(current, new UninitializedDispatchedCallNode(this, depth + 1), type));
-            }
-            RError.performanceWarning("S3 method dispatch fallback to generic");
-            return this.replace(new GenericDispatchNode(createCurrentNode(type, false)));
-        }
-
-        private DispatchNode createCurrentNode(RStringVector type, boolean cached) {
-            switch (dispatchType) {
-                case NextMethod:
-                    return new NextMethodDispatchNode(genericName, type, args, signature, enclosingName);
-                case UseMethod:
-                    return cached ? UseMethodDispatchNode.createCached(genericName, type, signature) : UseMethodDispatchNode.createGeneric(genericName, signature);
-                default:
-                    throw RInternalError.shouldNotReachHere();
-            }
-        }
-    }
-
-    private static final class GenericDispatchNode extends DispatchedCallNode {
-
-        @Child private DispatchNode dcn;
-
-        public GenericDispatchNode(DispatchNode dcn) {
-            this.dcn = dcn;
-        }
-
-        @Override
-        public Object execute(VirtualFrame frame, RStringVector type) {
-            return dcn.executeGeneric(frame, type);
-        }
-
-        @Override
-        public Object executeInternal(VirtualFrame frame, RStringVector type, Object[] args) throws NoGenericMethodException {
-            return dcn.executeInternalGeneric(frame, type, args);
-        }
-    }
-
-    private static final class CachedNode extends DispatchedCallNode {
-
-        private final ConditionProfile sameIdentityProfile = ConditionProfile.createBinaryProfile();
-        private final BranchProfile nullTypeProfile = BranchProfile.create();
-        private final BranchProfile lengthMismatch = BranchProfile.create();
-        private final BranchProfile notIdentityEqualElements = BranchProfile.create();
-
-        @Child private DispatchedCallNode nextNode;
-        @Child private DispatchNode currentNode;
-        private final RStringVector cachedType;
-        @CompilationFinal private final String[] cachedTypeElements;
-
-        CachedNode(DispatchNode currentNode, DispatchedCallNode nextNode, RStringVector type) {
-            this.nextNode = nextNode;
-            this.currentNode = currentNode;
-            this.cachedType = type;
-            this.cachedTypeElements = type.getDataCopy();
-        }
-
-        private boolean isEqualType(RStringVector type) {
-            if (sameIdentityProfile.profile(type == cachedType)) {
-                return true;
-            }
-            if (cachedType == null) {
-                return false;
-            }
-            if (type == null) {
-                nullTypeProfile.enter();
-                return false;
-            }
-            if (type.getLength() != cachedTypeElements.length) {
-                lengthMismatch.enter();
-                return false;
-            }
-            return compareLoop(type);
-        }
-
-        @ExplodeLoop
-        private boolean compareLoop(RStringVector type) {
-            for (int i = 0; i < cachedTypeElements.length; i++) {
-                String elementOne = cachedTypeElements[i];
-                String elementTwo = type.getDataAt(i);
-                if (elementOne != elementTwo) {
-                    notIdentityEqualElements.enter();
-                    if (!elementOne.equals(elementTwo)) {
-                        return false;
-                    }
-                }
-            }
-            return true;
-        }
-
-        @Override
-        public Object execute(VirtualFrame frame, RStringVector type) {
-            if (isEqualType(type)) {
-                return currentNode.execute(frame);
-            }
-            return nextNode.execute(frame, type);
-        }
-
-        @Override
-        public Object executeInternal(VirtualFrame frame, RStringVector type, Object[] args) throws NoGenericMethodException {
-            if (isEqualType(type)) {
-                return currentNode.executeInternal(frame, args);
-            }
-            return nextNode.executeInternal(frame, type, args);
-        }
-    }
-}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/EvaluatedArguments.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/EvaluatedArguments.java
index eba9932508c35d1c4f9ba48c75803732e5cfdb00..acde52fb93d690f44592763beba59c87a1fd7433 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/EvaluatedArguments.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/EvaluatedArguments.java
@@ -26,8 +26,7 @@ import com.oracle.truffle.r.runtime.*;
 
 /**
  * Simple container class for holding arguments ({@link #getEvaluatedArgs()}) which are ready to be
- * pushed into {@link RArguments} (or are taken from there!). This is used by
- * {@link UseMethodDispatchNode}, e.g.
+ * pushed into {@link RArguments} (or are taken from there!).
  */
 public class EvaluatedArguments extends Arguments<Object> {
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionDefinitionNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionDefinitionNode.java
index d668931becdb9bb7612f298757620095d06cf201..612abb1d7a21af3957056b873ff503a686de4cf5 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionDefinitionNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionDefinitionNode.java
@@ -38,6 +38,7 @@ import com.oracle.truffle.r.nodes.access.*;
 import com.oracle.truffle.r.nodes.access.variables.*;
 import com.oracle.truffle.r.nodes.instrument.*;
 import com.oracle.truffle.r.runtime.*;
+import com.oracle.truffle.r.runtime.RArguments.S3Args;
 import com.oracle.truffle.r.runtime.RDeparse.State;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.env.*;
@@ -54,7 +55,6 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo
     @Child private InlineCacheNode<VirtualFrame, RNode> onExitExpressionCache;
     private final ConditionProfile onExitProfile = ConditionProfile.createBinaryProfile();
 
-    private final ConditionProfile s3SlotsProfile = ConditionProfile.createBinaryProfile();
     @CompilationFinal private BranchProfile invalidateFrameSlotProfile;
     @Child private FrameSlotNode dotGenericSlot;
     @Child private FrameSlotNode dotMethodSlot;
@@ -168,9 +168,7 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo
         Object restartStack = RErrorHandling.getRestartStack();
         try {
             verifyEnclosingAssumptions(vf);
-            if (s3SlotsProfile.profile(RArguments.hasS3Args(vf))) {
-                setupS3Slots(vf);
-            }
+            setupS3Slots(vf);
             return body.execute(vf);
         } catch (ReturnException ex) {
             returnProfile.enter();
@@ -206,6 +204,10 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo
     }
 
     private void setupS3Slots(VirtualFrame frame) {
+        S3Args args = RArguments.getS3Args(frame);
+        if (args == null) {
+            return;
+        }
         if (dotGenericSlot == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
             assert invalidateFrameSlotProfile == null && dotMethodSlot == null && dotClassSlot == null && dotGenericCallEnvSlot == null && dotGenericCallDefSlot == null && dotGroupSlot == null;
@@ -217,12 +219,12 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo
             dotGenericCallDefSlot = insert(FrameSlotNode.create(RRuntime.RDotGenericDefEnv, true));
             dotGroupSlot = insert(FrameSlotNode.create(RRuntime.RDotGroup, true));
         }
-        FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericSlot.executeFrameSlot(frame), RArguments.getS3Generic(frame), false, invalidateFrameSlotProfile);
-        FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotMethodSlot.executeFrameSlot(frame), RArguments.getS3Method(frame), false, invalidateFrameSlotProfile);
-        FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotClassSlot.executeFrameSlot(frame), RArguments.getS3Class(frame), false, invalidateFrameSlotProfile);
-        FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericCallEnvSlot.executeFrameSlot(frame), RArguments.getS3CallEnv(frame), false, invalidateFrameSlotProfile);
-        FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericCallDefSlot.executeFrameSlot(frame), RArguments.getS3DefEnv(frame), false, invalidateFrameSlotProfile);
-        FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGroupSlot.executeFrameSlot(frame), RArguments.getS3Group(frame), false, invalidateFrameSlotProfile);
+        FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericSlot.executeFrameSlot(frame), args.generic, false, invalidateFrameSlotProfile);
+        FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotMethodSlot.executeFrameSlot(frame), args.method, false, invalidateFrameSlotProfile);
+        FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotClassSlot.executeFrameSlot(frame), args.clazz, false, invalidateFrameSlotProfile);
+        FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericCallEnvSlot.executeFrameSlot(frame), args.callEnv, false, invalidateFrameSlotProfile);
+        FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGenericCallDefSlot.executeFrameSlot(frame), args.defEnv, false, invalidateFrameSlotProfile);
+        FrameSlotChangeMonitor.setObjectAndInvalidate(frame, dotGroupSlot.executeFrameSlot(frame), args.group, false, invalidateFrameSlotProfile);
     }
 
     @SuppressWarnings("unchecked")
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionExpressionNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionExpressionNode.java
index 7480eee27edcc5611c71f2da6472e843d946b561..5593dddd33baa7e8fef95c4f47b49b6c1974f893 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionExpressionNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionExpressionNode.java
@@ -23,6 +23,7 @@
 package com.oracle.truffle.r.nodes.function;
 
 import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.api.nodes.NodeUtil.NodeCountFilter;
@@ -31,9 +32,11 @@ import com.oracle.truffle.r.nodes.access.variables.*;
 import com.oracle.truffle.r.nodes.function.PromiseHelperNode.*;
 import com.oracle.truffle.r.nodes.function.opt.*;
 import com.oracle.truffle.r.nodes.instrument.*;
+import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.RDeparse.State;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.env.*;
+import com.oracle.truffle.r.runtime.env.frame.*;
 
 public final class FunctionExpressionNode extends RNode {
 
@@ -45,6 +48,9 @@ public final class FunctionExpressionNode extends RNode {
     private final PromiseDeoptimizeFrameNode deoptFrameNode;
     private final boolean containsDispatch;
 
+    @CompilationFinal private StableValue<MaterializedFrame> enclosingFrameAssumption;
+    @CompilationFinal private StableValue<FrameDescriptor> enclosingFrameDescriptorAssumption;
+
     public FunctionExpressionNode(RootCallTarget callTarget) {
         this.callTarget = callTarget;
         this.deoptFrameNode = EagerEvalHelper.optExprs() || EagerEvalHelper.optVars() || EagerEvalHelper.optDefault() ? new PromiseDeoptimizeFrameNode() : null;
@@ -57,6 +63,9 @@ public final class FunctionExpressionNode extends RNode {
             return false;
         };
         this.containsDispatch = NodeUtil.countNodes(callTarget.getRootNode(), dispatchingMethodsFilter) > 0;
+
+        this.enclosingFrameAssumption = FrameSlotChangeMonitor.getEnclosingFrameAssumption(callTarget.getRootNode().getFrameDescriptor());
+        this.enclosingFrameDescriptorAssumption = FrameSlotChangeMonitor.getEnclosingFrameDescriptorAssumption(callTarget.getRootNode().getFrameDescriptor());
     }
 
     @Override
@@ -64,6 +73,37 @@ public final class FunctionExpressionNode extends RNode {
         return executeFunction(frame);
     }
 
+    protected void verifyEnclosingAssumptions(VirtualFrame enclosingFrame, FrameDescriptor descriptor) {
+        if (enclosingFrameAssumption != null) {
+            try {
+                enclosingFrameAssumption.getAssumption().check();
+            } catch (InvalidAssumptionException e) {
+                enclosingFrameAssumption = FrameSlotChangeMonitor.getEnclosingFrameAssumption(descriptor);
+            }
+            if (enclosingFrameAssumption != null) {
+                if (enclosingFrameAssumption.getValue() != enclosingFrame) {
+                    CompilerDirectives.transferToInterpreterAndInvalidate();
+                    enclosingFrameAssumption = FrameSlotChangeMonitor.getOrInitializeEnclosingFrameAssumption(null, descriptor, enclosingFrameAssumption, enclosingFrame.materialize());
+                }
+            }
+        }
+        if (enclosingFrameDescriptorAssumption != null) {
+            try {
+                enclosingFrameDescriptorAssumption.getAssumption().check();
+            } catch (InvalidAssumptionException e) {
+                enclosingFrameDescriptorAssumption = FrameSlotChangeMonitor.getEnclosingFrameDescriptorAssumption(descriptor);
+            }
+            if (enclosingFrameDescriptorAssumption != null) {
+                FrameDescriptor enclosingFrameDescriptor = enclosingFrame.getFrameDescriptor();
+                if (enclosingFrameDescriptorAssumption.getValue() != enclosingFrameDescriptor) {
+                    CompilerDirectives.transferToInterpreterAndInvalidate();
+                    enclosingFrameDescriptorAssumption = FrameSlotChangeMonitor.getOrInitializeEnclosingFrameDescriptorAssumption(null, descriptor, enclosingFrameDescriptorAssumption,
+                                    enclosingFrameDescriptor);
+                }
+            }
+        }
+    }
+
     @Override
     public RFunction executeFunction(VirtualFrame frame) {
         MaterializedFrame matFrame = frame.materialize();
@@ -71,6 +111,7 @@ public final class FunctionExpressionNode extends RNode {
             // Deoptimize every promise which is now in this frame, as it might leave it's stack
             deoptFrameNode.deoptimizeFrame(matFrame);
         }
+        verifyEnclosingAssumptions(frame, callTarget.getRootNode().getFrameDescriptor());
         RFunction func = RDataFactory.createFunction("", callTarget, matFrame, containsDispatch);
         if (RInstrument.instrumentingEnabled()) {
             RInstrument.checkDebugRequested(callTarget.toString(), func);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GroupDispatchCallNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GroupDispatchCallNode.java
deleted file mode 100644
index 717aef204d82d3e3aca183cb39c695adc82a878f..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GroupDispatchCallNode.java
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 2014, Purdue University
- * Copyright (c) 2015, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-package com.oracle.truffle.r.nodes.function;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.source.*;
-import com.oracle.truffle.r.nodes.*;
-import com.oracle.truffle.r.nodes.access.*;
-import com.oracle.truffle.r.nodes.access.variables.*;
-import com.oracle.truffle.r.nodes.runtime.*;
-import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.RDeparse.State;
-import com.oracle.truffle.r.runtime.data.*;
-import com.oracle.truffle.r.runtime.data.model.*;
-import com.oracle.truffle.r.runtime.env.*;
-
-import edu.umd.cs.findbugs.annotations.*;
-
-public abstract class GroupDispatchCallNode extends RNode {
-
-    private static final int INLINE_CACHE_SIZE = 4;
-    @Child protected CallArgumentsNode callArgsNode;
-
-    public static GroupDispatchCallNode create(String aGenericName, String groupName, CallArgumentsNode callArgNode, SourceSection callSrc) {
-        GroupDispatchCallNode gdcn = new UninitializedGroupDispatchCallNode(aGenericName, groupName, callArgNode);
-        gdcn.assignSourceSection(callSrc);
-        return gdcn;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        throw new UnsupportedOperationException();
-    }
-
-    public abstract Object execute(VirtualFrame frame, RArgsValuesAndNames argAndNames);
-
-    public abstract String getGenericName();
-
-    public abstract String getGroupName();
-
-    public abstract SourceSection getCallSrc();
-
-    protected RArgsValuesAndNames evalArgs(VirtualFrame frame) {
-        UnrolledVariadicArguments unrolledArgs = callArgsNode.executeFlatten(frame);
-        RNode[] unevaledArgs = unrolledArgs.getArguments();
-        Object[] evaledArgs = new Object[unevaledArgs.length];
-        for (int i = 0; i < unevaledArgs.length; ++i) {
-            if (unevaledArgs[i] != null) {
-                evaledArgs[i] = unevaledArgs[i].execute(frame);
-            } else {
-                evaledArgs[i] = RMissing.instance;
-            }
-        }
-        // Delay assignment to allow recursion
-        RArgsValuesAndNames argAndNames = new RArgsValuesAndNames(evaledArgs, unrolledArgs.getSignature());
-        return argAndNames;
-    }
-
-    @Override
-    public boolean isSyntax() {
-        return true;
-    }
-
-    @Override
-    public void deparse(State state) {
-        String name = getGenericName();
-        RDeparse.Func func = RDeparse.getFunc(name);
-        if (func != null) {
-            // infix operator
-            RASTDeparse.deparseInfixOperator(state, this, func);
-        } else {
-            state.append(name);
-            this.callArgsNode.deparse(state);
-        }
-    }
-
-    @Override
-    public RNode substitute(REnvironment env) {
-        // TODO substitute aDispatchNode
-        return RASTUtils.createCall(this, (CallArgumentsNode) callArgsNode.substitute(env));
-    }
-
-    private static class UninitializedGroupDispatchCallNode extends GroupDispatchCallNode {
-
-        private final String groupName;
-        @CompilationFinal private final String genericName;
-        private final int depth;
-
-        public UninitializedGroupDispatchCallNode(String aGenericName, String groupName, CallArgumentsNode callArgNode) {
-            this.genericName = aGenericName;
-            this.groupName = groupName;
-            this.callArgsNode = callArgNode;
-            this.depth = 0;
-        }
-
-        private UninitializedGroupDispatchCallNode(UninitializedGroupDispatchCallNode copy, int depth) {
-            this.genericName = copy.genericName;
-            this.groupName = copy.groupName;
-            this.callArgsNode = copy.callArgsNode;
-            this.depth = depth;
-            this.assignSourceSection(copy.getSourceSection());
-        }
-
-        @Override
-        public Object execute(VirtualFrame frame) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            RArgsValuesAndNames argAndNames = evalArgs(frame);
-            return specialize(argAndNames).execute(frame, argAndNames);
-        }
-
-        @Override
-        public Object execute(VirtualFrame frame, RArgsValuesAndNames argAndNames) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            return specialize(argAndNames).execute(frame, argAndNames);
-        }
-
-        private GroupDispatchCallNode specialize(RArgsValuesAndNames argAndNames) {
-            CompilerAsserts.neverPartOfCompilation();
-            if (depth < INLINE_CACHE_SIZE) {
-                final GroupDispatchNode current = createCurrentNode(argAndNames.getValues());
-                final GroupDispatchCallNode cachedNode = new CachedNode(current, new UninitializedGroupDispatchCallNode(this, this.depth + 1), this.callArgsNode);
-                this.replace(cachedNode);
-                return cachedNode;
-            }
-            return this.replace(new GenericDispatchNode(createGenericNode(argAndNames.getValues())));
-        }
-
-        private GroupDispatchNode createGenericNode(Object[] evaluatedArgs) {
-            if (this.groupName == RGroupGenerics.GROUP_OPS) {
-                if (evaluatedArgs.length == 1) {
-                    return new GenericUnaryOpsGroupDispatchNode(this.genericName, this.callArgsNode.containsVarArgsSymbol(), this.getSourceSection(), this.callArgsNode.getEncapsulatingSourceSection());
-                }
-                if (evaluatedArgs.length >= 2) {
-                    return new GenericBinarysOpsGroupDispatchNode(this.genericName, this.callArgsNode.containsVarArgsSymbol(), this.getSourceSection(),
-                                    this.callArgsNode.getEncapsulatingSourceSection());
-                }
-            }
-            if (evaluatedArgs.length == 0 /*
-                                           * TODO add condition for when all the arguments are
-                                           * constant
-                                           */) {
-                return new GroupDispatchNode(this.genericName, this.groupName, this.callArgsNode.containsVarArgsSymbol(), this.getSourceSection(), this.callArgsNode.getEncapsulatingSourceSection());
-            }
-            return new GenericGroupDispatchNode(this.genericName, this.groupName, this.callArgsNode.containsVarArgsSymbol(), this.getSourceSection(), this.callArgsNode.getEncapsulatingSourceSection());
-        }
-
-        @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "GROUP_OPS is intended to be used as an identity")
-        protected GroupDispatchNode createCurrentNode(Object[] evaluatedArgs) {
-            if (this.groupName == RGroupGenerics.GROUP_OPS) {
-                if (evaluatedArgs.length == 1) {
-                    return new UnaryOpsGroupDispatchNode(this.genericName, this.callArgsNode.containsVarArgsSymbol(), this.getSourceSection(), this.callArgsNode.getEncapsulatingSourceSection());
-                }
-                if (evaluatedArgs.length >= 2) {
-                    return new BinaryOpsGroupDispatchNode(this.genericName, this.callArgsNode.containsVarArgsSymbol(), this.getSourceSection(), this.callArgsNode.getEncapsulatingSourceSection());
-                }
-            }
-            return new GroupDispatchNode(this.genericName, this.groupName, this.callArgsNode.containsVarArgsSymbol(), this.getSourceSection(), this.callArgsNode.getEncapsulatingSourceSection());
-        }
-
-        @Override
-        public String getGenericName() {
-            return this.genericName;
-        }
-
-        @Override
-        public String getGroupName() {
-            return this.groupName;
-        }
-
-        @Override
-        public SourceSection getCallSrc() {
-            return this.getSourceSection();
-        }
-    }
-
-    private static final class CachedNode extends GroupDispatchCallNode {
-
-        @Child private GroupDispatchCallNode nextNode;
-        @Child private GroupDispatchNode currentNode;
-
-        CachedNode(final GroupDispatchNode currentNode, GroupDispatchCallNode nextNode, CallArgumentsNode callArgsNode) {
-            this.nextNode = nextNode;
-            this.currentNode = currentNode;
-            this.callArgsNode = callArgsNode;
-        }
-
-        @Override
-        public Object execute(VirtualFrame frame) {
-            RArgsValuesAndNames argsAndNames = evalArgs(frame);
-            if (currentNode.isSameType(argsAndNames.getValues())) {
-                return currentNode.execute(frame, argsAndNames);
-            }
-            return nextNode.execute(frame, argsAndNames);
-        }
-
-        @Override
-        public Object execute(VirtualFrame frame, RArgsValuesAndNames argAndNames) {
-            if (currentNode.isSameType(argAndNames.getValues())) {
-                return currentNode.execute(frame, argAndNames);
-            }
-            return nextNode.execute(frame, argAndNames);
-        }
-
-        @Override
-        public String getGenericName() {
-            return currentNode.genericName;
-        }
-
-        @Override
-        public String getGroupName() {
-            return currentNode.groupName;
-        }
-
-        @Override
-        public SourceSection getCallSrc() {
-            return currentNode.callSrc;
-        }
-    }
-
-    private static final class GenericDispatchNode extends GroupDispatchCallNode {
-
-        @Child private GroupDispatchNode gdn;
-
-        public GenericDispatchNode(GroupDispatchNode gdn) {
-            this.gdn = gdn;
-        }
-
-        @Override
-        public Object execute(VirtualFrame frame, RArgsValuesAndNames argAndNames) {
-            return gdn.execute(frame, argAndNames);
-        }
-
-        @Override
-        public String getGenericName() {
-            return gdn.genericName;
-        }
-
-        @Override
-        public String getGroupName() {
-            return gdn.groupName;
-        }
-
-        @Override
-        public SourceSection getCallSrc() {
-            return gdn.callSrc;
-        }
-    }
-}
-
-class GroupDispatchNode extends S3DispatchLegacyNode {
-
-    @CompilationFinal protected boolean isExecuted = false;
-    @CompilationFinal protected final String groupName;
-    @Child protected ReadVariableNode builtInNode;
-    @Child private WriteVariableNode wvnGroup;
-    protected RFunction builtinFunc;
-    protected boolean writeGroup;
-    protected RStringVector dotMethod;
-    protected boolean hasVararg;
-    protected final SourceSection callSrc;
-    protected final SourceSection argSrc;
-
-    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
-
-    @Override
-    public Object executeGeneric(VirtualFrame frame, RStringVector aType) {
-        throw new AssertionError();
-    }
-
-    protected GroupDispatchNode(String genericName, String groupName, boolean hasVarArg, SourceSection callSrc, SourceSection argSrc) {
-        super(genericName, null);
-        this.groupName = groupName;
-        this.hasVararg = hasVarArg;
-        this.callSrc = callSrc;
-        this.argSrc = argSrc;
-    }
-
-    public boolean isSameType(Object[] args) {
-        return !isExecuted || isEqualType(getArgClass(args[0]), this.type);
-    }
-
-    protected void initBuiltin(VirtualFrame frame) {
-        // assuming builtin functions don't get redefined.
-        if (builtInNode == null) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            builtInNode = insert(ReadVariableNode.createFunctionLookup(genericName, true));
-            try {
-                builtinFunc = builtInNode.executeFunction(frame);
-            } catch (UnexpectedResultException e) {
-                throw new RuntimeException("Builtin " + this.genericName + " not found");
-            }
-        }
-    }
-
-    protected void findTargetFunction(VirtualFrame frame) {
-        String[] prefix = {genericName, groupName};
-        for (int i = 0; i < this.type.getLength(); ++i) {
-            for (int j = 0; j < prefix.length; ++j) {
-                findFunction(prefix[j], this.type.getDataAt(i), frame);
-                if (targetFunction != null) {
-                    RStringVector classVec = null;
-                    if (i > 0) {
-                        isFirst = false;
-                        classVec = RDataFactory.createStringVector(Arrays.copyOfRange(this.type.getDataWithoutCopying(), i, this.type.getLength()), true);
-                    } else {
-                        isFirst = true;
-                        classVec = this.type.copyResized(this.type.getLength(), false);
-                    }
-                    klass = classVec;
-                    if (j == 1) {
-                        writeGroup = true;
-                    } else {
-                        writeGroup = false;
-                    }
-                    return;
-                }
-            }
-        }
-    }
-
-    public Object execute(VirtualFrame frame, RArgsValuesAndNames argAndNames) {
-        Object[] evaluatedArgs = argAndNames.getValues();
-        ArgumentsSignature signature = argAndNames.getSignature();
-        if (!isExecuted) {
-            isExecuted = true;
-            this.type = evaluatedArgs.length > 0 ? getArgClass(evaluatedArgs[0]) : null;
-            if (this.type == null) {
-                return callBuiltin(frame, evaluatedArgs, signature);
-            }
-            findTargetFunction(frame);
-            if (targetFunction != null) {
-                dotMethod = RDataFactory.createStringVector(new String[]{targetFunctionName, ""}, true);
-            }
-        }
-        if (targetFunction == null) {
-            return callBuiltin(frame, evaluatedArgs, signature);
-        }
-        return executeHelper(frame, evaluatedArgs, signature);
-    }
-
-    protected Object callBuiltin(VirtualFrame frame, Object[] evaluatedArgs, ArgumentsSignature argumentsSignature) {
-        initBuiltin(frame);
-        EvaluatedArguments reorderedArgs = reorderArgs(frame, builtinFunc, evaluatedArgs, argumentsSignature, this.hasVararg, this.callSrc);
-        Object[] argObject = RArguments.create(builtinFunc, this.callSrc, null, RArguments.getDepth(frame), reorderedArgs.getEvaluatedArgs(), reorderedArgs.getSignature());
-        indirectCallNode.assignSourceSection(this.callSrc);
-        return indirectCallNode.call(frame, builtinFunc.getTarget(), argObject);
-    }
-
-    protected Object executeHelper(VirtualFrame frame, Object[] evaluatedArgs, ArgumentsSignature argumentsSignature) {
-        EvaluatedArguments reorderedArgs = reorderArgs(frame, targetFunction, evaluatedArgs, argumentsSignature, this.hasVararg, this.callSrc);
-        Object[] argObject = RArguments.createS3Args(targetFunction, this.callSrc, null, RArguments.getDepth(frame) + 1, reorderedArgs.getEvaluatedArgs(), reorderedArgs.getSignature());
-        genCallEnv = frame.materialize();
-        defineVarsAsArguments(argObject, genericName, klass, genCallEnv, genDefEnv);
-        RArguments.setS3Method(argObject, dotMethod);
-        if (writeGroup) {
-            RArguments.setS3Group(argObject, groupName);
-        }
-        indirectCallNode.assignSourceSection(this.callSrc);
-        /*
-         * Create a new frame s3VarDefFrame and define s3 generic variables such as .Generic,
-         * .Method etc. in it and set this frame as the enclosing frame of the target function
-         * ensuring that these generic variables are available to the called function. The real
-         * enclosing frame of the target function become enclosing frame of the new frame
-         * s3VarDefFrame. After the function returns reset the enclosing frame of the target
-         * function.
-         */
-        Object result = indirectCallNode.call(frame, targetFunction.getTarget(), argObject);
-        return result;
-    }
-
-    protected RStringVector getArgClass(Object arg) {
-        if (arg instanceof RAbstractContainer && ((RAbstractContainer) arg).isObject(attrProfiles)) {
-            return ((RAbstractContainer) arg).getClassHierarchy();
-        }
-        return null;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        throw new AssertionError();
-    }
-}
-
-class GenericGroupDispatchNode extends GroupDispatchNode {
-
-    protected GenericGroupDispatchNode(String aGenericName, String groupName, boolean hasVarArg, SourceSection callSrc, SourceSection argSrc) {
-        super(aGenericName, groupName, hasVarArg, callSrc, argSrc);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame, RArgsValuesAndNames argAndNames) {
-        Object[] evaluatedArgs = argAndNames.getValues();
-        ArgumentsSignature signature = argAndNames.getSignature();
-        this.type = getArgClass(evaluatedArgs[0]);
-        if (this.type == null) {
-            return callBuiltin(frame, evaluatedArgs, signature);
-        }
-        findTargetFunction(frame);
-        if (targetFunction != null) {
-            dotMethod = RDataFactory.createStringVector(new String[]{targetFunctionName, ""}, true);
-        }
-        if (targetFunction == null) {
-            callBuiltin(frame, evaluatedArgs, signature);
-        }
-        return executeHelper(frame, evaluatedArgs, signature);
-    }
-}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GroupDispatchNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GroupDispatchNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..6afdb0f6e4eb2f9e05229272aba1d0409e66eda7
--- /dev/null
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GroupDispatchNode.java
@@ -0,0 +1,169 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 2014, Purdue University
+ * Copyright (c) 2015, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.nodes.function;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.source.*;
+import com.oracle.truffle.api.utilities.*;
+import com.oracle.truffle.r.nodes.*;
+import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode.NoGenericMethodException;
+import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode.Result;
+import com.oracle.truffle.r.nodes.runtime.*;
+import com.oracle.truffle.r.runtime.*;
+import com.oracle.truffle.r.runtime.RArguments.S3Args;
+import com.oracle.truffle.r.runtime.RDeparse.State;
+import com.oracle.truffle.r.runtime.data.*;
+import com.oracle.truffle.r.runtime.data.model.*;
+import com.oracle.truffle.r.runtime.env.*;
+
+public final class GroupDispatchNode extends RNode {
+
+    @Child private CallArgumentsNode callArgsNode;
+    @Child private S3FunctionLookupNode functionLookupL;
+    @Child private S3FunctionLookupNode functionLookupR;
+    @Child private CallMatcherNode callMatcher = CallMatcherNode.create(false, true);
+
+    private final String genericName;
+    private final RGroupGenerics group;
+    private final RFunction builtinFunc;
+    private final boolean binaryLookup;
+
+    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
+    private final ConditionProfile mismatchProfile = ConditionProfile.createBinaryProfile();
+
+    public GroupDispatchNode(String genericName, RGroupGenerics group, CallArgumentsNode callArgNode) {
+        this.genericName = genericName.intern();
+        this.group = group;
+        this.callArgsNode = callArgNode;
+        this.binaryLookup = group == RGroupGenerics.Ops && callArgsNode.getSignature().getLength() >= 2;
+
+        this.builtinFunc = RContext.getEngine().lookupBuiltin(genericName);
+    }
+
+    public static GroupDispatchNode create(String aGenericName, RGroupGenerics group, CallArgumentsNode callArgNode, SourceSection callSrc) {
+        GroupDispatchNode gdcn = new GroupDispatchNode(aGenericName, group, callArgNode);
+        gdcn.assignSourceSection(callSrc);
+        return gdcn;
+    }
+
+    public String getGenericName() {
+        return genericName;
+    }
+
+    public RGroupGenerics getGroup() {
+        return group;
+    }
+
+    public SourceSection getCallSrc() {
+        return getSourceSection();
+    }
+
+    @Override
+    public boolean isSyntax() {
+        return true;
+    }
+
+    @Override
+    public void deparse(State state) {
+        String name = getGenericName();
+        RDeparse.Func func = RDeparse.getFunc(name);
+        if (func != null) {
+            // infix operator
+            RASTDeparse.deparseInfixOperator(state, this, func);
+        } else {
+            state.append(name);
+            callArgsNode.deparse(state);
+        }
+    }
+
+    @Override
+    public RNode substitute(REnvironment env) {
+        // TODO substitute aDispatchNode
+        return RASTUtils.createCall(this, (CallArgumentsNode) callArgsNode.substitute(env));
+    }
+
+    protected RStringVector getArgClass(Object arg) {
+        if (arg instanceof RAbstractContainer && ((RAbstractContainer) arg).isObject(attrProfiles)) {
+            return ((RAbstractContainer) arg).getClassHierarchy();
+        }
+        return null;
+    }
+
+    @Override
+    public Object execute(VirtualFrame frame) {
+        RArgsValuesAndNames argAndNames = callArgsNode.evaluateFlatten(frame);
+        Object[] evaluatedArgs = argAndNames.getValues();
+
+        RStringVector typeL = evaluatedArgs.length == 0 ? null : getArgClass(evaluatedArgs[0]);
+
+        Result resultL = null;
+        if (typeL != null) {
+            try {
+                if (functionLookupL == null) {
+                    CompilerDirectives.transferToInterpreterAndInvalidate();
+                    functionLookupL = insert(S3FunctionLookupNode.create(false, false));
+                }
+                resultL = functionLookupL.execute(frame, genericName, typeL, group.getName(), frame.materialize(), null);
+            } catch (NoGenericMethodException e) {
+                // fall-through
+            }
+        }
+        Result resultR = null;
+        if (binaryLookup) {
+            RStringVector typeR = getArgClass(evaluatedArgs[1]);
+            if (typeR != null) {
+                try {
+                    if (functionLookupR == null) {
+                        CompilerDirectives.transferToInterpreterAndInvalidate();
+                        functionLookupR = insert(S3FunctionLookupNode.create(false, false));
+                    }
+                    resultR = functionLookupR.execute(frame, genericName, typeR, group.getName(), frame.materialize(), null);
+                } catch (NoGenericMethodException e) {
+                    // fall-through
+                }
+            }
+        }
+
+        Result result;
+        RStringVector dotMethod;
+        if (resultL == null) {
+            if (resultR == null) {
+                result = null;
+                dotMethod = null;
+            } else {
+                result = resultR;
+                dotMethod = RDataFactory.createStringVector(new String[]{"", result.targetFunctionName}, true);
+            }
+        } else {
+            if (resultR == null) {
+                result = resultL;
+                dotMethod = RDataFactory.createStringVector(new String[]{result.targetFunctionName, ""}, true);
+            } else {
+                if (mismatchProfile.profile(resultL.function != resultR.function)) {
+                    RError.warning(getSourceSection(), RError.Message.INCOMPATIBLE_METHODS, resultL.targetFunctionName, resultR.targetFunctionName, genericName);
+                    result = null;
+                    dotMethod = null;
+                } else {
+                    result = resultL;
+                    dotMethod = RDataFactory.createStringVector(new String[]{result.targetFunctionName, result.targetFunctionName}, true);
+                }
+            }
+        }
+        ArgumentsSignature signature = argAndNames.getSignature();
+        if (result == null) {
+            return callMatcher.execute(frame, signature, evaluatedArgs, builtinFunc, null);
+        } else {
+            S3Args s3Args = new S3Args(genericName, result.clazz, dotMethod, frame.materialize(), null, result.groupMatch ? group.getName() : null);
+            return callMatcher.execute(frame, signature, evaluatedArgs, result.function, s3Args);
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/NextMethodDispatchNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/NextMethodDispatchNode.java
deleted file mode 100644
index 723cccc47d4a007e6326c97c95da6cdd8c28c96a..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/NextMethodDispatchNode.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-
-package com.oracle.truffle.r.nodes.function;
-
-import java.util.*;
-
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.r.nodes.access.*;
-import com.oracle.truffle.r.nodes.access.variables.*;
-import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.data.*;
-
-public final class NextMethodDispatchNode extends S3DispatchLegacyNode {
-
-    @Child private ReadVariableNode rvnDefEnv;
-    @Child private ReadVariableNode rvnCallEnv;
-    @Child private ReadVariableNode rvnGroup;
-    @Child private ReadVariableNode rvnMethod;
-    @Child private WriteVariableNode wvnGroup;
-    private String group;
-    private String lastGroup;
-    private String storedFunctionName;
-    private String lastStoredFunctionName;
-    private String baseName;
-    private String[] prefix;
-    private boolean hasGroup;
-    private boolean lastHasGroup;
-    @CompilationFinal private final Object[] args;
-
-    NextMethodDispatchNode(String genericName, RStringVector type, Object[] args, ArgumentsSignature suppliedSignature, String storedFunctionName) {
-        super(genericName, suppliedSignature);
-        this.type = type;
-        this.args = args;
-        this.storedFunctionName = storedFunctionName;
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        readGenericVars(frame);
-        if (!isSame() || !isFirst) {
-            findTargetFunction(frame);
-            storeValues();
-        }
-        return executeHelper(frame);
-    }
-
-    @Override
-    public Object executeGeneric(VirtualFrame frame, RStringVector aType) {
-        readGenericVars(frame);
-        findTargetFunction(frame);
-        storeValues();
-        return executeHelper(frame);
-    }
-
-    private EvaluatedArguments processArgs(VirtualFrame frame) {
-        int argsLength = args == null ? 0 : args.length;
-        // Extract arguments from current frame...
-        int funArgsLength = RArguments.getArgumentsLength(frame);
-        ArgumentsSignature signature = RArguments.getSignature(frame);
-        assert signature.getLength() == funArgsLength;
-        Object[] funArgValues = new Object[funArgsLength + argsLength];
-        String[] funArgNames = new String[funArgsLength + argsLength];
-        int index = 0;
-        for (int fi = 0; fi < funArgsLength; fi++) {
-            Object argVal = RArguments.getArgument(frame, fi);
-            if (argVal instanceof RArgsValuesAndNames) {
-                RArgsValuesAndNames varArgs = (RArgsValuesAndNames) argVal;
-                int varArgsLength = varArgs.length();
-                if (varArgsLength != 1) {
-                    funArgValues = Utils.resizeArray(funArgValues, funArgValues.length + varArgsLength - 1);
-                }
-                System.arraycopy(varArgs.getValues(), 0, funArgValues, index, varArgsLength);
-                if (varArgsLength != 1) {
-                    funArgNames = Utils.resizeArray(funArgNames, funArgNames.length + varArgsLength - 1);
-                }
-                for (int i = 0; i < varArgsLength; i++) {
-                    funArgNames[index++] = varArgs.getSignature().getName(i);
-                }
-            } else {
-                funArgValues[index] = argVal;
-                funArgNames[index] = signature.getName(fi);
-                index++;
-            }
-        }
-        if (argsLength > 0) {
-            for (int i = 0; i < argsLength; i++) {
-                funArgValues[index] = args[i];
-                if (suppliedSignature != null) {
-                    funArgNames[index] = suppliedSignature.getName(i);
-                }
-                index++;
-            }
-        }
-
-        ArgumentsSignature evaluatedSignature = ArgumentsSignature.get(funArgNames);
-
-        EvaluatedArguments evaledArgs = EvaluatedArguments.create(funArgValues, evaluatedSignature);
-        // ...to match them against the chosen function's formal arguments
-        EvaluatedArguments reorderedArgs = ArgumentMatcher.matchArgumentsEvaluated(targetFunction, evaledArgs, getSourceSection(), true);
-        if (targetFunction.isBuiltin()) {
-            ArgumentMatcher.evaluatePromises(frame, promiseHelper, reorderedArgs.getEvaluatedArgs());
-        }
-        return reorderedArgs;
-    }
-
-    private Object executeHelper(VirtualFrame frame) {
-        EvaluatedArguments evaledArgs = processArgs(frame);
-        Object[] argObject = RArguments.createS3Args(targetFunction, getSourceSection(), null, RArguments.getDepth(frame) + 1, evaledArgs.getEvaluatedArgs(), evaledArgs.getSignature());
-        defineVarsAsArguments(argObject, genericName, klass, genCallEnv, genDefEnv);
-        if (storedFunctionName != null) {
-            RArguments.setS3Method(argObject, storedFunctionName);
-        } else {
-            RArguments.setS3Method(argObject, targetFunctionName);
-        }
-        if (hasGroup) {
-            RArguments.setS3Group(argObject, this.group);
-        }
-        return indirectCallNode.call(frame, targetFunction.getTarget(), argObject);
-    }
-
-    private boolean isSame() {
-        return lastHasGroup == hasGroup && isEqual(lastGroup, group) && isEqual(lastStoredFunctionName, storedFunctionName);
-    }
-
-    private static boolean isEqual(String a, String b) {
-        if (a == null || b == null) {
-            return a == null && b == null;
-        }
-        return a.equals(b);
-    }
-
-    private void findTargetFunction(VirtualFrame frame) {
-        int nextClassIndex = 0;
-        String currentFunctionName = storedFunctionName == null ? RArguments.getFunction(frame).getName() : storedFunctionName;
-        for (int i = 0; i < type.getLength(); ++i) {
-            if (RRuntime.toString(new StringBuffer(baseName).append(RRuntime.RDOT).append(type.getDataAt(i))).equals(currentFunctionName)) {
-                nextClassIndex = i + 1;
-                break;
-            }
-        }
-        final int firstClassIndex = nextClassIndex;
-        int index = 0;
-        // First try generic.class then group.class.
-        for (; nextClassIndex < type.getLength() && targetFunction == null; ++nextClassIndex) {
-            for (; index < prefix.length && targetFunction == null; findFunction(prefix[index++], type.getDataAt(nextClassIndex), genCallEnv)) {
-            }
-        }
-        if (firstClassIndex == nextClassIndex && index == 1) {
-            isFirst = true;
-        } else {
-            isFirst = false;
-        }
-        if (targetFunction == null) {
-            findFunction(this.genericName, RRuntime.DEFAULT, genCallEnv);
-        }
-        if (targetFunction == null) {
-            findFunction(this.genericName, frame);
-            if (targetFunction == null || !targetFunction.isBuiltin()) {
-                throw RError.error(getEncapsulatingSourceSection(), RError.Message.NO_METHOD_FOUND);
-            }
-        }
-        RStringVector classVec = null;
-        if (nextClassIndex == type.getLength()) {
-            classVec = RDataFactory.createStringVector("");
-        } else {
-            classVec = RDataFactory.createStringVector(Arrays.copyOfRange(type.getDataWithoutCopying(), nextClassIndex, type.getLength()), true);
-        }
-        classVec.setAttr(RRuntime.PREVIOUS_ATTR_KEY, type.copyResized(type.getLength(), false));
-        klass = classVec;
-    }
-
-    private void storeValues() {
-        lastHasGroup = hasGroup;
-        lastGroup = group;
-        lastStoredFunctionName = storedFunctionName;
-    }
-
-    private void readGenericVars(VirtualFrame frame) {
-        genDefEnv = RArguments.getS3DefEnv(frame);
-        if (genDefEnv == null) {
-            genDefEnv = RArguments.getEnclosingFrame(frame);
-        }
-        genCallEnv = RArguments.getS3CallEnv(frame);
-        if (genCallEnv == null) {
-            genCallEnv = frame.materialize();
-        }
-        group = RArguments.getS3Group(frame);
-        if (group == null || group.isEmpty()) {
-            handleMissingGroup();
-        } else {
-            handlePresentGroup();
-        }
-
-        Object method = RArguments.getS3Method(frame);
-        String functionName;
-        if (method == null) {
-            functionName = null;
-        } else if (method instanceof String) {
-            functionName = (String) method;
-        } else {
-            functionName = ((RStringVector) method).getDataAt(0);
-        }
-        if (functionName != null) {
-            storedFunctionName = functionName;
-        }
-    }
-
-    private void handleMissingGroup() {
-        baseName = genericName;
-        prefix = new String[1];
-        prefix[0] = genericName;
-        hasGroup = false;
-    }
-
-    private void handlePresentGroup() {
-        baseName = group;
-        prefix = new String[2];
-        prefix[0] = genericName;
-        prefix[1] = group;
-        hasGroup = true;
-    }
-}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3DispatchNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3DispatchNode.java
deleted file mode 100644
index 3d5779a6761882b8db1187cd745f5f41ffcf5588..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3DispatchNode.java
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-
-package com.oracle.truffle.r.nodes.function;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.source.*;
-import com.oracle.truffle.api.utilities.*;
-import com.oracle.truffle.r.nodes.access.variables.*;
-import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.data.*;
-
-public abstract class S3DispatchNode extends DispatchNode {
-
-    @Child protected PromiseHelperNode promiseHelper = new PromiseHelperNode();
-
-    protected final BranchProfile errorProfile = BranchProfile.create();
-    private final ConditionProfile topLevelFrameProfile = ConditionProfile.createBinaryProfile();
-    private final ConditionProfile callerFrameSlotPath = ConditionProfile.createBinaryProfile();
-    private final ConditionProfile hasVarArgsProfile = ConditionProfile.createBinaryProfile();
-    private final ValueProfile argumentCountProfile = ValueProfile.createPrimitiveProfile();
-
-    protected final ArgumentsSignature suppliedSignature;
-
-    public S3DispatchNode(String genericName, ArgumentsSignature suppliedSignature) {
-        super(genericName);
-        this.suppliedSignature = suppliedSignature;
-    }
-
-    protected MaterializedFrame getCallerFrame(VirtualFrame frame) {
-        MaterializedFrame funFrame = RArguments.getCallerFrame(frame);
-        if (callerFrameSlotPath.profile(funFrame == null)) {
-            funFrame = Utils.getCallerFrame(frame, FrameAccess.MATERIALIZE).materialize();
-            RError.performanceWarning("slow caller frame access in UseMethod dispatch");
-        }
-        // S3 method can be dispatched from top-level where there is no caller frame
-        return topLevelFrameProfile.profile(funFrame == null) ? frame.materialize() : funFrame;
-    }
-
-    protected Object[] extractArguments(VirtualFrame frame, boolean fixedLength) {
-        int argCount = argumentCountProfile.profile(RArguments.getArgumentsLength(frame));
-        Object[] argValues = new Object[argCount];
-        if (fixedLength) {
-            extractArgumentsLoopFixedLength(frame, argCount, argValues);
-        } else {
-            extractArgumentsLoop(frame, argCount, argValues);
-        }
-        return argValues;
-    }
-
-    private static void extractArgumentsLoop(VirtualFrame frame, int argCount, Object[] argValues) {
-        for (int i = 0; i < argCount; i++) {
-            argValues[i] = RArguments.getArgument(frame, i);
-        }
-    }
-
-    @ExplodeLoop
-    private static void extractArgumentsLoopFixedLength(VirtualFrame frame, int argCount, Object[] argValues) {
-        for (int i = 0; i < argCount; i++) {
-            argValues[i] = RArguments.getArgument(frame, i);
-        }
-    }
-
-    protected EvaluatedArguments reorderArguments(Object[] args, RFunction function, ArgumentsSignature paramSignature, SourceSection errorSourceSection) {
-        assert paramSignature.getLength() == args.length;
-
-        int argCount = args.length;
-        int argListSize = argCount;
-
-        boolean hasVarArgs = false;
-        for (int fi = 0; fi < argCount; ++fi) {
-            Object arg = args[fi];
-            if (hasVarArgsProfile.profile(arg instanceof RArgsValuesAndNames)) {
-                hasVarArgs = true;
-                argListSize += ((RArgsValuesAndNames) arg).length() - 1;
-            }
-        }
-        Object[] argValues;
-        ArgumentsSignature signature;
-        if (hasVarArgs) {
-            argValues = new Object[argListSize];
-            String[] argNames = new String[argListSize];
-            int index = 0;
-            for (int fi = 0; fi < argCount; ++fi) {
-                Object arg = args[fi];
-                if (arg instanceof RArgsValuesAndNames) {
-                    RArgsValuesAndNames varArgs = (RArgsValuesAndNames) arg;
-                    Object[] varArgValues = varArgs.getValues();
-                    ArgumentsSignature varArgSignature = varArgs.getSignature();
-                    for (int i = 0; i < varArgs.length(); i++) {
-                        argNames[index] = varArgSignature.getName(i);
-                        argValues[index++] = checkMissing(varArgValues[i]);
-                    }
-                } else {
-                    argNames[index] = paramSignature.getName(fi);
-                    argValues[index++] = checkMissing(arg);
-                }
-            }
-            signature = ArgumentsSignature.get(argNames);
-        } else {
-            argValues = new Object[argCount];
-            for (int i = 0; i < argCount; i++) {
-                argValues[i] = checkMissing(args[i]);
-            }
-            signature = paramSignature;
-        }
-
-        // ...and use them as 'supplied' arguments...
-        EvaluatedArguments evaledArgs = EvaluatedArguments.create(argValues, signature);
-
-        // ...to match them against the chosen function's formal arguments
-        EvaluatedArguments evaluated = ArgumentMatcher.matchArgumentsEvaluated(function, evaledArgs, errorSourceSection, false);
-        return evaluated;
-    }
-
-    private final ValueProfile callerFrameProfile = ValueProfile.createClassProfile();
-
-    protected final Object[] prepareArguments(MaterializedFrame callerFrame, MaterializedFrame genericDefFrame, Object[] evaluatedArguments, ArgumentsSignature evaluatedSignature, RFunction function,
-                    RStringVector clazz, String functionName) {
-        CompilerAsserts.partialEvaluationConstant(evaluatedArguments.length);
-
-        MaterializedFrame profiledCallerFrame = callerFrameProfile.profile(callerFrame);
-        Object[] argObject = RArguments.createS3Args(function, getSourceSection(), null, RArguments.getDepth(profiledCallerFrame) + 1, evaluatedArguments, evaluatedSignature);
-        defineVarsAsArguments(argObject, genericName, clazz, profiledCallerFrame.materialize(), genericDefFrame);
-        RArguments.setS3Method(argObject, functionName);
-        return argObject;
-    }
-
-    protected static Object checkMissing(Object value) {
-        return RMissingHelper.isMissing(value) || (value instanceof RPromise && RMissingHelper.isMissingName((RPromise) value)) ? null : value;
-    }
-
-    @TruffleBoundary
-    protected static String functionName(String generic, String className) {
-        return new StringBuilder(generic).append(RRuntime.RDOT).append(className).toString();
-    }
-
-    protected static void defineVarsAsArguments(Object[] args, String genericName, RStringVector klass, MaterializedFrame genCallEnv, MaterializedFrame genDefEnv) {
-        RArguments.setS3Generic(args, genericName);
-        RArguments.setS3Class(args, klass);
-        RArguments.setS3CallEnv(args, genCallEnv);
-        RArguments.setS3DefEnv(args, genDefEnv);
-    }
-
-    protected static final class TargetLookupResult {
-        public final ReadVariableNode[] unsuccessfulReads;
-        public final ReadVariableNode successfulRead;
-        public final RFunction targetFunction;
-        public final String targetFunctionName;
-        public final RStringVector clazz;
-
-        public TargetLookupResult(ReadVariableNode[] unsuccessfulReads, ReadVariableNode successfulRead, RFunction targetFunction, String targetFunctionName, RStringVector clazz) {
-            this.unsuccessfulReads = unsuccessfulReads;
-            this.successfulRead = successfulRead;
-            this.targetFunction = targetFunction;
-            this.targetFunctionName = targetFunctionName;
-            this.clazz = clazz;
-        }
-    }
-
-    protected static TargetLookupResult findTargetFunctionLookup(Frame lookupFrame, RStringVector type, String genericName, boolean createReadVariableNodes) {
-        CompilerAsserts.neverPartOfCompilation();
-        RFunction targetFunction = null;
-        String targetFunctionName = null;
-        RStringVector clazz = null;
-        ArrayList<ReadVariableNode> unsuccessfulReads = createReadVariableNodes ? new ArrayList<>() : null;
-
-        for (int i = 0; i <= type.getLength(); i++) {
-            String clazzName = i == type.getLength() ? RRuntime.DEFAULT : type.getDataAt(i);
-            String functionName = genericName + RRuntime.RDOT + clazzName;
-            ReadVariableNode rvn;
-            Object func;
-            if (createReadVariableNodes) {
-                rvn = ReadVariableNode.createFunctionLookup(functionName, false);
-                func = rvn.execute(null, lookupFrame);
-            } else {
-                rvn = null;
-                func = ReadVariableNode.lookupFunction(functionName, lookupFrame);
-            }
-            if (func != null) {
-                assert func instanceof RFunction;
-                targetFunctionName = functionName;
-                targetFunction = (RFunction) func;
-
-                if (i == 0) {
-                    clazz = type.copyResized(type.getLength(), false);
-                } else if (i == type.getLength()) {
-                    clazz = null;
-                } else {
-                    clazz = RDataFactory.createStringVector(Arrays.copyOfRange(type.getDataWithoutCopying(), i, type.getLength()), true);
-                    clazz.setAttr(RRuntime.PREVIOUS_ATTR_KEY, type.copyResized(type.getLength(), false));
-                }
-                ReadVariableNode[] array = createReadVariableNodes ? unsuccessfulReads.toArray(new ReadVariableNode[unsuccessfulReads.size()]) : null;
-                return new TargetLookupResult(array, rvn, targetFunction, targetFunctionName, clazz);
-            } else {
-                if (createReadVariableNodes) {
-                    unsuccessfulReads.add(rvn);
-                }
-            }
-        }
-        if (createReadVariableNodes) {
-            return new TargetLookupResult(unsuccessfulReads.toArray(new ReadVariableNode[unsuccessfulReads.size()]), null, null, null, null);
-        } else {
-            return null;
-        }
-    }
-}
-
-abstract class S3DispatchLegacyNode extends S3DispatchNode {
-
-    protected RStringVector type;
-
-    @Child protected IndirectCallNode indirectCallNode = Truffle.getRuntime().createIndirectCallNode();
-    protected RStringVector klass;
-    protected MaterializedFrame genCallEnv;
-    protected MaterializedFrame genDefEnv;
-    protected boolean isFirst;
-
-    @CompilationFinal private String lastFun;
-    @Child private ReadVariableNode lookup;
-    protected String targetFunctionName;
-    protected RFunction targetFunction;
-
-    public S3DispatchLegacyNode(String genericName, ArgumentsSignature suppliedSignature) {
-        super(genericName, suppliedSignature);
-    }
-
-    protected void findFunction(String functionName, Frame frame) {
-        if (lookup == null || !functionName.equals(lastFun)) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            lastFun = functionName;
-            ReadVariableNode rvn = ReadVariableNode.createFunctionLookup(functionName, false);
-            lookup = lookup == null ? insert(rvn) : lookup.replace(rvn);
-        }
-        targetFunction = null;
-        targetFunctionName = null;
-        Object func;
-        if (frame instanceof VirtualFrame) {
-            func = lookup.execute((VirtualFrame) frame);
-        } else {
-            func = lookup.execute(null, frame);
-        }
-        if (func != null) {
-            assert func instanceof RFunction;
-            targetFunctionName = functionName;
-            targetFunction = (RFunction) func;
-        }
-    }
-
-    protected void findFunction(String generic, String className, Frame frame) {
-        checkLength(className, generic);
-        findFunction(functionName(generic, className), frame);
-    }
-
-    private void checkLength(String className, String generic) {
-        // The magic number two taken from src/main/objects.c
-        if (className.length() + generic.length() + 2 > RRuntime.LEN_METHOD_NAME) {
-            throw RError.error(getEncapsulatingSourceSection(), RError.Message.TOO_LONG_CLASS_NAME, generic);
-        }
-    }
-
-    protected EvaluatedArguments reorderArgs(VirtualFrame frame, RFunction func, Object[] evaluatedArgs, ArgumentsSignature signature, boolean hasVarArgs, SourceSection callSrc) {
-        Object[] evaluatedArgsValues = evaluatedArgs;
-        ArgumentsSignature evaluatedSignature;
-        int argCount = evaluatedArgs.length;
-        if (hasVarArgs) {
-            evaluatedSignature = signature;
-        } else {
-            String[] evaluatedArgNames = null;
-            evaluatedArgNames = new String[signature.getLength()];
-            int fi = 0;
-            int index = 0;
-            int argListSize = evaluatedArgsValues.length;
-            for (; fi < argCount; ++fi) {
-                Object arg = evaluatedArgs[fi];
-                if (arg instanceof RArgsValuesAndNames) {
-                    RArgsValuesAndNames varArgsContainer = (RArgsValuesAndNames) arg;
-                    argListSize += varArgsContainer.length() - 1;
-                    evaluatedArgsValues = Utils.resizeArray(evaluatedArgsValues, argListSize);
-                    // argNames can be null if no names for arguments have been specified
-                    evaluatedArgNames = evaluatedArgNames == null ? new String[argListSize] : Utils.resizeArray(evaluatedArgNames, argListSize);
-                    Object[] varArgsValues = varArgsContainer.getValues();
-                    for (int i = 0; i < varArgsContainer.length(); i++) {
-                        evaluatedArgsValues[index] = checkMissing(varArgsValues[i]);
-                        String name = varArgsContainer.getSignature().getName(i);
-                        evaluatedArgNames[index] = name;
-                        index++;
-                    }
-                } else {
-                    evaluatedArgsValues[index] = checkMissing(arg);
-                    evaluatedArgNames[index] = signature.getName(fi);
-                    index++;
-                }
-            }
-            evaluatedSignature = ArgumentsSignature.get(evaluatedArgNames);
-        }
-        EvaluatedArguments evaledArgs = EvaluatedArguments.create(evaluatedArgsValues, evaluatedSignature);
-        // ...to match them against the chosen function's formal arguments
-        EvaluatedArguments reorderedArgs = ArgumentMatcher.matchArgumentsEvaluated(func, evaledArgs, callSrc, false);
-        if (func.isBuiltin()) {
-            ArgumentMatcher.evaluatePromises(frame, promiseHelper, reorderedArgs.getEvaluatedArgs());
-        }
-        return reorderedArgs;
-    }
-
-    public static boolean isEqualType(RStringVector one, RStringVector two) {
-        if (one == null && two == null) {
-            return true;
-        }
-        if (one == null || two == null) {
-            return false;
-        }
-
-        if (one.getLength() != two.getLength()) {
-            return false;
-        }
-        for (int i = 0; i < one.getLength(); i++) {
-            if (!one.getDataAt(i).equals(two.getDataAt(i))) {
-                return false;
-            }
-        }
-        return true;
-    }
-}
-
-abstract class S3DispatchCachedNode extends S3DispatchNode {
-    protected final RStringVector type;
-
-    public S3DispatchCachedNode(String genericName, RStringVector type, ArgumentsSignature suppliedSignature) {
-        super(genericName, suppliedSignature);
-        this.type = type;
-    }
-}
-
-abstract class S3DispatchGenericNode extends S3DispatchNode {
-
-    public S3DispatchGenericNode(String genericName, ArgumentsSignature suppliedSignature) {
-        super(genericName, suppliedSignature);
-    }
-}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3FunctionLookupNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3FunctionLookupNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..0f932cb1e10c6e210716dfcd3177053e22712153
--- /dev/null
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3FunctionLookupNode.java
@@ -0,0 +1,326 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 2014, Purdue University
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.nodes.function;
+
+import java.util.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.CompilerDirectives.ValueType;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.utilities.*;
+import com.oracle.truffle.r.nodes.access.variables.*;
+import com.oracle.truffle.r.runtime.*;
+import com.oracle.truffle.r.runtime.data.*;
+
+public abstract class S3FunctionLookupNode extends Node {
+    protected static final int MAX_CACHE_DEPTH = 3;
+
+    protected final boolean throwsError;
+    protected final boolean nextMethod;
+
+    protected S3FunctionLookupNode(boolean throwsError, boolean nextMethod) {
+        this.throwsError = throwsError;
+        this.nextMethod = nextMethod;
+    }
+
+    @ValueType
+    public static final class Result {
+        public final String generic;
+        public final RFunction function;
+        public final ArgumentsSignature signature;
+        public final Object clazz;
+        public final String targetFunctionName;
+        public final boolean groupMatch;
+
+        public Result(String generic, RFunction function, Object clazz, String targetFunctionName, boolean groupMatch) {
+            this.generic = generic.intern();
+            this.function = function;
+            this.signature = function == null ? null : ArgumentMatcher.getFunctionSignature(function);
+            this.clazz = clazz;
+            this.targetFunctionName = targetFunctionName;
+            this.groupMatch = groupMatch;
+        }
+    }
+
+    public static S3FunctionLookupNode create(boolean throwsError, boolean nextMethod) {
+        return new UseMethodFunctionLookupUninitializedNode(throwsError, nextMethod);
+    }
+
+    public abstract S3FunctionLookupNode.Result execute(VirtualFrame frame, String genericName, RStringVector type, String group, MaterializedFrame callerFrame, MaterializedFrame genericDefFrame);
+
+    private static UseMethodFunctionLookupCachedNode specialize(String genericName, RStringVector type, String group, MaterializedFrame callerFrame, MaterializedFrame genericDefFrame,
+                    S3FunctionLookupNode next) {
+        // look for a match in the caller frame hierarchy
+        TargetLookupResult result = findTargetFunctionLookup(callerFrame, type, genericName, group, true, next.nextMethod);
+        ReadVariableNode[] unsuccessfulReadsCaller = result.unsuccessfulReads;
+        ReadVariableNode[] unsuccessfulReadsDef = null;
+        if (result.successfulRead == null) {
+            if (genericDefFrame != null) {
+                // look for a match in the generic def frame hierarchy
+                result = findTargetFunctionLookup(genericDefFrame, type, genericName, group, true, next.nextMethod);
+                unsuccessfulReadsDef = result.unsuccessfulReads;
+            }
+        }
+        RFunction builtin = null;
+        if (next.throwsError && result.successfulRead == null) {
+            builtin = RContext.getEngine().lookupBuiltin(genericName);
+        }
+
+        UseMethodFunctionLookupCachedNode cachedNode = new UseMethodFunctionLookupCachedNode(next.throwsError, next.nextMethod, genericName, type, group, builtin, unsuccessfulReadsCaller,
+                        unsuccessfulReadsDef, result.successfulRead, result.targetFunction, result.clazz, result.targetFunctionName, result.groupMatch, next);
+        return cachedNode;
+    }
+
+    protected static final class TargetLookupResult {
+        public final ReadVariableNode[] unsuccessfulReads;
+        public final ReadVariableNode successfulRead;
+        public final RFunction targetFunction;
+        public final String targetFunctionName;
+        public final Object clazz;
+        public final boolean groupMatch;
+
+        public TargetLookupResult(ReadVariableNode[] unsuccessfulReads, ReadVariableNode successfulRead, RFunction targetFunction, String targetFunctionName, Object clazz, boolean groupMatch) {
+            this.unsuccessfulReads = unsuccessfulReads;
+            this.successfulRead = successfulRead;
+            this.targetFunction = targetFunction;
+            this.targetFunctionName = targetFunctionName;
+            this.clazz = clazz;
+            this.groupMatch = groupMatch;
+        }
+    }
+
+    protected static TargetLookupResult findTargetFunctionLookup(Frame lookupFrame, RStringVector type, String genericName, String groupName, boolean createReadVariableNodes, boolean nextMethod) {
+        CompilerAsserts.neverPartOfCompilation();
+        ArrayList<ReadVariableNode> unsuccessfulReads = createReadVariableNodes ? new ArrayList<>() : null;
+
+        for (int i = nextMethod ? 1 : 0; i <= type.getLength(); i++) {
+            String clazzName = i == type.getLength() ? RRuntime.DEFAULT : type.getDataAt(i);
+            String functionName = genericName + RRuntime.RDOT + clazzName;
+            TargetLookupResult lookupResult = lookupFunction(lookupFrame, type, createReadVariableNodes, unsuccessfulReads, i, functionName, false);
+            if (lookupResult == null && groupName != null) {
+                functionName = groupName + RRuntime.RDOT + clazzName;
+                lookupResult = lookupFunction(lookupFrame, type, createReadVariableNodes, unsuccessfulReads, i, functionName, true);
+            }
+            if (lookupResult != null) {
+                return lookupResult;
+            }
+        }
+        if (createReadVariableNodes) {
+            return new TargetLookupResult(unsuccessfulReads.toArray(new ReadVariableNode[unsuccessfulReads.size()]), null, null, null, null, false);
+        } else {
+            return null;
+        }
+    }
+
+    private static TargetLookupResult lookupFunction(Frame lookupFrame, RStringVector type, boolean createReadVariableNodes, ArrayList<ReadVariableNode> unsuccessfulReads, int i, String functionName,
+                    boolean groupMatch) {
+        ReadVariableNode rvn;
+        RFunction function;
+        if (createReadVariableNodes) {
+            rvn = ReadVariableNode.createFunctionLookup(functionName, false);
+            function = (RFunction) rvn.execute(null, lookupFrame);
+        } else {
+            rvn = null;
+            function = ReadVariableNode.lookupFunction(functionName, lookupFrame);
+        }
+        if (function != null) {
+            ReadVariableNode[] array = createReadVariableNodes ? unsuccessfulReads.toArray(new ReadVariableNode[unsuccessfulReads.size()]) : null;
+            if (i == 0) {
+                return new TargetLookupResult(array, rvn, function, functionName, type.copyResized(type.getLength(), false), groupMatch);
+            } else if (i == type.getLength()) {
+                return new TargetLookupResult(array, rvn, function, functionName, RNull.instance, groupMatch);
+            } else {
+                RStringVector clazz = RDataFactory.createStringVector(Arrays.copyOfRange(type.getDataWithoutCopying(), i, type.getLength()), true);
+                clazz.setAttr(RRuntime.PREVIOUS_ATTR_KEY, type.copyResized(type.getLength(), false));
+                return new TargetLookupResult(array, rvn, function, functionName, clazz, groupMatch);
+            }
+        } else {
+            if (createReadVariableNodes) {
+                unsuccessfulReads.add(rvn);
+            }
+            return null;
+        }
+    }
+
+    @NodeInfo(cost = NodeCost.UNINITIALIZED)
+    private static final class UseMethodFunctionLookupUninitializedNode extends S3FunctionLookupNode {
+        private int depth;
+
+        public UseMethodFunctionLookupUninitializedNode(boolean throwsError, boolean nextMethod) {
+            super(throwsError, nextMethod);
+        }
+
+        @Override
+        public Result execute(VirtualFrame frame, String genericName, RStringVector type, String group, MaterializedFrame callerFrame, MaterializedFrame genericDefFrame) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            if (++depth > MAX_CACHE_DEPTH) {
+                return replace(new UseMethodFunctionLookupGenericNode(throwsError, nextMethod)).execute(frame, genericName, type, group, callerFrame, genericDefFrame);
+            } else {
+                UseMethodFunctionLookupCachedNode cachedNode = replace(specialize(genericName, type, group, callerFrame, genericDefFrame, this));
+                return cachedNode.execute(frame, genericName, type, group, callerFrame, genericDefFrame);
+            }
+        }
+    }
+
+    private static final class UseMethodFunctionLookupCachedNode extends S3FunctionLookupNode {
+
+        @Child private S3FunctionLookupNode next;
+
+        @CompilationFinal private final String[] cachedTypeContents;
+        @Children private final ReadVariableNode[] unsuccessfulReadsCallerFrame;
+        @Children private final ReadVariableNode[] unsuccessfulReadsDefFrame;
+        // if unsuccessfulReadsDefFrame != null, then this read will go to the def frame
+        @Child private ReadVariableNode successfulRead;
+
+        private final String cachedGenericName;
+        private final RStringVector cachedType;
+
+        private final Result result;
+
+        private final ConditionProfile sameIdentityProfile = ConditionProfile.createBinaryProfile();
+        private final ConditionProfile genericIdentityProfile = ConditionProfile.createBinaryProfile();
+        private final BranchProfile nullTypeProfile = BranchProfile.create();
+        private final BranchProfile lengthMismatch = BranchProfile.create();
+        private final BranchProfile notIdentityEqualElements = BranchProfile.create();
+        private final String cachedGroup;
+        private final RFunction builtin;
+
+        public UseMethodFunctionLookupCachedNode(boolean throwsError, boolean nextMethod, String genericName, RStringVector type, String group, RFunction builtin,
+                        ReadVariableNode[] unsuccessfulReadsCaller, ReadVariableNode[] unsuccessfulReadsDef, ReadVariableNode successfulRead, RFunction function, Object clazz,
+                        String targetFunctionName, boolean groupMatch, S3FunctionLookupNode next) {
+            super(throwsError, nextMethod);
+            this.cachedGenericName = genericName;
+            this.cachedGroup = group;
+            this.builtin = builtin;
+            this.next = next;
+            this.cachedType = type;
+            this.cachedTypeContents = type.getDataCopy();
+            this.unsuccessfulReadsCallerFrame = unsuccessfulReadsCaller;
+            this.unsuccessfulReadsDefFrame = unsuccessfulReadsDef;
+            this.successfulRead = successfulRead;
+            this.result = new Result(genericName, function != null ? function : builtin, clazz, targetFunctionName, groupMatch);
+        }
+
+        @Override
+        public Result execute(VirtualFrame frame, String genericName, RStringVector type, String group, MaterializedFrame callerFrame, MaterializedFrame genericDefFrame) {
+            do {
+                if ((genericIdentityProfile.profile(genericName != cachedGenericName) && !cachedGenericName.equals(genericName)) || !isEqualType(type) || group != cachedGroup) {
+                    return next.execute(frame, genericName, type, group, callerFrame, genericDefFrame);
+                }
+                if (!executeReads(unsuccessfulReadsCallerFrame, callerFrame)) {
+                    break;
+                }
+                if (unsuccessfulReadsDefFrame != null && !executeReads(unsuccessfulReadsDefFrame, genericDefFrame)) {
+                    break;
+                }
+                if (successfulRead != null) {
+                    Object actualFunction = successfulRead.execute(null, unsuccessfulReadsDefFrame == null ? callerFrame : genericDefFrame);
+                    if (actualFunction != result.function) {
+                        break;
+                    }
+                    return result;
+                }
+                if (throwsError) {
+                    if (builtin != null) {
+                        return result;
+                    }
+                    throw RError.error(getEncapsulatingSourceSection(), RError.Message.UNKNOWN_FUNCTION_USE_METHOD, genericName, type);
+                } else {
+                    throw S3FunctionLookupNode.NoGenericMethodException.instance;
+                }
+            } while (true);
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            return replace(specialize(genericName, type, group, callerFrame, genericDefFrame, next)).execute(frame, genericName, type, group, callerFrame, genericDefFrame);
+        }
+
+        @ExplodeLoop
+        private static boolean executeReads(ReadVariableNode[] reads, Frame callerFrame) {
+            for (ReadVariableNode read : reads) {
+                if (read.execute(null, callerFrame) != null) {
+                    CompilerDirectives.transferToInterpreterAndInvalidate();
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        private boolean isEqualType(RStringVector type) {
+            if (sameIdentityProfile.profile(type == cachedType)) {
+                return true;
+            }
+            if (cachedType == null) {
+                return false;
+            }
+            if (type == null) {
+                nullTypeProfile.enter();
+                return false;
+            }
+            if (type.getLength() != cachedTypeContents.length) {
+                lengthMismatch.enter();
+                return false;
+            }
+            return compareLoop(type);
+        }
+
+        @ExplodeLoop
+        private boolean compareLoop(RStringVector type) {
+            for (int i = 0; i < cachedTypeContents.length; i++) {
+                String elementOne = cachedTypeContents[i];
+                String elementTwo = type.getDataAt(i);
+                if (elementOne != elementTwo) {
+                    notIdentityEqualElements.enter();
+                    if (!elementOne.equals(elementTwo)) {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+    }
+
+    private static final class UseMethodFunctionLookupGenericNode extends S3FunctionLookupNode {
+
+        protected UseMethodFunctionLookupGenericNode(boolean throwsError, boolean nextMethod) {
+            super(throwsError, nextMethod);
+        }
+
+        @Override
+        public Result execute(VirtualFrame frame, String genericName, RStringVector type, String group, MaterializedFrame callerFrame, MaterializedFrame genericDefFrame) {
+            TargetLookupResult lookupResult = findTargetFunctionLookup(callerFrame, type, genericName, group, false, nextMethod);
+            if (lookupResult == null) {
+                lookupResult = findTargetFunctionLookup(genericDefFrame, type, genericName, group, false, nextMethod);
+                if (lookupResult == null) {
+                    if (throwsError) {
+                        RFunction function = RContext.getEngine().lookupBuiltin(genericName);
+                        if (function != null) {
+                            return new Result(genericName, function, RNull.instance, genericName, false);
+                        }
+                        throw RError.error(getEncapsulatingSourceSection(), RError.Message.UNKNOWN_FUNCTION_USE_METHOD, genericName, RRuntime.toString(type));
+                    } else {
+                        throw S3FunctionLookupNode.NoGenericMethodException.instance;
+                    }
+                }
+            }
+            return new Result(genericName, lookupResult.targetFunction, lookupResult.clazz, lookupResult.targetFunctionName, lookupResult.groupMatch);
+        }
+    }
+
+    @SuppressWarnings("serial")
+    public static final class NoGenericMethodException extends ControlFlowException {
+        public static final NoGenericMethodException instance = new NoGenericMethodException();
+
+        private NoGenericMethodException() {
+            // empty
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UnaryOpsGroupDispatchNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UnaryOpsGroupDispatchNode.java
deleted file mode 100644
index d95ca5c21ef877b0e8c8b1833ab3086cf0efd9b6..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UnaryOpsGroupDispatchNode.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 2014-2015, Purdue University
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-package com.oracle.truffle.r.nodes.function;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.source.*;
-import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.data.*;
-
-/*
- * Handles unary +, - and ! operators.
- */
-public class UnaryOpsGroupDispatchNode extends GroupDispatchNode {
-
-    public UnaryOpsGroupDispatchNode(String genericName, boolean hasVararg, SourceSection callSrc, SourceSection argSrc) {
-        super(genericName, RGroupGenerics.GROUP_OPS, hasVararg, callSrc, argSrc);
-    }
-
-    @Override
-    protected Object callBuiltin(VirtualFrame frame, Object[] evaluatedArgs, ArgumentsSignature signature) {
-        initBuiltin(frame);
-        Object[] args = ((HasSignature) builtinFunc.getRootNode()).getSignature().getLength() == 1 ? new Object[]{evaluatedArgs[0]} : new Object[]{evaluatedArgs[0], RMissing.instance};
-        Object[] argObject = RArguments.create(builtinFunc, callSrc, null, RArguments.getDepth(frame) + 1, args);
-        return indirectCallNode.call(frame, builtinFunc.getTarget(), argObject);
-    }
-}
-
-class GenericUnaryOpsGroupDispatchNode extends UnaryOpsGroupDispatchNode {
-
-    public GenericUnaryOpsGroupDispatchNode(String genericName, boolean hasVararg, SourceSection callSrc, SourceSection argSrc) {
-        super(genericName, hasVararg, callSrc, argSrc);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame, final RArgsValuesAndNames argAndNames) {
-        Object[] evaluatedArgs = argAndNames.getValues();
-        ArgumentsSignature signature = argAndNames.getSignature();
-        this.type = getArgClass(evaluatedArgs[0]);
-        if (this.type == null) {
-            return callBuiltin(frame, evaluatedArgs, signature);
-        }
-        findTargetFunction(frame);
-        if (targetFunction != null) {
-            dotMethod = RDataFactory.createStringVector(new String[]{targetFunctionName, ""}, true);
-        }
-        if (targetFunction == null) {
-            callBuiltin(frame, evaluatedArgs, signature);
-        }
-        return executeHelper(frame, evaluatedArgs, signature);
-    }
-}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodDispatchNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodDispatchNode.java
deleted file mode 100644
index 9a7bcc91fdd08a0f10dfcbf65a39c3fd30448151..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodDispatchNode.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-
-package com.oracle.truffle.r.nodes.function;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.source.*;
-import com.oracle.truffle.r.nodes.*;
-import com.oracle.truffle.r.nodes.access.variables.*;
-import com.oracle.truffle.r.nodes.function.ArgumentMatcher.MatchPermutation;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.NoGenericMethodException;
-import com.oracle.truffle.r.runtime.*;
-import com.oracle.truffle.r.runtime.data.*;
-
-/**
- * {@code UseMethod} is typically called like this:
- *
- * <pre>
- * f <- function(x, ...) UseMethod("f")
- * </pre>
- *
- * Locating the correct call depends on the class of {@code x}, and the search starts in the
- * enclosing (parent) environment of {@code f}, which, for packages, which is where most of these
- * definitions occur, will be the package {@code namepace} enviromnent.
- */
-public abstract class UseMethodDispatchNode {
-
-    public static DispatchNode createCached(String genericName, RStringVector type, ArgumentsSignature suppliedSignature) {
-        return new UseMethodDispatchCachedNode(genericName, type, suppliedSignature);
-    }
-
-    public static DispatchNode createGeneric(String genericName, ArgumentsSignature suppliedSignature) {
-        return new UseMethodDispatchGenericNode(genericName, suppliedSignature);
-    }
-}
-
-final class UseMethodDispatchCachedNode extends S3DispatchCachedNode {
-
-    @NodeInfo(cost = NodeCost.NONE)
-    private static final class CheckReadsNode extends Node {
-        @Children private final ReadVariableNode[] unsuccessfulReadsCallerFrame;
-        @Children private final ReadVariableNode[] unsuccessfulReadsDefFrame;
-        // if readsDefFrame != null, then this read will go to the def frame
-        @Child private ReadVariableNode successfulRead;
-
-        private final ArgumentsSignature signature;
-        @CompilationFinal private final ArgumentsSignature[] varArgSignature;
-
-        public final RFunction function;
-        public final RStringVector clazz;
-        public final String functionName;
-        @CompilationFinal public long[] preparePermutation;
-        public final MatchPermutation permutation;
-
-        public CheckReadsNode(ReadVariableNode[] unsuccessfulReadsCallerFrame, ReadVariableNode[] unsuccessfulReadsDefFrame, ReadVariableNode successfulRead, RFunction function, RStringVector clazz,
-                        String functionName, ArgumentsSignature signature, ArgumentsSignature[] varArgSignature, long[] preparePermutation, MatchPermutation permutation) {
-            this.unsuccessfulReadsCallerFrame = unsuccessfulReadsCallerFrame;
-            this.unsuccessfulReadsDefFrame = unsuccessfulReadsDefFrame;
-            this.successfulRead = successfulRead;
-            this.function = function;
-            this.clazz = clazz;
-            this.functionName = functionName;
-            this.signature = signature;
-            this.varArgSignature = varArgSignature;
-            this.preparePermutation = preparePermutation;
-            this.permutation = permutation;
-        }
-
-        public boolean executeReads(Frame callerFrame, MaterializedFrame defFrame, ArgumentsSignature actualSignature, Object[] actualArguments) {
-            if (actualSignature != signature) {
-                return false;
-            }
-            if (!checkLastArgSignature(actualArguments)) {
-                return false;
-            }
-            if (!executeReads(unsuccessfulReadsCallerFrame, callerFrame)) {
-                return false;
-            }
-            Object actualFunction;
-            if (unsuccessfulReadsDefFrame != null) {
-                if (!executeReads(unsuccessfulReadsDefFrame, defFrame)) {
-                    return false;
-                }
-                actualFunction = successfulRead.execute(null, defFrame);
-            } else {
-                actualFunction = successfulRead.execute(null, callerFrame);
-            }
-            return actualFunction == function;
-        }
-
-        @ExplodeLoop
-        private static boolean executeReads(ReadVariableNode[] reads, Frame callerFrame) {
-            for (ReadVariableNode read : reads) {
-                if (read.execute(null, callerFrame) != null) {
-                    CompilerDirectives.transferToInterpreterAndInvalidate();
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        @ExplodeLoop
-        private boolean checkLastArgSignature(Object[] arguments) {
-            for (int i = 0; i < arguments.length; i++) {
-                Object arg = arguments[i];
-                if (arg instanceof RArgsValuesAndNames) {
-                    if (varArgSignature == null || varArgSignature[i] != ((RArgsValuesAndNames) arg).getSignature()) {
-                        return false;
-                    }
-                } else {
-                    if (varArgSignature != null && varArgSignature[i] != null) {
-                        return false;
-                    }
-                }
-            }
-            return true;
-        }
-    }
-
-    @Child private CheckReadsNode cached;
-    @Child private DirectCallNode call;
-
-    public UseMethodDispatchCachedNode(String genericName, RStringVector type, ArgumentsSignature suppliedSignature) {
-        super(genericName, type, suppliedSignature);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        Object[] arguments = extractArguments(frame, true);
-        ArgumentsSignature signature = RArguments.getSignature(frame);
-        MaterializedFrame genericDefFrame = RArguments.getEnclosingFrame(frame);
-        MaterializedFrame callerFrame = getCallerFrame(frame);
-
-        if (cached == null || !cached.executeReads(callerFrame, genericDefFrame, signature, arguments)) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            specialize(frame, callerFrame, signature, arguments, true);
-        }
-
-        Object[] preparedArguments = prepareSuppliedArgument(cached.preparePermutation, arguments);
-
-        RRootNode rootNode = (RRootNode) cached.function.getTarget().getRootNode();
-        FormalArguments formals = rootNode.getFormalArguments();
-        ArgumentsSignature formalSignature = formals.getSignature();
-
-        Object[] reorderedArgs = ArgumentMatcher.matchArgumentsEvaluated(cached.permutation, preparedArguments, formals);
-
-        CompilerAsserts.partialEvaluationConstant(reorderedArgs.length);
-
-        if (cached.function.isBuiltin()) {
-            ArgumentMatcher.evaluatePromises(frame, promiseHelper, reorderedArgs);
-        }
-
-        Object[] argObject = prepareArguments(callerFrame, genericDefFrame, reorderedArgs, formalSignature, cached.function, cached.clazz, cached.functionName);
-
-        return call.call(frame, argObject);
-    }
-
-    @ExplodeLoop
-    private static Object[] prepareSuppliedArgument(long[] preparePermutation, Object[] arguments) {
-        Object[] result = new Object[preparePermutation.length];
-        for (int i = 0; i < result.length; i++) {
-            long source = preparePermutation[i];
-            if (source >= 0) {
-                result[i] = arguments[(int) source];
-            } else {
-                source = -source;
-                result[i] = ((RArgsValuesAndNames) arguments[(int) (source >> 32)]).getValues()[(int) source];
-            }
-        }
-        return result;
-    }
-
-    private void specialize(Frame callerFrame, MaterializedFrame genericDefFrame, ArgumentsSignature signature, Object[] arguments, boolean throwsRError) {
-        CompilerAsserts.neverPartOfCompilation();
-        // look for a match in the caller frame hierarchy
-        TargetLookupResult result = findTargetFunctionLookup(callerFrame, type, genericName, true);
-        ReadVariableNode[] unsuccessfulReadsCaller = result.unsuccessfulReads;
-        ReadVariableNode[] unsuccessfulReadsDef = null;
-        if (result.successfulRead == null) {
-            if (genericDefFrame != null) {
-                // look for a match in the generic def frame hierarchy
-                result = findTargetFunctionLookup(genericDefFrame, type, genericName, true);
-                unsuccessfulReadsDef = result.unsuccessfulReads;
-            }
-            if (result.successfulRead == null) {
-                if (throwsRError) {
-                    throw RError.error(getEncapsulatingSourceSection(), RError.Message.UNKNOWN_FUNCTION_USE_METHOD, genericName, type);
-                } else {
-                    throw new NoGenericMethodException();
-                }
-            }
-        }
-
-        int argCount = arguments.length;
-        int argListSize = argCount;
-
-        // extract vararg signatures from the arguments
-        ArgumentsSignature[] varArgSignatures = null;
-        for (int i = 0; i < arguments.length; i++) {
-            Object arg = arguments[i];
-            if (arg instanceof RArgsValuesAndNames) {
-                if (varArgSignatures == null) {
-                    varArgSignatures = new ArgumentsSignature[arguments.length];
-                }
-                varArgSignatures[i] = ((RArgsValuesAndNames) arg).getSignature();
-                argListSize += ((RArgsValuesAndNames) arg).length() - 1;
-            }
-        }
-
-        long[] preparePermutation;
-        ArgumentsSignature resultSignature;
-        if (varArgSignatures != null) {
-            resultSignature = ArgumentsSignature.flattenNames(signature, varArgSignatures, argListSize);
-            preparePermutation = ArgumentsSignature.flattenIndexes(varArgSignatures, argListSize);
-        } else {
-            preparePermutation = new long[argCount];
-            for (int i = 0; i < argCount; i++) {
-                preparePermutation[i] = i;
-            }
-            resultSignature = signature;
-        }
-
-        assert resultSignature != null;
-        MatchPermutation permutation = ArgumentMatcher.matchArguments(result.targetFunction, resultSignature, getEncapsulatingSourceSection(), false);
-
-        CheckReadsNode newCheckedReads = new CheckReadsNode(unsuccessfulReadsCaller, unsuccessfulReadsDef, result.successfulRead, result.targetFunction, result.clazz, result.targetFunctionName,
-                        signature, varArgSignatures, preparePermutation, permutation);
-        DirectCallNode newCall = Truffle.getRuntime().createDirectCallNode(result.targetFunction.getTarget());
-        if (call == null) {
-            cached = insert(newCheckedReads);
-            call = insert(newCall);
-        } else {
-            RError.performanceWarning("re-specializing UseMethodDispatchCachedNode");
-            cached.replace(newCheckedReads);
-            call.replace(newCall);
-        }
-    }
-
-    @Override
-    public Object executeGeneric(VirtualFrame frame, RStringVector aType) {
-        throw RInternalError.shouldNotReachHere();
-    }
-
-    @Override
-    public Object executeInternal(VirtualFrame frame, Object[] arguments) throws NoGenericMethodException {
-        ArgumentsSignature signature = suppliedSignature;
-        if (cached == null || !cached.executeReads(frame, null, signature, arguments)) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            specialize(frame, null, signature, arguments, false);
-        }
-        EvaluatedArguments reorderedArgs = reorderArguments(arguments, cached.function, suppliedSignature, getEncapsulatingSourceSection());
-        if (cached.function.isBuiltin()) {
-            ArgumentMatcher.evaluatePromises(frame, promiseHelper, reorderedArgs.getEvaluatedArgs());
-        }
-        Object[] argObject = prepareArguments(frame.materialize(), null, reorderedArgs.arguments, reorderedArgs.signature, cached.function, cached.clazz, cached.functionName);
-        return call.call(frame, argObject);
-    }
-
-    @Override
-    public Object executeInternalGeneric(VirtualFrame frame, RStringVector aType, Object[] args) throws NoGenericMethodException {
-        throw RInternalError.shouldNotReachHere();
-    }
-
-}
-
-final class UseMethodDispatchGenericNode extends S3DispatchGenericNode {
-
-    @Child protected IndirectCallNode indirectCallNode = Truffle.getRuntime().createIndirectCallNode();
-
-    public UseMethodDispatchGenericNode(String genericName, ArgumentsSignature suppliedSignature) {
-        super(genericName, suppliedSignature);
-    }
-
-    @Override
-    public Object execute(VirtualFrame frame) {
-        throw RInternalError.shouldNotReachHere();
-    }
-
-    @Override
-    public Object executeGeneric(VirtualFrame frame, RStringVector type) {
-        Object[] arguments = extractArguments(frame, false);
-        ArgumentsSignature signature = RArguments.getSignature(frame);
-        MaterializedFrame genericDefFrame = RArguments.getEnclosingFrame(frame);
-        MaterializedFrame callerFrame = getCallerFrame(frame);
-
-        TargetLookupResult lookupResult = findTargetFunction(callerFrame, genericDefFrame, type, true);
-        Object[] callArguments = executeHelper(frame, callerFrame, genericDefFrame, lookupResult, arguments, signature, getSourceSection());
-        return indirectCallNode.call(frame, lookupResult.targetFunction.getTarget(), callArguments);
-    }
-
-    @Override
-    public Object executeInternal(VirtualFrame frame, Object[] args) {
-        throw RInternalError.shouldNotReachHere();
-    }
-
-    @Override
-    public Object executeInternalGeneric(VirtualFrame frame, RStringVector type, Object[] arguments) {
-        MaterializedFrame genericDefFrame = RArguments.getEnclosingFrame(frame);
-        MaterializedFrame callerFrame = getCallerFrame(frame);
-
-        TargetLookupResult lookupResult = findTargetFunction(callerFrame, genericDefFrame, type, true);
-        Object[] callArguments = executeHelper(frame, callerFrame, genericDefFrame, lookupResult, arguments, suppliedSignature, getEncapsulatingSourceSection());
-        return indirectCallNode.call(frame, lookupResult.targetFunction.getTarget(), callArguments);
-    }
-
-    private Object[] executeHelper(VirtualFrame frame, MaterializedFrame callerFrame, MaterializedFrame genericDefFrame, TargetLookupResult lookupResult, Object[] args,
-                    ArgumentsSignature paramSignature, SourceSection errorSourceSection) {
-        RFunction function = lookupResult.targetFunction;
-        EvaluatedArguments reorderedArgs = reorderArguments(args, function, paramSignature, errorSourceSection);
-        if (function.isBuiltin()) {
-            ArgumentMatcher.evaluatePromises(frame, promiseHelper, reorderedArgs.getEvaluatedArgs());
-        }
-        return prepareArguments(callerFrame, genericDefFrame, lookupResult, function, reorderedArgs);
-    }
-
-    @Override
-    @TruffleBoundary
-    protected EvaluatedArguments reorderArguments(Object[] args, RFunction function, ArgumentsSignature paramSignature, SourceSection errorSourceSection) {
-        return super.reorderArguments(args, function, paramSignature, errorSourceSection);
-    }
-
-    @TruffleBoundary
-    private Object[] prepareArguments(MaterializedFrame callerFrame, MaterializedFrame genericDefFrame, TargetLookupResult lookupResult, RFunction function, EvaluatedArguments reorderedArgs) {
-        return super.prepareArguments(callerFrame, genericDefFrame, reorderedArgs.arguments, reorderedArgs.signature, function, lookupResult.clazz, lookupResult.targetFunctionName);
-    }
-
-    @TruffleBoundary
-    private TargetLookupResult findTargetFunction(MaterializedFrame callerFrame, MaterializedFrame genericDefFrame, RStringVector type, boolean throwsRError) {
-        TargetLookupResult lookupResult = findTargetFunctionLookup(callerFrame, type, genericName, false);
-        if (lookupResult == null) {
-            lookupResult = findTargetFunctionLookup(genericDefFrame, type, genericName, false);
-            if (lookupResult == null) {
-                if (throwsRError) {
-                    throw RError.error(getEncapsulatingSourceSection(), RError.Message.UNKNOWN_FUNCTION_USE_METHOD, genericName, RRuntime.toString(type));
-                } else {
-                    throw new NoGenericMethodException();
-                }
-            }
-        }
-        return lookupResult;
-    }
-}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodInternalNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodInternalNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..6161a5f1bb457c591dc5a459ad8f626bd46db993
--- /dev/null
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodInternalNode.java
@@ -0,0 +1,44 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 2014, Purdue University
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.nodes.function;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.r.nodes.*;
+import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode.Result;
+import com.oracle.truffle.r.runtime.*;
+import com.oracle.truffle.r.runtime.RArguments.S3Args;
+import com.oracle.truffle.r.runtime.data.*;
+
+public final class UseMethodInternalNode extends RNode implements VisibilityController {
+
+    @Child private S3FunctionLookupNode lookup = S3FunctionLookupNode.create(false, false);
+    @Child private CallMatcherNode callMatcher = CallMatcherNode.create(false, false);
+
+    private final String generic;
+    private final ArgumentsSignature signature;
+
+    public UseMethodInternalNode(String generic, ArgumentsSignature signature) {
+        this.generic = generic;
+        this.signature = signature;
+    }
+
+    public Object execute(VirtualFrame frame, RStringVector type, Object[] arguments) {
+        controlVisibility();
+        Result lookupResult = lookup.execute(frame, generic, type, null, frame.materialize(), null);
+        S3Args s3Args = new S3Args(generic, lookupResult.clazz, lookupResult.targetFunctionName, frame.materialize(), null, null);
+        return callMatcher.execute(frame, signature, arguments, lookupResult.function, s3Args);
+    }
+
+    @Override
+    public Object execute(VirtualFrame frame) {
+        throw RInternalError.shouldNotReachHere();
+    }
+}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/ArgumentsNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/ArgumentsNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..6b16c66570a6b4059a9921a1c6678dd87635c643
--- /dev/null
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/ArgumentsNode.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.nodes.function.signature;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.r.runtime.*;
+
+@TypeSystemReference(ArgumentsTypeSystem.class)
+public abstract class ArgumentsNode extends Node {
+
+    public abstract ArgumentsSignature execute(VirtualFrame frame);
+}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/ArgumentsTypeSystem.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/ArgumentsTypeSystem.java
new file mode 100644
index 0000000000000000000000000000000000000000..2dd8a33e22897645968d419ca1ddbe124bcafdff
--- /dev/null
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/ArgumentsTypeSystem.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.nodes.function.signature;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.r.runtime.*;
+
+@TypeSystem(ArgumentsSignature.class)
+public class ArgumentsTypeSystem {
+
+}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/CombineSignaturesNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/CombineSignaturesNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..88d0d88e309d000308a52726674d654ba993824a
--- /dev/null
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/signature/CombineSignaturesNode.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.nodes.function.signature;
+
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.r.runtime.*;
+
+@NodeChildren({@NodeChild("left"), @NodeChild("right")})
+public abstract class CombineSignaturesNode extends ArgumentsNode {
+
+    public abstract ArgumentsSignature execute(ArgumentsSignature left, ArgumentsSignature right);
+
+    @SuppressWarnings("unused")
+    @Specialization(guards = {"left == leftCached", "right == rightCached"})
+    protected ArgumentsSignature combineCached(ArgumentsSignature left, ArgumentsSignature right, @Cached("left") ArgumentsSignature leftCached, @Cached("right") ArgumentsSignature rightCached,
+                    @Cached("combine(left, right)") ArgumentsSignature resultCached) {
+        return resultCached;
+    }
+
+    @Specialization(guards = "left.isEmpty()")
+    protected ArgumentsSignature combineLeftEmpty(@SuppressWarnings("unused") ArgumentsSignature left, ArgumentsSignature right) {
+        return right;
+    }
+
+    @Specialization(guards = "right.isEmpty()")
+    protected ArgumentsSignature combineRightEmpty(ArgumentsSignature left, @SuppressWarnings("unused") ArgumentsSignature right) {
+        return left;
+    }
+
+    @Specialization
+    @TruffleBoundary
+    protected ArgumentsSignature combine(ArgumentsSignature left, ArgumentsSignature right) {
+        String[] names = new String[left.getLength() + right.getLength()];
+        for (int i = 0; i < left.getLength(); i++) {
+            names[i] = left.getName(i);
+        }
+        for (int i = 0; i < right.getLength(); i++) {
+            names[left.getLength() + i] = right.getName(i);
+        }
+        return ArgumentsSignature.get(names);
+    }
+}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/runtime/RASTDeparse.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/runtime/RASTDeparse.java
index 4caaaec40886a4f06178d5314301770997ce329a..9f20193bcbb18957ef53efd0cf8a9058f4675065 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/runtime/RASTDeparse.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/runtime/RASTDeparse.java
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1995-2012, The R Core Team
  * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -52,7 +52,7 @@ public class RASTDeparse {
     }
 
     private static Func isInfixOperatorNode(Node node) {
-        if (node instanceof RCallNode || node instanceof GroupDispatchCallNode) {
+        if (node instanceof RCallNode || node instanceof GroupDispatchNode) {
             Object fname = RASTUtils.findFunctionName(node, false);
             return isInfixOperator(fname);
         } else {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/runtime/RASTHelperImpl.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/runtime/RASTHelperImpl.java
index 05b653c51471165fc1d0251bdc0ea81031885514..e99cad9a266821c727b1d8ae8b7517393cd5c802 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/runtime/RASTHelperImpl.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/runtime/RASTHelperImpl.java
@@ -87,7 +87,7 @@ public class RASTHelperImpl implements RASTHelper {
     @TruffleBoundary
     private static int computeLength(Node node) {
         int result = 1;
-        if (node instanceof RCallNode || node instanceof DispatchedCallNode || node instanceof GroupDispatchCallNode) {
+        if (node instanceof RCallNode || node instanceof GroupDispatchNode) {
             // 1 + number of args
             CallArgumentsNode args = RASTUtils.findCallArgumentsNode(node);
             result += args.getArguments().length;
@@ -137,7 +137,7 @@ public class RASTHelperImpl implements RASTHelper {
         // index has already been range checked based on computeLength
         Node node = RASTUtils.unwrap(rl.getRep());
         int index = indexArg;
-        if (node instanceof RCallNode || node instanceof DispatchedCallNode || node instanceof GroupDispatchCallNode) {
+        if (node instanceof RCallNode || node instanceof GroupDispatchNode) {
             if (index == 0) {
                 return RASTUtils.findFunctionName(node, true);
             } else {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ArgumentsSignature.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ArgumentsSignature.java
index 58419b2db1919959a032e6c3659e7b189f4351d4..ce9281558773d2a74d2b22668f1aef1828128c08 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ArgumentsSignature.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ArgumentsSignature.java
@@ -102,6 +102,10 @@ public final class ArgumentsSignature implements Iterable<String> {
         }
     }
 
+    public boolean isEmpty() {
+        return names.length == 0;
+    }
+
     public int getLength() {
         return names.length;
     }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RArguments.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RArguments.java
index f1c07d7699c0e11d6ba1a052f834b456efc8161f..1afbd162e1652935500c56896d0c0c6acc290ebf 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RArguments.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RArguments.java
@@ -27,7 +27,6 @@ import java.util.*;
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.api.source.*;
 import com.oracle.truffle.api.utilities.*;
 import com.oracle.truffle.r.runtime.data.*;
@@ -85,32 +84,42 @@ public final class RArguments {
     @CompilationFinal public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
     @CompilationFinal public static final String[] EMPTY_STRING_ARRAY = new String[0];
 
+    public static final class S3Args {
+        public final String generic;
+        public final Object clazz;
+        public final Object method;
+        public final MaterializedFrame callEnv;
+        public final MaterializedFrame defEnv;
+        public final String group;
+
+        public S3Args(String generic, Object clazz, Object method, MaterializedFrame callEnv, MaterializedFrame defEnv, String group) {
+            assert generic != null && callEnv != null : generic + " " + callEnv;
+            assert generic.intern() == generic;
+            this.generic = generic;
+            this.clazz = clazz;
+            this.method = method;
+            this.callEnv = callEnv;
+            this.defEnv = defEnv;
+            this.group = group;
+        }
+    }
+
     public static final int INDEX_ENVIRONMENT = 0;
     public static final int INDEX_FUNCTION = 1;
     public static final int INDEX_CALL_SRC = 2;
     public static final int INDEX_CALLER_FRAME = 3;
     public static final int INDEX_ENCLOSING_FRAME = 4;
-    public static final int INDEX_N_ARGS = 5;
+    public static final int INDEX_S3_ARGS = 5;
     public static final int INDEX_DEPTH = 6;
     public static final int INDEX_IS_IRREGULAR = 7;
     public static final int INDEX_SIGNATURE = 8;
     public static final int INDEX_ARGUMENTS = 9;
-    /*
-     * These indices are relative to INDEX_ARGUMENTS + nArgs+ nNames
-     */
-    private static final int S3_INDEX_GENERIC = 0;
-    private static final int S3_INDEX_CLASS = 1;
-    private static final int S3_INDEX_METHOD = 2;
-    private static final int S3_INDEX_CALL_ENV = 3;
-    private static final int S3_INDEX_DEF_ENV = 4;
-    private static final int S3_INDEX_GROUP = 5;
-    private static final int S3_VAR_COUNT = 6;
 
     /**
      * At the least, the array contains the function, enclosing frame, and numbers of arguments and
      * names.
      */
-    public static final int MINIMAL_ARRAY_LENGTH = INDEX_SIGNATURE + 1;
+    public static final int MINIMAL_ARRAY_LENGTH = INDEX_ARGUMENTS;
 
     private static final ValueProfile materializedFrameProfile = ValueProfile.createClassProfile();
 
@@ -147,33 +156,30 @@ public final class RArguments {
     }
 
     private static int getNArgs(Frame frame) {
-        return (int) getArgumentsWithEvalCheck(frame)[INDEX_N_ARGS];
-    }
-
-    private static int getS3StartIndex(Object[] args) {
-        return INDEX_ARGUMENTS + (int) args[INDEX_N_ARGS];
+        return getSignature(frame).getLength();
     }
 
     private static ArgumentsSignature getSignature(RFunction function) {
         return ((HasSignature) function.getRootNode()).getSignature();
     }
 
-    private static void createHelper(Object[] a, REnvironment env, RFunction functionObj, SourceSection callSrc, MaterializedFrame callerFrame, int depth, MaterializedFrame enclosingFrame,
-                    Object[] evaluatedArgs, ArgumentsSignature signature) {
+    public static Object[] create(RFunction functionObj, SourceSection callSrc, MaterializedFrame callerFrame, int depth, Object[] evaluatedArgs, ArgumentsSignature signature) {
         assert evaluatedArgs != null && signature != null : evaluatedArgs + " " + signature;
         assert evaluatedArgs.length == signature.getLength() : Arrays.toString(evaluatedArgs) + " " + signature;
         assert signature == getSignature(functionObj) : signature + " vs. " + getSignature(functionObj);
-        a[INDEX_ENVIRONMENT] = env;
+
+        Object[] a = new Object[MINIMAL_ARRAY_LENGTH + evaluatedArgs.length];
+        a[INDEX_ENVIRONMENT] = null;
         a[INDEX_FUNCTION] = functionObj;
         a[INDEX_CALL_SRC] = callSrc;
         a[INDEX_CALLER_FRAME] = callerFrame;
-        a[INDEX_ENCLOSING_FRAME] = enclosingFrame;
+        a[INDEX_ENCLOSING_FRAME] = functionObj.getEnclosingFrameWithAssumption();
         a[INDEX_DEPTH] = depth;
         a[INDEX_IS_IRREGULAR] = false;
-        a[INDEX_N_ARGS] = evaluatedArgs.length;
         a[INDEX_SIGNATURE] = signature;
         copyArguments(evaluatedArgs, a, INDEX_ARGUMENTS);
         // assert envFunctionInvariant(a);
+        return a;
     }
 
     /**
@@ -183,7 +189,6 @@ public final class RArguments {
      * change at any point in time. Therefore, even though source is known at compile time, Graal
      * would have to be conservative and keep the array copy.
      */
-    @ExplodeLoop
     private static void copyArguments(Object[] source, Object[] destination, int position) {
         for (int i = 0; i < source.length; i++) {
             destination[position + i] = source[i];
@@ -202,142 +207,22 @@ public final class RArguments {
     public static Object[] createUnitialized() {
         Object[] a = new Object[MINIMAL_ARRAY_LENGTH];
         a[INDEX_DEPTH] = 0;
-        a[INDEX_N_ARGS] = 0;
         a[INDEX_SIGNATURE] = ArgumentsSignature.empty(0);
         a[INDEX_IS_IRREGULAR] = false;
         return a;
     }
 
-    public static Object[] create(RFunction functionObj, SourceSection callSrc, MaterializedFrame callerFrame, int depth, Object[] evaluatedArgs) {
-        if (functionObj != null) {
-            return create(null, functionObj, callSrc, callerFrame, depth, functionObj.getEnclosingFrameWithAssumption(), evaluatedArgs, ArgumentsSignature.empty(evaluatedArgs.length));
-        }
-        return create(null, functionObj, callSrc, callerFrame, depth, null, evaluatedArgs, ArgumentsSignature.empty(evaluatedArgs.length));
-    }
-
-    public static Object[] create(RFunction functionObj, SourceSection callSrc, MaterializedFrame callerFrame, int depth, Object[] evaluatedArgs, ArgumentsSignature signature) {
-        return create(null, functionObj, callSrc, callerFrame, depth, functionObj.getEnclosingFrameWithAssumption(), evaluatedArgs, signature);
-    }
-
-    public static Object[] create(REnvironment env, RFunction functionObj, SourceSection callSrc, MaterializedFrame callerFrame, int depth, MaterializedFrame enclosingFrame, Object[] evaluatedArgs,
-                    ArgumentsSignature signature) {
-        Object[] a = new Object[MINIMAL_ARRAY_LENGTH + evaluatedArgs.length];
-        createHelper(a, env, functionObj, callSrc, callerFrame, depth, enclosingFrame, evaluatedArgs, signature);
-        return a;
-    }
-
-    public static Object[] createS3Args(RFunction functionObj, SourceSection callSrc, MaterializedFrame callerFrame, int depth, Object[] evaluatedArgs, ArgumentsSignature signature) {
-        Object[] a = new Object[MINIMAL_ARRAY_LENGTH + evaluatedArgs.length + S3_VAR_COUNT];
-        createHelper(a, null, functionObj, callSrc, callerFrame, depth, functionObj.getEnclosingFrameWithAssumption(), evaluatedArgs, signature);
-        return a;
-    }
-
-    public static boolean hasS3Args(Frame frame) {
-        Object[] args = getArgumentsWithEvalCheck(frame);
-        if (args[INDEX_N_ARGS] == null) {
-            return false;
-        } else {
-            int s3StartIndex = getS3StartIndex(args);
-            return args.length > s3StartIndex;
-        }
-    }
-
-    public static String getS3Generic(Frame frame) {
-        Object[] args = getArgumentsWithEvalCheck(frame);
-        int s3StartIndex = getS3StartIndex(args);
-        assert (args.length > s3StartIndex);
-        return (String) args[s3StartIndex + S3_INDEX_GENERIC];
-    }
-
-    public static void setS3Generic(Object[] args, String generic) {
-        int s3StartIndex = getS3StartIndex(args);
-        assert (args.length > s3StartIndex);
-        args[s3StartIndex + S3_INDEX_GENERIC] = generic;
-    }
-
     public static MaterializedFrame getCallerFrame(Frame frame) {
         Object[] args = getArgumentsWithEvalCheck(frame);
         return (MaterializedFrame) args[INDEX_CALLER_FRAME];
     }
 
-    public static RStringVector getS3Class(Frame frame) {
-        Object[] args = getArgumentsWithEvalCheck(frame);
-        int s3StartIndex = getS3StartIndex(args);
-        if (args.length <= s3StartIndex) {
-            return null;
-        } else {
-            return (RStringVector) args[s3StartIndex + S3_INDEX_CLASS];
-        }
-    }
-
-    public static void setS3Class(Object[] args, RStringVector klass) {
-        int s3StartIndex = getS3StartIndex(args);
-        assert (args.length > s3StartIndex);
-        args[s3StartIndex + S3_INDEX_CLASS] = klass;
-    }
-
-    public static Object getS3Method(Frame frame) {
-        Object[] args = getArgumentsWithEvalCheck(frame);
-        int s3StartIndex = getS3StartIndex(args);
-        if (args.length <= s3StartIndex) {
-            return null;
-        } else {
-            return args[s3StartIndex + S3_INDEX_METHOD];
-        }
+    public static S3Args getS3Args(Frame frame) {
+        return (S3Args) getArgumentsWithEvalCheck(frame)[INDEX_S3_ARGS];
     }
 
-    public static void setS3Method(Object[] args, Object method) {
-        int s3StartIndex = getS3StartIndex(args);
-        assert (args.length > s3StartIndex);
-        args[s3StartIndex + S3_INDEX_METHOD] = method;
-    }
-
-    public static MaterializedFrame getS3DefEnv(Frame frame) {
-        Object[] args = getArgumentsWithEvalCheck(frame);
-        int s3StartIndex = getS3StartIndex(args);
-        if (args.length <= s3StartIndex) {
-            return null;
-        } else {
-            return (MaterializedFrame) args[s3StartIndex + S3_INDEX_DEF_ENV];
-        }
-    }
-
-    public static void setS3DefEnv(Object[] args, MaterializedFrame defEnv) {
-        int s3StartIndex = getS3StartIndex(args);
-        assert (args.length > s3StartIndex);
-        args[s3StartIndex + S3_INDEX_DEF_ENV] = defEnv;
-    }
-
-    public static MaterializedFrame getS3CallEnv(Frame frame) {
-        Object[] args = getArgumentsWithEvalCheck(frame);
-        int s3StartIndex = getS3StartIndex(args);
-        if (args.length <= s3StartIndex) {
-            return null;
-        } else {
-            return (MaterializedFrame) args[s3StartIndex + S3_INDEX_CALL_ENV];
-        }
-    }
-
-    public static void setS3CallEnv(Object[] args, MaterializedFrame callEnv) {
-        int s3StartIndex = getS3StartIndex(args);
-        assert (args.length > s3StartIndex);
-        args[s3StartIndex + S3_INDEX_CALL_ENV] = callEnv;
-    }
-
-    public static String getS3Group(Frame frame) {
-        Object[] args = getArgumentsWithEvalCheck(frame);
-        int s3StartIndex = getS3StartIndex(args);
-        if (args.length <= s3StartIndex) {
-            return null;
-        } else {
-            return (String) args[s3StartIndex + S3_INDEX_GROUP];
-        }
-    }
-
-    public static void setS3Group(Object[] args, String group) {
-        int s3StartIndex = getS3StartIndex(args);
-        assert (args.length > s3StartIndex);
-        args[s3StartIndex + S3_INDEX_GROUP] = group;
+    public static void setS3Args(Object[] args, S3Args s3Args) {
+        args[INDEX_S3_ARGS] = s3Args;
     }
 
     public static REnvironment getEnvironment(Frame frame) {
@@ -388,6 +273,11 @@ public final class RArguments {
         return getArgumentsWithEvalCheck(frame)[INDEX_ARGUMENTS + argIndex];
     }
 
+    public static Object[] getArguments(Frame frame) {
+        Object[] args = getArgumentsWithEvalCheck(frame);
+        return Arrays.copyOfRange(args, INDEX_ARGUMENTS, INDEX_ARGUMENTS + ((ArgumentsSignature) args[INDEX_SIGNATURE]).getLength());
+    }
+
     /**
      * <b>Only to be called from AccessArgumentNode!</b>
      *
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java
index 705c21911e5674824c43828e712846f90927fe13..75c26ad53304c20c3300754562d41823551144db 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java
@@ -1017,6 +1017,7 @@ public class RDeparse {
             case INTSXP:
                 int i = (int) element;
                 state.append(Integer.toString(i));
+                state.append('L');
                 break;
             case CPLXSXP:
                 RComplex c = (RComplex) element;
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
index 30c1a5fd6a750567f444d95b884b57eb869c2c4d..e948eab02e3d697fa29c4ab762912280f388d9ce 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
@@ -449,6 +449,7 @@ public final class RError extends RuntimeException {
         INVALID_TYPE_LENGTH("invalid type/length (%s/%d) in vector allocation"),
         SUBASSIGN_TYPE_FIX("incompatible types (from %s to %s) in subassignment type fix"),
         SUBSCRIPT_TYPES("incompatible types (from %s to %s) in [[ assignment"),
+        INCOMPATIBLE_METHODS("incompatible methods (\"%s\", \"%s\") for \"%s\""),
         RECURSIVE_INDEXING_FAILED("recursive indexing failed at level %d"),
         ARGUMENTS_PASSED("%d arguments passed to '%s' which requires %d"),
         ARGUMENTS_PASSED_0_1("0 arguments passed to '%s' which requires 1"),
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RGroupGenerics.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RGroupGenerics.java
index cb31c420d522c7d92e2b7c92317b29adfe42d6bd..95e86e618b321d2e1cff457e4a91fdc5338818be 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RGroupGenerics.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RGroupGenerics.java
@@ -10,121 +10,88 @@
  */
 package com.oracle.truffle.r.runtime;
 
-import java.util.*;
-
-public class RGroupGenerics {
-
-    public static final String GROUP_MATH = "Math";
-
-    public static final String GROUP_OPS = "Ops";
-
-    public static final String GROUP_SUMMARY = "Summary";
-
-    public static final String GROUP_COMPLEX = "Complex";
-
-    private static Map<String, String> methodToGroup;
-
-    static {
-        initializeMethodToGroup();
-    }
-
-    /*
-     * Returns the group to which a given S-3 group generic method belongs to.
-     */
-    public static String getGroup(final String methodName) {
-        return methodToGroup.get(methodName);
+public enum RGroupGenerics {
+    Math,
+    Ops,
+    Summary,
+    Complex;
+
+    public String getName() {
+        return name();
     }
 
-    /*
-     * Returns true if the method is group generic.
-     */
-    public static boolean isGroupGeneric(final String methodName) {
-        return methodToGroup.containsKey(methodName);
+    public static RGroupGenerics getGroup(String methodName) {
+        switch (methodName) {
+            case "abs":
+            case "sign":
+            case "sqrt":
+            case "floor":
+            case "ceiling":
+            case "trunc":
+            case "round":
+            case "signif":
+            case "exp":
+            case "log":
+            case "expm1":
+            case "log1p":
+            case "cos":
+            case "sin":
+            case "tan":
+            case "acos":
+            case "asin":
+            case "atan":
+            case "cosh":
+            case "sinh":
+            case "tanh":
+            case "acosh":
+            case "asinh":
+            case "atanh":
+            case "lgamma":
+            case "gamma":
+            case "digamma":
+            case "trigamma":
+            case "cumsum":
+            case "cumprod":
+            case "cummax":
+            case "cummin":
+                return Math;
+            case "+":
+            case "-":
+            case "*":
+            case "/":
+            case "^":
+            case "%%":
+            case "%/%":
+            case "&":
+            case "|":
+            case "!":
+            case "==":
+            case "!=":
+            case "<":
+            case "<=":
+            case ">=":
+            case ">":
+                return Ops;
+            case "max":
+            case "min":
+            case "prod":
+            case "sum":
+            case "all":
+            case "any":
+            case "range":
+                return Summary;
+            case "Arg":
+            case "Conj":
+            case "Im":
+            case "Mod":
+            case "Re":
+                return Complex;
+            default:
+                return null;
+        }
     }
 
-    /*
-     * S3 methods can be written for four groups:"Math", "Ops", "Summary" and "Complex". The
-     * following method maps each method to its associated group.
-     */
-    private static void initializeMethodToGroup() {
-        assert (methodToGroup == null);
-        methodToGroup = new HashMap<>();
-        addGroupMath();
-        addGroupOps();
-        addGroupSummary();
-        addGroupComplex();
+    public static boolean isGroupGeneric(String methodName) {
+        return getGroup(methodName) != null;
     }
-
-    private static void addGroupMath() {
-        methodToGroup.put("abs", GROUP_MATH);
-        methodToGroup.put("sign", GROUP_MATH);
-        methodToGroup.put("sqrt", GROUP_MATH);
-        methodToGroup.put("floor", GROUP_MATH);
-        methodToGroup.put("ceiling", GROUP_MATH);
-        methodToGroup.put("trunc", GROUP_MATH);
-        methodToGroup.put("round", GROUP_MATH);
-        methodToGroup.put("signif", GROUP_MATH);
-        methodToGroup.put("exp", GROUP_MATH);
-        methodToGroup.put("log", GROUP_MATH);
-        methodToGroup.put("expm1", GROUP_MATH);
-        methodToGroup.put("log1p", GROUP_MATH);
-        methodToGroup.put("cos", GROUP_MATH);
-        methodToGroup.put("sin", GROUP_MATH);
-        methodToGroup.put("tan", GROUP_MATH);
-        methodToGroup.put("acos", GROUP_MATH);
-        methodToGroup.put("asin", GROUP_MATH);
-        methodToGroup.put("atan", GROUP_MATH);
-        methodToGroup.put("cosh", GROUP_MATH);
-        methodToGroup.put("sinh", GROUP_MATH);
-        methodToGroup.put("tanh", GROUP_MATH);
-        methodToGroup.put("acosh", GROUP_MATH);
-        methodToGroup.put("asinh", GROUP_MATH);
-        methodToGroup.put("atanh", GROUP_MATH);
-        methodToGroup.put("lgamma", GROUP_MATH);
-        methodToGroup.put("gamma", GROUP_MATH);
-        methodToGroup.put("digamma", GROUP_MATH);
-        methodToGroup.put("trigamma", GROUP_MATH);
-        methodToGroup.put("cumsum", GROUP_MATH);
-        methodToGroup.put("cumprod", GROUP_MATH);
-        methodToGroup.put("cummax", GROUP_MATH);
-        methodToGroup.put("cummin", GROUP_MATH);
-    }
-
-    private static void addGroupOps() {
-        methodToGroup.put("+", GROUP_OPS);
-        methodToGroup.put("-", GROUP_OPS);
-        methodToGroup.put("*", GROUP_OPS);
-        methodToGroup.put("/", GROUP_OPS);
-        methodToGroup.put("^", GROUP_OPS);
-        methodToGroup.put("%%", GROUP_OPS);
-        methodToGroup.put("%/%", GROUP_OPS);
-        methodToGroup.put("&", GROUP_OPS);
-        methodToGroup.put("|", GROUP_OPS);
-        methodToGroup.put("!", GROUP_OPS);
-        methodToGroup.put("==", GROUP_OPS);
-        methodToGroup.put("!=", GROUP_OPS);
-        methodToGroup.put("<", GROUP_OPS);
-        methodToGroup.put("<=", GROUP_OPS);
-        methodToGroup.put(">=", GROUP_OPS);
-        methodToGroup.put(">", GROUP_OPS);
-    }
-
-    private static void addGroupSummary() {
-        methodToGroup.put("max", GROUP_SUMMARY);
-        methodToGroup.put("min", GROUP_SUMMARY);
-        methodToGroup.put("prod", GROUP_SUMMARY);
-        methodToGroup.put("sum", GROUP_SUMMARY);
-        methodToGroup.put("all", GROUP_SUMMARY);
-        methodToGroup.put("any", GROUP_SUMMARY);
-        methodToGroup.put("range", GROUP_SUMMARY);
-    }
-
-    private static void addGroupComplex() {
-        methodToGroup.put("Arg", GROUP_COMPLEX);
-        methodToGroup.put("Conj", GROUP_COMPLEX);
-        methodToGroup.put("Im", GROUP_COMPLEX);
-        methodToGroup.put("Mod", GROUP_COMPLEX);
-        methodToGroup.put("Re", GROUP_COMPLEX);
-    }
-
 }
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 857b16a9fe6e436eb3f5745ccb0c6a449d0ab5f2..69dec9f5e01d13e66adede3e539dd1acd8fbda51 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
@@ -571,7 +571,7 @@ public class RSerialize {
                 String tag = tagSym.getName().intern();
                 // this may convert a plain vector to a data.frame or factor
                 if (result instanceof RVector && tag.equals(RRuntime.CLASS_ATTR_KEY)) {
-                    result = ((RVector) result).setClassAttr((RStringVector) pl.car());
+                    result = ((RVector) result).setClassAttr((RStringVector) pl.car(), false);
                 } else {
                     rAttributable.setAttr(tag, pl.car());
                 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java
index 91bf1b61aa116be5cd60a4b7845cbb8f7e97ca0e..91710d01f4c52dd42e4ed1fe71a61d7e8a0d055e 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java
@@ -89,7 +89,13 @@ public interface RAttributable {
         }
     }
 
-    default RAttributable setClassAttr(RStringVector classAttr) {
+    default RAttributes resetAllAttributes(@SuppressWarnings("unused") boolean nullify) {
+        RAttributes attributes = getAttributes();
+        attributes.clear();
+        return attributes;
+    }
+
+    default RAttributable setClassAttr(RStringVector classAttr, @SuppressWarnings("unused") boolean convertToInt) {
         setAttr(RRuntime.CLASS_ATTR_KEY, classAttr);
         return this;
     }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFrame.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFrame.java
index 5b83186b0534f96d2a776ba19cb6911c6a2e4cc3..e64fdc74a8d53a90d7605024c93ac0ca9fa5ca4f 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFrame.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFrame.java
@@ -55,6 +55,21 @@ public final class RDataFrame implements RShareable, RAbstractContainer {
         }
     }
 
+    @Override
+    public RAbstractContainer resize(int size) {
+        if (vector instanceof RList || size == 0) {
+            return vector.resize(size);
+        } else {
+            RVector v = RDataFactory.createList();
+            v.resize(size);
+            v.setNames(vector.getNames());
+            if (vector.getLength() == 0) {
+                v.updateDataAtAsObject(0, vector, null);
+            }
+            return v;
+        }
+    }
+
     @Override
     public void markNonTemporary() {
         vector.markNonTemporary();
@@ -97,18 +112,22 @@ public final class RDataFrame implements RShareable, RAbstractContainer {
         return null;
     }
 
+    @Override
+    public void setDimensions(int[] newDimensions) {
+        // this may be strange, considering that getDimensions() must be obtained using builtins,
+        // but this sets the explicit attribute that is listed with other data frame attributes
+        vector.setDimensions(newDimensions);
+    }
+
     @Override
     public Class<?> getElementClass() {
         return RDataFrame.class;
     }
 
     @Override
-    public RVector materializeNonSharedVector() {
-        if (isShared()) {
-            vector = vector.copy();
-            vector.markNonTemporary();
-        }
-        return vector;
+    public RDataFrame materializeNonShared() {
+        RVector v = vector.materializeNonShared();
+        return vector != v ? RDataFactory.createDataFrame(v) : this;
     }
 
     @Override
@@ -121,17 +140,32 @@ public final class RDataFrame implements RShareable, RAbstractContainer {
         return vector.getNames(attrProfiles);
     }
 
+    @Override
+    public void setNames(RStringVector newNames) {
+        vector.setNames(newNames);
+    }
+
     @Override
     public RList getDimNames() {
         Utils.nyi("data frame's dimnames needs to be obtained using builtins");
         return null;
     }
 
+    @Override
+    public void setDimNames(RList newDimNames) {
+        vector.setDimNames(newDimNames);
+    }
+
     @Override
     public Object getRowNames(RAttributeProfiles attrProfiles) {
         return vector.getRowNames(attrProfiles);
     }
 
+    @Override
+    public void setRowNames(RAbstractVector rowNames) {
+        vector.setRowNames(rowNames);
+    }
+
     @Override
     public RStringVector getClassHierarchy() {
         return vector.getClassHierarchy();
@@ -142,10 +176,16 @@ public final class RDataFrame implements RShareable, RAbstractContainer {
         return true;
     }
 
+    @Override
     public RAttributes initAttributes() {
         return vector.initAttributes();
     }
 
+    @Override
+    public RAttributes resetAllAttributes(boolean nullify) {
+        return vector.resetAllAttributes(nullify);
+    }
+
     @Override
     public RShareable materializeToShareable() {
         return this;
@@ -160,8 +200,8 @@ public final class RDataFrame implements RShareable, RAbstractContainer {
     }
 
     @Override
-    public RAbstractContainer setClassAttr(RStringVector classAttr) {
-        return RVector.setVectorClassAttr(vector, classAttr, this, null);
+    public RAbstractContainer setClassAttr(RStringVector classAttr, boolean convertToInt) {
+        return vector.setClassAttr(classAttr, convertToInt);
     }
 
 }
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 b886be702fdf78e3e27b32cd6d3fe010b45432f9..6463066dcfd46bc910230d72cd05d13e9603d006 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
@@ -45,22 +45,35 @@ public class RExpression implements RShareable, RAbstractContainer {
         return data.getDataAt(index);
     }
 
+    @Override
     public RAttributes initAttributes() {
         return data.initAttributes();
     }
 
+    @Override
     public RAttributes getAttributes() {
         return data.getAttributes();
     }
 
+    @Override
+    public final RAttributes resetAllAttributes(boolean nullify) {
+        return data.resetAllAttributes(nullify);
+    }
+
     public boolean isComplete() {
         return data.isComplete();
     }
 
+    @Override
     public int getLength() {
         return data.getLength();
     }
 
+    @Override
+    public RAbstractContainer resize(int size) {
+        return data.resize(size);
+    }
+
     public boolean hasDimensions() {
         return data.hasDimensions();
     }
@@ -69,31 +82,54 @@ public class RExpression implements RShareable, RAbstractContainer {
         return data.getDimensions();
     }
 
+    @Override
+    public void setDimensions(int[] newDimensions) {
+        data.setDimensions(newDimensions);
+    }
+
     public Class<?> getElementClass() {
         return RExpression.class;
     }
 
-    public RVector materializeNonSharedVector() {
-        return data.materializeNonSharedVector();
+    public RExpression materializeNonShared() {
+        RVector d = data.materializeNonShared();
+        return data != d ? RDataFactory.createExpression((RList) d) : this;
     }
 
     public Object getDataAtAsObject(int index) {
         return data.getDataAtAsObject(index);
     }
 
+    @Override
     public RStringVector getNames(RAttributeProfiles attrProfiles) {
         return data.getNames(attrProfiles);
     }
 
+    @Override
+    public void setNames(RStringVector newNames) {
+        data.setNames(newNames);
+    }
+
+    @Override
     public RList getDimNames() {
         return data.getDimNames();
     }
 
+    @Override
+    public void setDimNames(RList newDimNames) {
+        data.setDimNames(newDimNames);
+    }
+
     @Override
     public Object getRowNames(RAttributeProfiles attrProfiles) {
         return data.getRowNames(attrProfiles);
     }
 
+    @Override
+    public void setRowNames(RAbstractVector rowNames) {
+        data.setRowNames(rowNames);
+    }
+
     public RStringVector getClassHierarchy() {
         return data.getClassHierarchy();
     }
@@ -131,4 +167,10 @@ public class RExpression implements RShareable, RAbstractContainer {
     public RShareable materializeToShareable() {
         return this;
     }
+
+    @Override
+    public RAbstractContainer setClassAttr(RStringVector classAttr, boolean convertToInt) {
+        return data.setClassAttr(classAttr, convertToInt);
+    }
+
 }
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 ce7570096d21f6299e8dabc3b79ad53ba1bb4fc6..f9d37a667058ddf57657a712357cf758412e1188 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
@@ -58,6 +58,11 @@ public final class RFactor implements RShareable, RAbstractContainer {
         return vector.getLength();
     }
 
+    @Override
+    public RAbstractContainer resize(int size) {
+        return vector.resize(size);
+    }
+
     @Override
     public void markNonTemporary() {
         vector.markNonTemporary();
@@ -98,18 +103,20 @@ public final class RFactor implements RShareable, RAbstractContainer {
         return vector.getDimensions();
     }
 
+    @Override
+    public void setDimensions(int[] newDimensions) {
+        vector.setDimensions(newDimensions);
+    }
+
     @Override
     public Class<?> getElementClass() {
         return RFactor.class;
     }
 
     @Override
-    public RVector materializeNonSharedVector() {
-        if (isShared()) {
-            vector = (RIntVector) vector.copy();
-            vector.markNonTemporary();
-        }
-        return vector;
+    public RFactor materializeNonShared() {
+        RVector v = vector.materializeNonShared();
+        return vector != v ? RDataFactory.createFactor((RIntVector) v, ordered) : this;
     }
 
     @Override
@@ -122,16 +129,31 @@ public final class RFactor implements RShareable, RAbstractContainer {
         return vector.getNames(attrProfiles);
     }
 
+    @Override
+    public void setNames(RStringVector newNames) {
+        vector.setNames(newNames);
+    }
+
     @Override
     public RList getDimNames() {
         return vector.getDimNames();
     }
 
+    @Override
+    public void setDimNames(RList newDimNames) {
+        vector.setDimNames(newDimNames);
+    }
+
     @Override
     public Object getRowNames(RAttributeProfiles attrProfiles) {
         return vector.getRowNames(attrProfiles);
     }
 
+    @Override
+    public void setRowNames(RAbstractVector rowNames) {
+        vector.setRowNames(rowNames);
+    }
+
     @Override
     public RStringVector getClassHierarchy() {
         return vector.getClassHierarchy();
@@ -142,30 +164,36 @@ public final class RFactor implements RShareable, RAbstractContainer {
         return true;
     }
 
+    @Override
     public RAttributes initAttributes() {
         return vector.initAttributes();
     }
 
+    @Override
+    public RAttributes resetAllAttributes(boolean nullify) {
+        return vector.resetAllAttributes(nullify);
+    }
+
     @Override
     public RShareable materializeToShareable() {
         return this;
     }
 
     public void setLevels(Object newLevels) {
-        vector.setLevels(newLevels);
+        vector.setAttr(RRuntime.LEVELS_ATTR_KEY, newLevels);
     }
 
     @Override
-    public RAbstractContainer setClassAttr(RStringVector classAttr) {
-        return RVector.setVectorClassAttr(vector, classAttr, null, this);
+    public RAbstractContainer setClassAttr(RStringVector classAttr, boolean convertToInt) {
+        return vector.setClassAttr(classAttr, convertToInt);
     }
 
-    public RVector getLevels() {
-        return vector.getLevels();
+    public RVector getLevels(RAttributeProfiles attrProfiles) {
+        return (RVector) vector.getAttr(attrProfiles, RRuntime.LEVELS_ATTR_KEY);
     }
 
-    public int getNLevels() {
-        RVector levels = vector.getLevels();
+    public int getNLevels(RAttributeProfiles attrProfiles) {
+        RVector levels = getLevels(attrProfiles);
         return levels == null ? 0 : levels.getLength();
     }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java
index c7f1926a1bb6935a69c572f931873ae8c4d9efe0..5b9c577715d6e4664c7a48e454e3ac3d9e19eece 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java
@@ -72,10 +72,10 @@ public class RLanguage extends RLanguageRep implements RAbstractContainer, RAttr
     }
 
     public boolean isComplete() {
-        assert false;
-        return false;
+        throw RInternalError.shouldNotReachHere();
     }
 
+    @Override
     public int getLength() {
         if (length < 0) {
             length = RContext.getRASTHelper().getLength(this);
@@ -83,6 +83,11 @@ public class RLanguage extends RLanguageRep implements RAbstractContainer, RAttr
         return length;
     }
 
+    @Override
+    public RAbstractContainer resize(int size) {
+        throw RInternalError.shouldNotReachHere();
+    }
+
     public boolean hasDimensions() {
         // TODO
         return false;
@@ -93,18 +98,21 @@ public class RLanguage extends RLanguageRep implements RAbstractContainer, RAttr
         return null;
     }
 
+    @Override
+    public void setDimensions(int[] newDimensions) {
+        throw RInternalError.unimplemented();
+    }
+
     public Class<?> getElementClass() {
         return RLanguage.class;
     }
 
-    public RVector materializeNonSharedVector() {
-        assert false;
-        return null;
+    public RVector materializeNonShared() {
+        throw RInternalError.shouldNotReachHere();
     }
 
     public RShareable materializeToShareable() {
-        assert false;
-        return null;
+        throw RInternalError.shouldNotReachHere();
     }
 
     public Object getDataAtAsObject(int index) {
@@ -116,16 +124,31 @@ public class RLanguage extends RLanguageRep implements RAbstractContainer, RAttr
         return (RStringVector) getAttr(attrProfiles, RRuntime.NAMES_ATTR_KEY);
     }
 
+    @Override
+    public void setNames(RStringVector newNames) {
+        setAttr(RRuntime.NAMES_ATTR_KEY, newNames);
+    }
+
     @Override
     public RList getDimNames() {
         return (RList) getAttr(localAttrProfiles, RRuntime.DIMNAMES_ATTR_KEY);
     }
 
+    @Override
+    public void setDimNames(RList newDimNames) {
+        setAttr(RRuntime.DIMNAMES_ATTR_KEY, newDimNames);
+    }
+
     @Override
     public Object getRowNames(RAttributeProfiles attrProfiles) {
         return getAttr(attrProfiles, RRuntime.ROWNAMES_ATTR_KEY);
     }
 
+    @Override
+    public void setRowNames(RAbstractVector rowNames) {
+        setAttr(RRuntime.ROWNAMES_ATTR_KEY, rowNames);
+    }
+
     public RStringVector getClassHierarchy() {
         return RDataFactory.createStringVector(RRuntime.CLASS_LANGUAGE);
     }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
index acd47e767aa6a51f070458e43c169b3ce32c70eb..253ed4cf7c7a92d8e8408b63aea2e6100273b37a 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java
@@ -109,6 +109,7 @@ public class RPairList extends RAttributeStorage implements RAttributable, RAbst
         return false;
     }
 
+    @Override
     public int getLength() {
         int result = 1;
         Object tcdr = cdr;
@@ -121,6 +122,11 @@ public class RPairList extends RAttributeStorage implements RAttributable, RAbst
         return result;
     }
 
+    @Override
+    public RAbstractContainer resize(int size) {
+        throw RInternalError.shouldNotReachHere();
+    }
+
     public boolean hasDimensions() {
         return true;
     }
@@ -129,11 +135,17 @@ public class RPairList extends RAttributeStorage implements RAttributable, RAbst
         return new int[]{1};
     }
 
+    @Override
+    public void setDimensions(int[] newDimensions) {
+        throw RInternalError.shouldNotReachHere();
+    }
+
     public Class<?> getElementClass() {
         return null;
     }
 
-    public RVector materializeNonSharedVector() {
+    @Override
+    public RVector materializeNonShared() {
         RInternalError.shouldNotReachHere();
         return null;
     }
@@ -153,6 +165,7 @@ public class RPairList extends RAttributeStorage implements RAttributable, RAbst
         return pl.car;
     }
 
+    @Override
     public RStringVector getNames(RAttributeProfiles attrProfiles) {
         int l = getLength();
         String[] data = new String[l];
@@ -173,12 +186,29 @@ public class RPairList extends RAttributeStorage implements RAttributable, RAbst
         return RDataFactory.createStringVector(data, complete);
     }
 
+    @Override
+    public void setNames(RStringVector newNames) {
+        throw RInternalError.shouldNotReachHere();
+    }
+
+    @Override
     public RList getDimNames() {
-        return null;
+        throw RInternalError.shouldNotReachHere();
+    }
+
+    @Override
+    public void setDimNames(RList newDimNames) {
+        throw RInternalError.shouldNotReachHere();
     }
 
+    @Override
     public Object getRowNames(RAttributeProfiles attrProfiles) {
-        return null;
+        throw RInternalError.shouldNotReachHere();
+    }
+
+    @Override
+    public void setRowNames(RAbstractVector rowNames) {
+        throw RInternalError.shouldNotReachHere();
     }
 
     public RStringVector getClassHierarchy() {
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 70573b296eb97c1c4a764440830e0efaa83ac8b6..13abd2082ca85b43a0ab7019e35610b1a0edee60 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
@@ -38,6 +38,11 @@ public abstract class RSequence extends RBounded implements RAbstractVector {
         return length;
     }
 
+    @Override
+    public RAbstractContainer resize(int size) {
+        return materialize().resize(size);
+    }
+
     public final boolean isComplete() {
         return true;
     }
@@ -50,6 +55,12 @@ public abstract class RSequence extends RBounded implements RAbstractVector {
         return null;
     }
 
+    @Override
+    public void setDimensions(int[] newDimensions) {
+        // should only be used on materialized sequence
+        throw RInternalError.shouldNotReachHere();
+    }
+
     public final RVector createVector() {
         return internalCreateVector();
     }
@@ -76,21 +87,37 @@ public abstract class RSequence extends RBounded implements RAbstractVector {
         return null;
     }
 
+    @Override
+    public void setNames(RStringVector newNames) {
+        // should only be used on materialized sequence
+        throw RInternalError.shouldNotReachHere();
+    }
+
     @Override
     public final RList getDimNames() {
         return null;
     }
 
+    @Override
+    public void setDimNames(RList newDimNames) {
+        // should only be used on materialized sequence
+        throw RInternalError.shouldNotReachHere();
+    }
+
     @Override
     public final Object getRowNames(RAttributeProfiles attrProfiles) {
         return RNull.instance;
     }
 
+    @Override
+    public void setRowNames(RAbstractVector rowNames) {
+        // should only be used on materialized sequence
+        throw RInternalError.shouldNotReachHere();
+    }
+
     @Override
     public final RAttributes initAttributes() {
-        // TODO implement
-        assert false;
-        return null;
+        throw RInternalError.shouldNotReachHere();
     }
 
     @Override
@@ -112,9 +139,13 @@ public abstract class RSequence extends RBounded implements RAbstractVector {
     }
 
     @Override
-    public final RVector materializeNonSharedVector() {
+    public final RVector materializeNonShared() {
         RVector resultVector = this.materialize();
         assert !resultVector.isShared();
+        // marking non-temp must be consistent with what RVector does, otherwise the following code
+        // will not work:
+        // x<-1:3 ; attr(x, "myatt")<-2:4 ; y <- x; attr(x, "myatt1")<-"hello" ; attributes(y)
+        resultVector.markNonTemporary();
         return resultVector;
     }
 
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 be3f6273df820aef06ad99b7ab6f6663c6194fcf..921aadb896479c867e71aeb87da9501bb0ef3fe7 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
@@ -256,21 +256,6 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV
         }
     }
 
-    @TruffleBoundary
-    public final void setLevels(Object newLevels) {
-        if (attributes != null && newLevels == null) {
-            // whether it's one dimensional array or not, assigning null always removes the "Levels"
-            // attribute
-            removeAttributeMapping(RRuntime.LEVELS_ATTR_KEY);
-        } else if (newLevels != null && newLevels != RNull.instance) {
-            putAttribute(RRuntime.LEVELS_ATTR_KEY, newLevels);
-        }
-    }
-
-    public final RVector getLevels() {
-        return (RVector) attributes.get(RRuntime.LEVELS_ATTR_KEY);
-    }
-
     /**
      * Sets names attribute without doing any error checking - to be used sparingly.
      *
@@ -488,8 +473,8 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV
     }
 
     @Override
-    public RAbstractContainer setClassAttr(RStringVector classAttr) {
-        return setClassAttrInternal(this, classAttr, null, null, true);
+    public RAbstractContainer setClassAttr(RStringVector classAttr, boolean convertToInt) {
+        return setClassAttrInternal(this, classAttr, null, null, convertToInt);
     }
 
     public static RAbstractContainer setVectorClassAttr(RVector vector, RStringVector classAttr, RAbstractContainer enclosingDataFrame, RAbstractContainer enclosingFactor) {
@@ -645,7 +630,7 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV
         RAttributes vecAttributes = vector.getAttributes();
         if (vecAttributes != null) {
             this.attributes = vecAttributes.copy();
-            return this.setClassAttr((RStringVector) vecAttributes.get(RRuntime.CLASS_ATTR_KEY));
+            return this.setClassAttr((RStringVector) vecAttributes.get(RRuntime.CLASS_ATTR_KEY), false);
         } else {
             return this;
         }
@@ -665,7 +650,7 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV
         RAttributes vecAttributes = vector.getAttributes();
         if (vecAttributes != null) {
             this.attributes = vecAttributes.copy();
-            return this.setClassAttr((RStringVector) vecAttributes.get(RRuntime.CLASS_ATTR_KEY));
+            return this.setClassAttr((RStringVector) vecAttributes.get(RRuntime.CLASS_ATTR_KEY), false);
         } else {
             return this;
         }
@@ -723,9 +708,14 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV
         return this;
     }
 
-    public final RShareable resize(int size, boolean resetAll) {
+    public final RVector resize(int size) {
+        return resize(size, true);
+    }
+
+    public final RVector resize(int size, boolean resetAll) {
         this.complete &= getLength() >= size;
         RVector res = this;
+        RStringVector oldNames = res.names;
         if (this.isShared()) {
             res = copyResized(size, true);
             res.markNonTemporary();
@@ -733,20 +723,16 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV
             resizeInternal(size);
         }
         if (resetAll) {
-            RStringVector oldNames = res.names;
             resetAllAttributes(oldNames == null);
-            if (oldNames != null) {
-                oldNames.resizeWithEmpty(size);
-                res.putAttribute(RRuntime.NAMES_ATTR_KEY, oldNames);
-                res.names = oldNames;
-            }
         } else {
             res.setDimensionsNoCheck(null);
             res.matrixDimension = 0;
             res.setDimNamesNoCheck(null);
-            if (res.names != null) {
-                res.names.resizeWithEmpty(size);
-            }
+        }
+        if (oldNames != null) {
+            oldNames.resizeWithEmpty(size);
+            res.putAttribute(RRuntime.NAMES_ATTR_KEY, oldNames);
+            res.names = oldNames;
         }
         return res;
     }
@@ -772,6 +758,7 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV
         }
     }
 
+    @Override
     public final RAttributes resetAllAttributes(boolean nullify) {
         this.dimensions = null;
         this.matrixDimension = 0;
@@ -779,15 +766,12 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV
         this.dimNames = null;
         if (nullify) {
             this.attributes = null;
-            return null;
         } else {
             if (this.attributes != null) {
                 this.attributes.clear();
-                return this.attributes;
-            } else {
-                return null;
             }
         }
+        return this.attributes;
     }
 
     @Override
@@ -820,14 +804,19 @@ public abstract class RVector extends RBounded implements RShareable, RAbstractV
     }
 
     @Override
-    public final RVector materializeNonSharedVector() {
+    public final RVector materializeNonShared() {
         if (this.isShared()) {
             RVector res = this.copy();
             res.markNonTemporary();
             return res;
-        } else {
-            return this;
         }
+        if (this.isTemporary()) {
+            // this is needed for primitive values coerced to vector - they need to be marked as
+            // non-temp, otherwise the following code will not work:
+            // x<-1; attributes(x) <- list(my = 1); y<-x; attributes(y)<-list(his = 2); x
+            this.markNonTemporary();
+        }
+        return this;
     }
 
     @Override
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 423ede5add9e0fd962a43c7a7ed77eda2f5c8850..4fdd525ae58eef2e6cc8f585902bbc1d94f7f5e9 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -104,8 +104,8 @@ public class RClosures {
 
     // Factor to vector
 
-    public static RAbstractVector createFactorToVector(RFactor factor, NACheck check) {
-        RAbstractVector levels = factor.getLevels();
+    public static RAbstractVector createFactorToVector(RFactor factor, NACheck check, RAttributeProfiles attrProfiles) {
+        RAbstractVector levels = factor.getLevels(attrProfiles);
         if (levels == null) {
             return new RFactorToStringVectorClosure(factor, null, check);
         } else {
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 e977dd5da3fd1bc6041a414883efc37070b6a698..1655725f219151c6a4e9a8cef7faa46248de76fd 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
@@ -39,18 +39,30 @@ public abstract class RToVectorClosure implements RAbstractVector {
         return vector.getLength();
     }
 
+    @Override
+    public RAbstractContainer resize(int size) {
+        return vector.resize(size);
+    }
+
     public boolean isComplete() {
         return vector.isComplete();
     }
 
+    @Override
     public boolean hasDimensions() {
         return vector.hasDimensions();
     }
 
+    @Override
     public int[] getDimensions() {
         return vector.getDimensions();
     }
 
+    @Override
+    public void setDimensions(int[] newDimensions) {
+        vector.setDimensions(newDimensions);
+    }
+
     @Override
     public final void verifyDimensions(int[] newDimensions, SourceSection sourceSection) {
         vector.verifyDimensions(newDimensions, sourceSection);
@@ -61,16 +73,31 @@ public abstract class RToVectorClosure implements RAbstractVector {
         return vector.getNames(attrProfiles);
     }
 
+    @Override
+    public void setNames(RStringVector newNames) {
+        vector.setNames(newNames);
+    }
+
     @Override
     public RList getDimNames() {
         return vector.getDimNames();
     }
 
+    @Override
+    public void setDimNames(RList newDimNames) {
+        vector.setDimNames(newDimNames);
+    }
+
     @Override
     public Object getRowNames(RAttributeProfiles attrProfiles) {
         return vector.getRowNames(attrProfiles);
     }
 
+    @Override
+    public void setRowNames(RAbstractVector rowNames) {
+        vector.setRowNames(rowNames);
+    }
+
     @Override
     public RAttributes initAttributes() {
         return vector.initAttributes();
@@ -122,8 +149,8 @@ public abstract class RToVectorClosure implements RAbstractVector {
     }
 
     @Override
-    public RVector materializeNonSharedVector() {
-        return vector.materializeNonSharedVector();
+    public RAbstractVector materializeNonShared() {
+        return (RAbstractVector) vector.materializeNonShared();
     }
 
     @Override
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractContainer.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractContainer.java
index 0e0a46a4214e10e0749a332186296c2484d2f97f..56d8905b17f57cd2b3a67f122ccae835ebb6c1f4 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractContainer.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractContainer.java
@@ -30,13 +30,17 @@ public interface RAbstractContainer extends RAttributable, RClassHierarchy, RTyp
 
     int getLength();
 
+    RAbstractContainer resize(int size);
+
     boolean hasDimensions();
 
     int[] getDimensions();
 
+    void setDimensions(int[] newDimensions);
+
     Class<?> getElementClass();
 
-    RVector materializeNonSharedVector();
+    RAbstractContainer materializeNonShared();
 
     RShareable materializeToShareable();
 
@@ -44,10 +48,16 @@ public interface RAbstractContainer extends RAttributable, RClassHierarchy, RTyp
 
     RStringVector getNames(RAttributeProfiles attrProfiles);
 
+    void setNames(RStringVector newNames);
+
     RList getDimNames();
 
+    void setDimNames(RList newDimNames);
+
     Object getRowNames(RAttributeProfiles attrProfiles);
 
+    void setRowNames(RAbstractVector rowNames);
+
     /**
      * Returns {@code true} if and only if the value has a {@code class} attribute added explicitly.
      * When {@code true}, it is possible to call {@link RClassHierarchy#getClassHierarchy()}.
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 d118ff88be5a01c33f52089ddec7e2307e9b0d33..6455555482eca6ab6899ce4d0abecce1ac02401b 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
@@ -28,10 +28,6 @@ import com.oracle.truffle.r.runtime.data.*;
 
 public interface RAbstractVector extends RAbstractContainer {
 
-    boolean hasDimensions();
-
-    int[] getDimensions();
-
     /**
      * Creates a copy of the vector. This copies all of the contained data as well. If the data in
      * the vector is to be updated upon copying, the corresponding {@code copyResetData()} method
@@ -58,8 +54,6 @@ public interface RAbstractVector extends RAbstractContainer {
 
     RVector materialize();
 
-    RList getDimNames();
-
     boolean isMatrix();
 
     boolean isArray();
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java
index a3466ab8608a51f50f4f34f14ec6bd183b6f6961..6c7c86f5ad523b0abfc165e490511601a45809f7 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java
@@ -119,7 +119,7 @@ public class DLL {
              */
             data[4] = createExternalPtr(id, INFO_REFERENCE_CLASS);
             RList dllInfo = RDataFactory.createList(data, DLLInfo.NAMES);
-            dllInfo.setClassAttr(RDataFactory.createStringVectorFromScalar(DLLINFO_CLASS));
+            dllInfo.setClassAttr(RDataFactory.createStringVectorFromScalar(DLLINFO_CLASS), false);
             return dllInfo;
         }
 
@@ -190,7 +190,7 @@ public class DLL {
 
     public static RExternalPtr createExternalPtr(long value, RStringVector rClass) {
         RExternalPtr result = RDataFactory.createExternalPtr(value, rClass.getDataAt(0));
-        result.setClassAttr(rClass);
+        result.setClassAttr(rClass, false);
         return result;
     }
 
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index 8ba4399a901738acfd5a89b71a61b9bda092956f..049563e1aec359aa79a227b61cfbff1bead2cf41 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -12920,6 +12920,11 @@ integer(0)
 [2,] 2+1i 2+2i 2+3i
 [3,] 3+1i 3+2i 3+3i
 
+##com.oracle.truffle.r.test.library.base.TestSimpleBuiltins.testOuter
+#{ foo <- function (x,y) { x + y * 1i } ; outer(3,3,"foo") }
+     [,1]
+[1,] 3+3i
+
 ##com.oracle.truffle.r.test.library.base.TestSimpleBuiltins.testOuter
 #{ foo <- function (x,y) { x + y * 1i } ; outer(3,3,foo) }
      [,1]
@@ -19844,6 +19849,10 @@ list()
 #{ l <- quote(for(i in s) { x <- i }) ; s <- 1:3 ; eval(l) ; s <- 2:1 ; eval(l) ; x }
 [1] 1
 
+##com.oracle.truffle.r.test.library.base.TestSimpleLoop.testLoops3
+#{ l <- quote(for(i in s) { x <- i }) ; s <- 1:3 ; eval(l) ; s <- NULL ; eval(l) ; x }
+[1] 3
+
 ##com.oracle.truffle.r.test.library.base.TestSimpleLoop.testLoops3
 #{ l <- quote({ for(i in 1:4) { if (i == 1) { next } ; if (i==3) { break } ; x <- i ; if (i==4) { x <- 10 } } ; x }) ; f <- function() { eval(l) } ; f()  }
 [1] 2
@@ -57972,6 +57981,22 @@ Error in x[[NA]] <- c(7, 42) : attempt to select more than one element
 #{ x<-list(1,2,3,4); dim(x)<-c(2,2); x[[NA]]<-c(7, 42, 1); x }
 Error in x[[NA]] <- c(7, 42, 1) : attempt to select more than one element
 
+##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testNullUpdate
+#{ x <- NULL; x[1] <- c(5); x; }
+[1] 5
+
+##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testNullUpdate
+#{ x <- NULL; x[[1]] <- c(5); x; }
+[1] 5
+
+##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testNullUpdate
+#{ x <- NULL; x[c(1,2)] <- c(1,5); x; }
+[1] 1 5
+
+##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testNullUpdate
+#{ x <- NULL; x[c(1,2)] <- c(5); x; }
+[1] 5 5
+
 ##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testObject
 #{ `[.foo` <- function(x, i, ...) structure(NextMethod("["), class = class(x)); x<-c(1,2); class(x)<-"foo"; x[1] }
 [1] 1
@@ -64062,6 +64087,14 @@ $two
 #{ x <- .Internal(unserializeFromConn(gzfile("com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/ser/data/factor1.rds"), NULL)); is.factor(x) }
 [1] TRUE
 
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinEncoding.testEncoding1
+#argv <- list('Byte Code Compiler'); .Internal(Encoding(argv[[1]]))
+[1] "unknown"
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinEncoding.testEncoding9
+#argv <- structure(list(x = 'abc'), .Names = 'x');do.call('Encoding', argv)
+[1] "unknown"
+
 ##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinIm.testIm1
 #argv <- list(c(0.117646597100126-0.573973479297987i, -0.740437474899139-0.482946826369552i, -0.333166449062945-0.753763230370951i, -0.256092192198247+0.707588353835588i, 0.522033838837248+0.102958580568997i, -0.651949901695459+0.059749937384601i, 0.235386572284857-0.70459646368007i, 0.077960849563711-0.71721816157401i, -0.563222209454641-0.518013590538404i, -0.068796124369349+0.97981641556181i, 0.244428915757284-0.330850507052219i, 0.451504053079215-0.090319593965852i, 0.04123292199294+0.214538826629216i, -0.422496832339625-0.738527704739573i, -0.451685375030484+0.126357395265016i, 0.375304016677864+0.436900190874168i, -0.674059300339186+0.084416799015191i, 0.739947510877334+0.418982404924464i, 0.509114684244823-0.086484623694157i, -0.535642839219739+0.289927561259502i, 0.629727249341749+0.707648659913726i, -0.262197489402468-0.502198718342861i, -0.333800277698424-0.317646103980588i, -0.422186107911717+0.317002735170286i, -0.616692335171505+0.068946145379939i, -0.136100485502624-0.487679764177213i, -0.68086000613138+0.047032323152903i, 0.296209908189768+0.585533462557103i, 0.43280012844045+0.136998748692477i, -0.680205941942733-0.256569497284745i, 0.787738847475178-0.375602871669773i, 0.76904224100091-0.561876363549783i, 0.332202578950118-0.343917234128459i, -0.983769553611346-0.088288289740869i, -0.046488672133508-0.622109071207677i, -0.280395335170247-0.088565112138884i, 0.379095891586975-0.727769566649926i, -0.372438756103829+0.630754115650567i, 0.976973386685621-0.113639895506141i, -0.150428076228347+0.615598727377677i, 0.762964492726935+0.377685645913312i, -0.7825325866026+0.365371705974346i, -0.792443423040311-0.029652870362208i, 0.265771060547393-0.106618612674382i, -0.076741350022367-0.422144111460857i, 0.120061986786934-0.623033085890884i, 0.636569674033849-0.133150964328944i, -0.145741981978782+0.529165019069452i, 0.516862044313609-0.388779864071743i, 0.368964527385086+0.089207223073295i, -0.215380507641693+0.845013004067436i, 0.065293033525315+0.962527968484271i, -0.034067253738464+0.684309429416465i, 0.328611964770906+0.215416587846774i, -0.583053183540166-0.668235480667835i, -0.782507286391418+0.318827979750013i, 0.037788399171079+0.174802700161256i, 0.310480749443137+0.074551177173735i, 0.436523478910183+0.428166764970505i, -0.458365332711106+0.02467498282614i, -0.271871452223431+0.426340387811162i, 0.590808184713385-0.344468770084509i, -0.349650387953555+0.386026568349676i, -0.865512862653374-0.265651625278222i, -0.236279568941097+0.118144511046681i, -0.197175894348552+0.134038645368463i, 0.866602113481861-0.172567291859327i, 0.031389337713892-0.607820631329035i, 0.754053785184521-0.219050378933476i, -0.499292017172261+0.168065383884658i, 0.151969488085021-0.827990593142535i, -0.266853748421854-0.866413193943766i, 0.071623062591495-0.867246686843546i, -0.788765741891382+0.508717463380604i, -0.228835546857432-0.349587041980114i, 0.500139791176978-0.016703152458872i, 0.15619107374708-0.485402548890295i, -0.369039310626083+0.398423724273751i, -0.611165916680421+0.020983586354237i, -0.399467692630093-0.421179989556223i, 0.411274074028001+0.133781691724871i, 0.573364366690245+0.328833257005489i, -0.265145056696353-0.938538703606894i, 0.387209171815106+0.750271083217101i, -0.41433994791886-0.437159533180399i, -0.476246894615578+0.331179172958982i, -0.168543113030619+0.43048451175239i, -0.594617267459511+0.211980433372292i, 0.388005062566602-0.290649953587954i, -0.013004326537709-0.490434895455784i, 0.069845221019376-0.762134635168809i, 0.243687429599092+0.756774763795962i, 0.27384734040072+0.383667165938905i, -0.51606383094478-0.601506708006782i, -0.894951082455532+0.317442909372288i, 0.5073401683933-0.213001485168032i, -0.441163216905286-0.105671334003774i, -0.343169835663372+0.597359384628839i, -0.283179001991236-0.385834501657171i, -0.517794900198098-0.36732932802092i));Im(argv[[1]]);
   [1] -0.57397348 -0.48294683 -0.75376323  0.70758835  0.10295858  0.05974994
@@ -64344,6 +64377,10 @@ numeric(0)
 #argv <- structure(list(target = as.raw(c(1, 2, 3)), current = as.raw(c(1,     2, 3))), .Names = c('target', 'current'));do.call('all.equal.raw', argv)
 [1] TRUE
 
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinand_octmode.testand_octmode1
+#argv <- structure(list(a = structure(integer(0), class = 'octmode'),     b = '400'), .Names = c('a', 'b'));do.call('&.octmode', argv)
+character(0)
+
 ##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinany.testany1
 #argv <- list(structure(c(TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE), .Tsp = c(1, 101, 1), class = 'ts'));any(argv[[1]]);
 [1] TRUE
@@ -65421,10 +65458,26 @@ c   -1   -1
 a b
 1 2
 
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinascall.testascall2
+#argv <- list(list(quote(quote), FALSE));as.call(argv[[1]]);
+quote(FALSE)
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinascall.testascall3
+#argv <- list(list(quote(quote), list(NULL, c('time', 'status'))));as.call(argv[[1]]);
+quote(list(NULL, c("time", "status")))
+
 ##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinascall.testascall4
 #argv <- list(structure(expression(data.frame, check.names = TRUE, stringsAsFactors = TRUE), .Names = c('', 'check.names', 'stringsAsFactors')));as.call(argv[[1]]);
 data.frame(check.names = TRUE, stringsAsFactors = TRUE)
 
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinascall.testascall5
+#argv <- list(list(quote(quote), 80L));as.call(argv[[1]]);
+quote(80L)
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinascall.testascall6
+#argv <- list(list(quote(quote), NA));as.call(argv[[1]]);
+quote(NA)
+
 ##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinascharacter.testascharacter1
 #argv <- list('bessel_y(2,nu=181.2): precision lost in result');as.character(argv[[1]]);
 [1] "bessel_y(2,nu=181.2): precision lost in result"
@@ -65761,6 +65814,10 @@ numeric(0)
 Warning message:
 NAs introduced by coercion
 
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinasdoubledifftime.testasdoubledifftime1
+#argv <- structure(list(x = structure(16351.8259046444, units = 'days',     class = 'difftime', origin = structure(0, class = c('POSIXct',         'POSIXt'), tzone = 'GMT'))), .Names = 'x');do.call('as.double.difftime', argv)
+[1] 16351.83
+
 ##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinasexpression.testasexpression1
 #argv <- structure(list(x = 1), .Names = 'x');do.call('as.expression', argv)
 expression(1)
@@ -66932,6 +66989,42 @@ character(0)
 #argv <- structure(list(path = 'myTst'), .Names = 'path');do.call('basename', argv)
 [1] "myTst"
 
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinbitwiseAnd.testbitwiseAnd1
+#argv <- list(structure(c(420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 493L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 493L, 493L, 493L, 493L, 493L, 493L, 493L, 493L, 493L, 493L, 493L), class = 'octmode'), structure(256L, class = 'octmode')); .Internal(bitwiseAnd(argv[[1]], argv[[2]]))
+  [1] 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256
+ [19] 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256
+ [37] 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256
+ [55] 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256
+ [73] 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256
+ [91] 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256
+[109] 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256
+[127] 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinbitwiseAnd.testbitwiseAnd2
+#argv <- list(structure(integer(0), class = 'hexmode'), structure(integer(0), class = 'hexmode')); .Internal(bitwiseAnd(argv[[1]], argv[[2]]))
+integer(0)
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinbitwiseNot.testbitwiseNot1
+#argv <- list(structure(numeric(0), .Dim = c(0L, 0L))); .Internal(bitwiseNot(argv[[1]]))
+integer(0)
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinbitwiseOr.testbitwiseOr1
+#argv <- list(15L, 7L); .Internal(bitwiseOr(argv[[1]], argv[[2]]))
+[1] 15
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinbitwiseShiftR.testbitwiseShiftR1
+#argv <- list(-1, 1:31); .Internal(bitwiseShiftR(argv[[1]], argv[[2]]))
+ [1] 2147483647 1073741823  536870911  268435455  134217727   67108863
+ [7]   33554431   16777215    8388607    4194303    2097151    1048575
+[13]     524287     262143     131071      65535      32767      16383
+[19]       8191       4095       2047       1023        511        255
+[25]        127         63         31         15          7          3
+[31]          1
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinbitwiseXor.testbitwiseXor1
+#argv <- list(-1L, 1L); .Internal(bitwiseXor(argv[[1]], argv[[2]]))
+[1] -2
+
 ##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinbody.testbody5
 #argv <- list(structure(list(c0 = structure(integer(0), .Label = character(0), class = 'factor')), .Names = 'c0', row.names = character(0), class = 'data.frame')); .Internal(body(argv[[1]]))
 NULL
@@ -68883,6 +68976,20 @@ Levels: a b c d e f
 [1] Two   One   Three
 Levels: One Two Three
 
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinextract_parentasis_extract_parentasis_factor.testextract_parentasis_extract_parentasis_factor1
+#argv <- structure(list(x = structure(2:4, .Label = c('A', 'B',     'C', 'D', 'E'), class = 'factor'), 2), .Names = c('x', ''));do.call('[[.factor', argv)
+[1] C
+Levels: A B C D E
+
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinextract_parentasis_factor.testextract_parentasis_factor1
+#argv <- structure(list(x = structure(c(111L, 88L, 93L, 74L, 138L,     103L, 46L, 114L, 112L, 24L, 99L, 97L, 57L, 40L, 86L, 37L,     124L, 9L, 20L, 54L, 145L, 3L, 7L, 134L, 98L, 143L, 131L,     47L, 128L, 116L, 137L, 5L, 132L, 21L, 81L, 58L, 108L, 17L,     107L, 126L, 2L, 18L, 75L, 4L, 63L, 121L, 84L, 101L, 123L,     102L, 36L, 48L, 12L, 105L, 100L, 90L, 34L, 55L, 68L, 10L,     52L, 91L, 146L, 127L, 1L, 29L, 106L, 26L, 115L, 118L, 25L,     82L, 16L, 45L, 95L, 69L, 72L, 15L, 120L, 104L, 125L, 6L,     140L, 65L, 62L, 39L, 35L, 38L, 83L, 117L, 42L, 13L, 87L,     22L, 53L, 41L, 113L, 73L, 133L, 23L, 80L, 8L, 19L, 78L, 60L,     31L, 33L, 147L, 139L, 56L, 130L, 64L, 71L, 43L, 136L, 89L,     94L, 96L, 70L, 59L, 129L, 27L, 92L, 51L, 77L, 50L, 66L, 119L,     135L, 110L, 144L, 109L, 67L, 44L, 32L, 141L, 76L, 79L, 49L,     142L, 30L, 14L, 85L, 28L, 11L, 61L, 122L), .Label = c('1415787_at',     '1415904_at', '1415993_at', '1416164_at', '1416181_at', '1416221_at',     '1416481_s_at', '1416812_at', '1416855_at', '1416949_s_at',     '1417129_a_at', '1417425_at', '1417447_at', '1417466_at',     '1417572_at', '1417624_at', '1417667_a_at', '1417964_at',     '1418084_at', '1418382_at', '1418424_at', '1418471_at', '1418479_at',     '1418486_at', '1418516_at', '1418560_at', '1418649_at', '1418835_at',     '1419361_at', '1419430_at', '1419686_at', '1419833_s_at',     '1420011_s_at', '1420643_at', '1420886_a_at', '1421045_at',     '1421180_at', '1421773_at', '1422018_at', '1422557_s_at',     '1422671_s_at', '1422809_at', '1422850_at', '1422979_at',     '1423095_s_at', '1423110_at', '1423123_at', '1423124_x_at',     '1423176_at', '1423319_at', '1423852_at', '1423924_s_at',     '1424107_at', '1424186_at', '1424212_at', '1424243_at', '1424474_a_at',     '1424749_at', '1425494_s_at', '1425534_at', '1425779_a_at',     '1426083_a_at', '1426295_at', '1426371_at', '1426485_at',     '1426510_at', '1426628_at', '1426845_at', '1427120_at', '1427208_at',     '1427256_at', '1427314_at', '1427672_a_at', '1428922_at',     '1428942_at', '1429177_x_at', '1429514_at', '1429859_a_at',     '1431830_at', '1433512_at', '1434326_x_at', '1434485_a_at',     '1434831_a_at', '1434920_a_at', '1435129_at', '1435327_at',     '1435357_at', '1436392_s_at', '1436528_at', '1436886_x_at',     '1437163_x_at', '1437223_s_at', '1437434_a_at', '1437455_a_at',     '1438312_s_at', '1438651_a_at', '1439148_a_at', '1439373_x_at',     '1439381_x_at', '1439962_at', '1448131_at', '1448143_at',     '1448147_at', '1448259_at', '1448269_a_at', '1448466_at',     '1448601_s_at', '1448630_a_at', '1448823_at', '1448943_at',     '1448995_at', '1449059_a_at', '1449376_at', '1449623_at',     '1449630_s_at', '1449697_s_at', '1449699_s_at', '1449755_at',     '1449773_s_at', '1449885_at', '1450070_s_at', '1450723_at',     '1450846_at', '1450857_a_at', '1450941_at', '1451103_at',     '1451266_at', '1451317_at', '1451332_at', '1451415_at', '1451418_a_at',     '1451532_s_at', '1451536_at', '1452003_at', '1452110_at',     '1452183_a_at', '1452665_at', '1452671_s_at', '1452869_at',     '1453030_at', '1455056_at', '1455517_at', '1456174_x_at',     '1456393_at', '1456434_x_at', '1460260_s_at', '1460359_at'),     class = 'factor'), 1:25), .Names = c('x', ''));do.call('[.factor', argv)
+ [1] 1448995_at   1436392_s_at 1437434_a_at 1428922_at   1452671_s_at
+ [6] 1448147_at   1423110_at   1449623_at   1449059_a_at 1418486_at
+[11] 1439381_x_at 1439148_a_at 1424474_a_at 1422557_s_at 1435327_at
+[16] 1421180_at   1450857_a_at 1416855_at   1418382_at   1424186_at
+[21] 1456434_x_at 1415993_at   1416481_s_at 1452003_at   1439373_x_at
+147 Levels: 1415787_at 1415904_at 1415993_at 1416164_at ... 1460359_at
+
 ##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinfactor.testfactor1
 #argv <- structure(list(x = c(1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L,     0L, 0L, 0L, 0L, 1L, 1L, 0L, 1L, 0L, 1L, 1L, 1L, 0L, 1L, 0L,     0L, 1L, 1L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L,     0L, 0L, 1L, 0L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 1L, 1L, 0L,     1L, 1L, 1L, 0L, 1L, 0L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 0L,     0L, 1L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 0L,     1L, 0L, 0L, 0L, 0L, 1L, 0L, 1L, 1L, 0L, 0L, 0L, 1L, 0L, 0L,     1L, 0L, 1L, 0L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,     1L, 1L, 1L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 0L,     0L, 0L, 0L, 0L, 1L, 1L, 0L, 1L, 1L, 1L, 0L, 0L, 1L, 1L, 1L,     0L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 0L, 0L, 0L, 1L, 0L, 0L,     0L, 1L, 1L, 1L, 0L, 1L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L,     1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 1L, 1L, 1L, 0L, 1L, 0L, 0L,     1L, 1L, 1L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 1L, 0L, 0L, 1L, 0L,     0L, 0L, 1L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 1L, 0L,     1L, 1L, 0L, 1L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 0L, 1L, 1L,     1L, 0L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 0L,     0L, 1L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L,     1L, 1L, 1L, 1L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 1L, 1L, 1L, 1L,     1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 0L, 0L, 0L,     0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 1L, 1L, 1L, 1L,     1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L,     1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,     1L, 0L, 1L, 1L, 1L, 0L, 1L, 1L, 0L, 1L, 1L, 0L, 1L, 1L, 1L,     0L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,     0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L,     1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 0L, 0L, 1L, 0L, 1L, 1L, 1L,     1L, 1L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L,     0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L,     0L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,     0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 1L, 1L,     1L, 1L, 0L, 1L, 1L, 0L, 1L, 0L, 1L, 0L, 0L, 1L, 1L, 1L, 0L,     1L, 0L, 0L, 1L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 1L,     0L, 0L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 1L, 1L, 0L, 1L, 0L,     0L, 1L, 1L, 0L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 1L,     1L, 0L, 1L, 0L, 0L, 0L, 1L, 1L, 0L, 1L, 0L, 0L, 0L, 0L, 0L,     1L, 0L, 1L, 0L, 1L, 1L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 0L, 1L,     0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 0L,     0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 1L, 0L,     0L, 0L, 1L, 1L, 0L, 1L, 0L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 0L,     0L, 1L, 0L, 1L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 1L, 0L,     0L, 1L, 0L, 0L, 1L, 1L, 0L, 1L, 1L, 0L, 0L, 0L, 1L, 0L, 1L,     0L, 1L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L,     0L, 1L, 0L, 0L, 1L, 1L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L,     1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 1L, 0L, 0L, 1L, 0L,     0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L,     1L, 0L, 1L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L,     0L, 1L, 0L, 1L, 0L, 0L, 1L, 1L, 0L, 0L, 1L, 1L, 1L, 0L, 0L,     0L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 1L,     0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 1L, 1L, 0L, 0L, 1L, 0L, 1L,     1L, 0L, 1L, 1L, 0L, 1L, 1L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 0L,     0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 0L,     0L, 0L, 1L, 0L, 1L, 0L, 1L, 1L, 0L, 0L, 0L, 1L, 1L, 0L, 0L,     1L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 0L, 1L, 1L, 0L,     1L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 1L, 0L, 0L, 1L, 1L,     0L, 1L, 0L, 1L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L,     0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 0L, 1L, 0L, 0L,     0L, 1L, 1L, 1L, 0L, 1L, 0L, 0L, 0L, 1L, 0L, 1L, 0L, 1L, 0L,     1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 0L, 1L, 1L,     0L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 1L,     0L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 1L, 1L, 1L, 0L, 0L,     1L, 0L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 1L, 0L, 0L, 1L, 0L,     0L, 1L, 0L, 0L, 1L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L,     0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 1L, 1L, 0L,     0L, 1L, 0L, 0L, 1L, 1L, 0L, 1L, 1L, 0L, 0L, 0L, 1L, 0L, 0L,     0L, 0L, 1L, 1L, 0L, 1L, 0L, 0L, 1L, 1L, 0L, 1L, 1L, 0L, 1L,     1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 0L, 1L, 0L, 1L, 1L, 0L, 1L,     0L, 1L)), .Names = 'x');do.call('factor', argv)
    [1] 1 0 1 1 1 1 1 1 0 0 0 0 1 1 0 1 0 1 1 1 0 1 0 0 1 1 0 0 1 1 0 0 0 0 0 0 1
@@ -69146,6 +69253,10 @@ character(0)
 #argv <- structure(list(x = structure(integer(0), class = 'AsIs')),     .Names = 'x');do.call('format.AsIs', argv)
 character(0)
 
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinformatdifftime.testformatdifftime1
+#argv <- structure(list(x = structure(c(0, 30, 60), units = 'mins',     class = 'difftime')), .Names = 'x');do.call('format.difftime', argv)
+[1] " 0 mins" "30 mins" "60 mins"
+
 ##com.oracle.truffle.r.test.testrgen.TestrGenBuilting.testg1
 #argv <- list(1);g(argv[[1]]);
 Error: could not find function "g"
@@ -72913,6 +73024,10 @@ Time difference of 31 days
 #argv <- list(structure(c(2134, 1863, 1877, 1877, 1492, 1249, 1280, 1131, 1209, 1492, 1621, 1846, 2103, 2137, 2153, 1833, 1403, 1288, 1186, 1133, 1053, 1347, 1545, 2066, 2020, 2750, 2283, 1479, 1189, 1160, 1113, 970, 999, 1208, 1467, 2059, 2240, 1634, 1722, 1801, 1246, 1162, 1087, 1013, 959, 1179, 1229, 1655, 2019, 2284, 1942, 1423, 1340, 1187, 1098, 1004, 970, 1140, 1110, 1812, 2263, 1820, 1846, 1531, 1215, 1075, 1056, 975), .Tsp = c(1974, 1979.58333333333, 12), class = 'ts')); .Internal(mean(argv[[1]]))
 [1] 1515.471
 
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinmeandifftime.testmeandifftime1
+#argv <- structure(list(x = structure(c(31, NA, NA, 31), units = 'days',     class = 'difftime'), na.rm = TRUE), .Names = c('x', 'na.rm'));do.call('mean.difftime', argv)
+Time difference of 31 days
+
 ##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinmin.testmin1
 #argv <- list(c(10L, 1L));min(argv[[1]]);
 [1] 1
@@ -73688,6 +73803,10 @@ logical(0)
    100 -1e-13    Inf   -Inf    NaN   3.14     NA
   TRUE   TRUE   TRUE   TRUE   TRUE   TRUE   TRUE
 
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinoperators.testoperators169
+#argv <- list(structure(1:3, .Label = c('1', '2', NA), class = 'factor'), structure(1:3, .Label = c('1', '2', NA), class = 'factor'));`!=`(argv[[1]],argv[[2]]);
+[1] FALSE FALSE FALSE
+
 ##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinoperators.testoperators17
 #argv <- list(4.40646552950873, structure(c(2.62980519617636, 3.871217247387, 4.50132920500077, 4.98499803067693, 5.10709299286893, 5.03983500591087, 4.63030887318817, 5.53509956067429, 5.33332559980012, 5.70084841033141, 4.71574513022187, 4.22037009914704, 3.98171648049174, 4.03049403236714, 4.12846177743637, 4.47709151156657, 5.3332151234887, 5.63317778205492, 5.92697054095118, 6.19581080008781, 6.04311655609605, 6.94831988490059, 6.18986185304067, 5.62147157665625, 4.74634441202163, 4.26914765102244, 5.32109627677161, 6.60533693281051, 5.67035960484307, 5.44401652160046, 3.65126501643718, 3.93293892861635, 3.04580339357603, 3.07640267537579, 2.77049106976243, 2.76443164640389, 3.33918351115387, 4.07927158424254, 4.04908494376122, 4.33034621462195, 3.99989475056739, 4.25702880430535), .Names = c('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42')));`+`(argv[[1]],argv[[2]]);
         1         2         3         4         5         6         7         8
@@ -74352,6 +74471,10 @@ FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  <NA> FALSE  TRUE  <NA> FALSE  TRUE  <NA> FALSE  TRUE
    NA    NA  TRUE    NA FALSE  TRUE  TRUE  TRUE  TRUE
 
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinoperators.testoperators314
+#argv <- list(structure(120L, class = 'octmode'), '644');`|`(argv[[1]],argv[[2]]);
+[1] "774"
+
 ##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinoperators.testoperators316
 #argv <- list(character(0));`!`(argv[[1]]);
 logical(0)
@@ -74519,6 +74642,10 @@ is.na.numeric_version               is.name                is.nan
  <NA> FALSE  TRUE  <NA> FALSE  TRUE  <NA> FALSE  TRUE
    NA FALSE    NA FALSE FALSE FALSE    NA FALSE  TRUE
 
+##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinoperators.testoperators343
+#argv <- list(structure(508L, class = 'octmode'), '755');`&`(argv[[1]],argv[[2]]);
+[1] "754"
+
 ##com.oracle.truffle.r.test.testrgen.TestrGenBuiltinoperators.testoperators344
 #argv <- list(list());`&`(argv[[1]]);
 logical(0)
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java
index f38a27dd4902e884e53d3889bd6d2c4fe4e677e2..dc489dac547ece7d8f3c4b543156811b1436743b 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java
@@ -12600,7 +12600,7 @@ public class AllTests extends TestBase {
     }
 
     @Test
-    public void TestSimpleBuiltins_testOuterIgnore_fa7bab756255d002e9b280b544ccabdb() {
+    public void TestSimpleBuiltins_testOuter_fa7bab756255d002e9b280b544ccabdb() {
         assertEval("{ foo <- function (x,y) { x + y * 1i } ; outer(3,3,\"foo\") }");
     }
 
@@ -20330,7 +20330,7 @@ public class AllTests extends TestBase {
     }
 
     @Test
-    public void TestSimpleLoop_testLoops3Ignore_569178ca1ef4a4eb52481f6da3753a5a() {
+    public void TestSimpleLoop_testLoops3_569178ca1ef4a4eb52481f6da3753a5a() {
         assertEval("{ l <- quote(for(i in s) { x <- i }) ; s <- 1:3 ; eval(l) ; s <- NULL ; eval(l) ; x }");
     }
 
@@ -22430,13 +22430,13 @@ public class AllTests extends TestBase {
     }
 
     @Test
-    public void TestSimpleVectors_testListIndexIgnore_f9635083f8a0b70845e7d644ae6ea282() {
-        assertEvalError("{ z<-list(1,2,3,4); z[[list(1)]]<-NULL }");
+    public void TestSimpleVectors_testListIndexIgnore_2856013d57376f52f235d42dbf5472cd() {
+        assertEvalError("{ z<-1:4; z[[list(1)]]<-NULL }");
     }
 
     @Test
-    public void TestSimpleVectors_testListIndexIgnore_2856013d57376f52f235d42dbf5472cd() {
-        assertEvalError("{ z<-1:4; z[[list(1)]]<-NULL }");
+    public void TestSimpleVectors_testListIndexIgnore_f9635083f8a0b70845e7d644ae6ea282() {
+        assertEvalError("{ z<-list(1,2,3,4); z[[list(1)]]<-NULL }");
     }
 
     @Test
@@ -25295,182 +25295,182 @@ public class AllTests extends TestBase {
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_e664dced4050c3b0ec79ddfad13762d3() {
+    public void TestSimpleVectors_testNullUpdate_8cc751e6274d005bc4c6d552cc83eca0() {
+        assertEval("{ x <- NULL; x[[1]] <- c(5); x; }");
+    }
+
+    @Test
+    public void TestSimpleVectors_testNullUpdate_b3d51e938f7a8337dfdc84de7e9c7794() {
+        assertEval("{ x <- NULL; x[1] <- c(5); x; }");
+    }
+
+    @Test
+    public void TestSimpleVectors_testNullUpdate_6e81bd750316716655c2d14c6064ee61() {
+        assertEval("{ x <- NULL; x[c(1,2)] <- c(5); x; }");
+    }
+
+    @Test
+    public void TestSimpleVectors_testNullUpdate_a0e0dbeaa4bbcce1c45933d0368aa77a() {
+        assertEval("{ x <- NULL; x[c(1,2)] <- c(1,5); x; }");
+    }
+
+    @Test
+    public void TestSimpleVectors_testNullUpdateIgnore_e664dced4050c3b0ec79ddfad13762d3() {
         assertEval("{ x <- NULL; x[[0]] <- c(); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_6623dfd61adfbed1969aa6def31d48bd() {
+    public void TestSimpleVectors_testNullUpdateIgnore_6623dfd61adfbed1969aa6def31d48bd() {
         assertEval("{ x <- NULL; x[[1]] <- c(); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_115c835bb82f854eb9298f29030c50fb() {
+    public void TestSimpleVectors_testNullUpdateIgnore_115c835bb82f854eb9298f29030c50fb() {
         assertEval("{ x <- NULL; x[[c(1,0)]] <- c(); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_d6b24d15ca8bbc2d8898f2893ee48922() {
+    public void TestSimpleVectors_testNullUpdateIgnore_d6b24d15ca8bbc2d8898f2893ee48922() {
         assertEval("{ x <- NULL; x[[c(1,2)]] <- c(); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_2cb0c5508e6c5487d7ab3f34797f13b1() {
+    public void TestSimpleVectors_testNullUpdateIgnore_2cb0c5508e6c5487d7ab3f34797f13b1() {
         assertEval("{ x <- NULL; x[[c(0,1)]] <- c(); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_54147238425f466cc178d17eae76ceda() {
+    public void TestSimpleVectors_testNullUpdateIgnore_54147238425f466cc178d17eae76ceda() {
         assertEval("{ x <- NULL; x[[c(0,2)]] <- c(); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_9f6574f3776434274b3282c3b7cf4b9f() {
+    public void TestSimpleVectors_testNullUpdateIgnore_9f6574f3776434274b3282c3b7cf4b9f() {
         assertEval("{ x <- NULL; x[[0]] <- c(5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_8cc751e6274d005bc4c6d552cc83eca0() {
-        assertEval("{ x <- NULL; x[[1]] <- c(5); x; }");
-    }
-
-    @Test
-    public void TestSimpleVectors_testNullUpdate_a2f92f0914beffd008980e24f8d926a3() {
+    public void TestSimpleVectors_testNullUpdateIgnore_a2f92f0914beffd008980e24f8d926a3() {
         assertEval("{ x <- NULL; x[[c(1,0)]] <- c(5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_a0030d7c00203e4877a612e07291cd0b() {
+    public void TestSimpleVectors_testNullUpdateIgnore_a0030d7c00203e4877a612e07291cd0b() {
         assertEval("{ x <- NULL; x[[c(1,2)]] <- c(5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_0dca78f42826ed2ca5c82bb0dfcfe98d() {
+    public void TestSimpleVectors_testNullUpdateIgnore_0dca78f42826ed2ca5c82bb0dfcfe98d() {
         assertEval("{ x <- NULL; x[[c(0,1)]] <- c(5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_9286dc5a5e867285d67162938029e66a() {
+    public void TestSimpleVectors_testNullUpdateIgnore_9286dc5a5e867285d67162938029e66a() {
         assertEval("{ x <- NULL; x[[c(0,2)]] <- c(5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_2ff2bb5063043781e2dd4a5643e76e3f() {
+    public void TestSimpleVectors_testNullUpdateIgnore_2ff2bb5063043781e2dd4a5643e76e3f() {
         assertEval("{ x <- NULL; x[[0]] <- c(1,5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_b642a755473c66405719474adff409b5() {
+    public void TestSimpleVectors_testNullUpdateIgnore_b642a755473c66405719474adff409b5() {
         assertEval("{ x <- NULL; x[[1]] <- c(1,5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_64931012b5b20bfc8a8cf3d64429f520() {
+    public void TestSimpleVectors_testNullUpdateIgnore_64931012b5b20bfc8a8cf3d64429f520() {
         assertEval("{ x <- NULL; x[[c(1,0)]] <- c(1,5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_111c7e91a1ec07a73078de391361e157() {
+    public void TestSimpleVectors_testNullUpdateIgnore_111c7e91a1ec07a73078de391361e157() {
         assertEval("{ x <- NULL; x[[c(1,2)]] <- c(1,5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_057fc7addb0f7dc3a0e6c02e64fa2100() {
+    public void TestSimpleVectors_testNullUpdateIgnore_057fc7addb0f7dc3a0e6c02e64fa2100() {
         assertEval("{ x <- NULL; x[[c(0,1)]] <- c(1,5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_b10a18e2590314639aab86131ed765c9() {
+    public void TestSimpleVectors_testNullUpdateIgnore_b10a18e2590314639aab86131ed765c9() {
         assertEval("{ x <- NULL; x[[c(0,2)]] <- c(1,5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_eead23a44fc9d89e024143584819856b() {
+    public void TestSimpleVectors_testNullUpdateIgnore_eead23a44fc9d89e024143584819856b() {
         assertEval("{ x <- NULL; x[0] <- c(); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_95c2d54d689c1811ed66aae4d8a4af71() {
+    public void TestSimpleVectors_testNullUpdateIgnore_95c2d54d689c1811ed66aae4d8a4af71() {
         assertEval("{ x <- NULL; x[1] <- c(); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_4c0165b06588940c8aa1d829ff87f93a() {
+    public void TestSimpleVectors_testNullUpdateIgnore_4c0165b06588940c8aa1d829ff87f93a() {
         assertEval("{ x <- NULL; x[c(1,0)] <- c(); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_a9d3ab6f0969676b3da1051c915b6f92() {
+    public void TestSimpleVectors_testNullUpdateIgnore_a9d3ab6f0969676b3da1051c915b6f92() {
         assertEval("{ x <- NULL; x[c(1,2)] <- c(); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_3af3768ad0bdc831c3045b43219067af() {
+    public void TestSimpleVectors_testNullUpdateIgnore_3af3768ad0bdc831c3045b43219067af() {
         assertEval("{ x <- NULL; x[c(0,1)] <- c(); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_950084e021745a08ae3e14d398be6b88() {
+    public void TestSimpleVectors_testNullUpdateIgnore_950084e021745a08ae3e14d398be6b88() {
         assertEval("{ x <- NULL; x[c(0,2)] <- c(); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_65d3b6d2fe5a6f900abe16f53b8c3597() {
+    public void TestSimpleVectors_testNullUpdateIgnore_65d3b6d2fe5a6f900abe16f53b8c3597() {
         assertEval("{ x <- NULL; x[0] <- c(5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_b3d51e938f7a8337dfdc84de7e9c7794() {
-        assertEval("{ x <- NULL; x[1] <- c(5); x; }");
-    }
-
-    @Test
-    public void TestSimpleVectors_testNullUpdate_551d3ebbb6ac9fe58e4d30355fd2ec74() {
+    public void TestSimpleVectors_testNullUpdateIgnore_551d3ebbb6ac9fe58e4d30355fd2ec74() {
         assertEval("{ x <- NULL; x[c(1,0)] <- c(5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_6e81bd750316716655c2d14c6064ee61() {
-        assertEval("{ x <- NULL; x[c(1,2)] <- c(5); x; }");
-    }
-
-    @Test
-    public void TestSimpleVectors_testNullUpdate_fbe98cd1ce1c05710193e4f8c95d6f1c() {
+    public void TestSimpleVectors_testNullUpdateIgnore_fbe98cd1ce1c05710193e4f8c95d6f1c() {
         assertEval("{ x <- NULL; x[c(0,1)] <- c(5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_7257cb3decb49c4dac158dd8d90b5c09() {
+    public void TestSimpleVectors_testNullUpdateIgnore_7257cb3decb49c4dac158dd8d90b5c09() {
         assertEval("{ x <- NULL; x[c(0,2)] <- c(5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_2bfe43cdec831af749d3ec2ef32287cb() {
+    public void TestSimpleVectors_testNullUpdateIgnore_2bfe43cdec831af749d3ec2ef32287cb() {
         assertEval("{ x <- NULL; x[0] <- c(1,5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_d2e82b16d1a6c84e2b7aae9b8e297565() {
+    public void TestSimpleVectors_testNullUpdateIgnore_d2e82b16d1a6c84e2b7aae9b8e297565() {
         assertEval("{ x <- NULL; x[1] <- c(1,5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_dd9025a6b2e780cc03a7f92800512f84() {
+    public void TestSimpleVectors_testNullUpdateIgnore_dd9025a6b2e780cc03a7f92800512f84() {
         assertEval("{ x <- NULL; x[c(1,0)] <- c(1,5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_a0e0dbeaa4bbcce1c45933d0368aa77a() {
-        assertEval("{ x <- NULL; x[c(1,2)] <- c(1,5); x; }");
-    }
-
-    @Test
-    public void TestSimpleVectors_testNullUpdate_1f8c18cc93d9cec8047e76c15e8c8eca() {
+    public void TestSimpleVectors_testNullUpdateIgnore_1f8c18cc93d9cec8047e76c15e8c8eca() {
         assertEval("{ x <- NULL; x[c(0,1)] <- c(1,5); x; }");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_a2146a5c80766a6d5cc2f40c06202033() {
+    public void TestSimpleVectors_testNullUpdateIgnore_a2146a5c80766a6d5cc2f40c06202033() {
         assertEval("{ x <- NULL; x[c(0,2)] <- c(1,5); x; }");
     }
 
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/failing/FailingTests.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/failing/FailingTests.java
index aeaaed988a6536ef89f2082b287f717bed433080..3a354327db5a13aa779787306e2428890b39144c 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/failing/FailingTests.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/failing/FailingTests.java
@@ -939,12 +939,6 @@ public class FailingTests extends TestBase {
         check("TestSimpleBuiltins_testNArgsIgnore_ee082d552ee9efa22803929c01c73692");
     }
 
-    @Test
-    public void TestSimpleBuiltins_testOuterIgnore_fa7bab756255d002e9b280b544ccabdb() {
-        assertEval("{ foo <- function (x,y) { x + y * 1i } ; outer(3,3,\"foo\") }");
-        check("TestSimpleBuiltins_testOuterIgnore_fa7bab756255d002e9b280b544ccabdb");
-    }
-
     @Test
     public void TestSimpleBuiltins_testParen_499acebd19ac76555ed92ca7ecc3ec53() {
         assertEval("{ a = array(1,c(3,3,3)); (a[1,2,3] = 3) }");
@@ -1521,12 +1515,6 @@ public class FailingTests extends TestBase {
         check("TestSimpleLists_testListArgumentEvaluation_f62339e36ed620e527abf492790cea00");
     }
 
-    @Test
-    public void TestSimpleLoop_testLoops3Ignore_569178ca1ef4a4eb52481f6da3753a5a() {
-        assertEval("{ l <- quote(for(i in s) { x <- i }) ; s <- 1:3 ; eval(l) ; s <- NULL ; eval(l) ; x }");
-        check("TestSimpleLoop_testLoops3Ignore_569178ca1ef4a4eb52481f6da3753a5a");
-    }
-
     @Test
     public void TestSimpleLoop_testLoopsErrorsIgnore_f394e8f19fc73574a5c55ba7f8e03973() {
         assertEvalError("{ l <- quote(for(i in s) { x <- i }) ; s <- 1:3 ; eval(l) ; s <- function(){} ; eval(l) ; x }");
@@ -1569,18 +1557,18 @@ public class FailingTests extends TestBase {
         check("TestSimpleVectors_testListIndexIgnore_2223add8510c9d9c0c26ffc36fbf858e");
     }
 
-    @Test
-    public void TestSimpleVectors_testListIndexIgnore_f9635083f8a0b70845e7d644ae6ea282() {
-        assertEvalError("{ z<-list(1,2,3,4); z[[list(1)]]<-NULL }");
-        check("TestSimpleVectors_testListIndexIgnore_f9635083f8a0b70845e7d644ae6ea282");
-    }
-
     @Test
     public void TestSimpleVectors_testListIndexIgnore_2856013d57376f52f235d42dbf5472cd() {
         assertEvalError("{ z<-1:4; z[[list(1)]]<-NULL }");
         check("TestSimpleVectors_testListIndexIgnore_2856013d57376f52f235d42dbf5472cd");
     }
 
+    @Test
+    public void TestSimpleVectors_testListIndexIgnore_f9635083f8a0b70845e7d644ae6ea282() {
+        assertEvalError("{ z<-list(1,2,3,4); z[[list(1)]]<-NULL }");
+        check("TestSimpleVectors_testListIndexIgnore_f9635083f8a0b70845e7d644ae6ea282");
+    }
+
     @Test
     public void TestSimpleVectors_testListUpdateIgnore_942201d73db7111f1ae9c68deaed4964() {
         assertEvalError("{ f <- function(b,i,v) { b[[i]] <- v ; b } ; f(list(1,2,list(3)), c(3,1), 4) ; f(c(1,2,3), 2L, NULL) }");
@@ -1684,219 +1672,195 @@ public class FailingTests extends TestBase {
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_e664dced4050c3b0ec79ddfad13762d3() {
+    public void TestSimpleVectors_testNullUpdateIgnore_e664dced4050c3b0ec79ddfad13762d3() {
         assertEval("{ x <- NULL; x[[0]] <- c(); x; }");
-        check("TestSimpleVectors_testNullUpdate_e664dced4050c3b0ec79ddfad13762d3");
+        check("TestSimpleVectors_testNullUpdateIgnore_e664dced4050c3b0ec79ddfad13762d3");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_6623dfd61adfbed1969aa6def31d48bd() {
+    public void TestSimpleVectors_testNullUpdateIgnore_6623dfd61adfbed1969aa6def31d48bd() {
         assertEval("{ x <- NULL; x[[1]] <- c(); x; }");
-        check("TestSimpleVectors_testNullUpdate_6623dfd61adfbed1969aa6def31d48bd");
+        check("TestSimpleVectors_testNullUpdateIgnore_6623dfd61adfbed1969aa6def31d48bd");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_115c835bb82f854eb9298f29030c50fb() {
+    public void TestSimpleVectors_testNullUpdateIgnore_115c835bb82f854eb9298f29030c50fb() {
         assertEval("{ x <- NULL; x[[c(1,0)]] <- c(); x; }");
-        check("TestSimpleVectors_testNullUpdate_115c835bb82f854eb9298f29030c50fb");
+        check("TestSimpleVectors_testNullUpdateIgnore_115c835bb82f854eb9298f29030c50fb");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_d6b24d15ca8bbc2d8898f2893ee48922() {
+    public void TestSimpleVectors_testNullUpdateIgnore_d6b24d15ca8bbc2d8898f2893ee48922() {
         assertEval("{ x <- NULL; x[[c(1,2)]] <- c(); x; }");
-        check("TestSimpleVectors_testNullUpdate_d6b24d15ca8bbc2d8898f2893ee48922");
+        check("TestSimpleVectors_testNullUpdateIgnore_d6b24d15ca8bbc2d8898f2893ee48922");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_2cb0c5508e6c5487d7ab3f34797f13b1() {
+    public void TestSimpleVectors_testNullUpdateIgnore_2cb0c5508e6c5487d7ab3f34797f13b1() {
         assertEval("{ x <- NULL; x[[c(0,1)]] <- c(); x; }");
-        check("TestSimpleVectors_testNullUpdate_2cb0c5508e6c5487d7ab3f34797f13b1");
+        check("TestSimpleVectors_testNullUpdateIgnore_2cb0c5508e6c5487d7ab3f34797f13b1");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_54147238425f466cc178d17eae76ceda() {
+    public void TestSimpleVectors_testNullUpdateIgnore_54147238425f466cc178d17eae76ceda() {
         assertEval("{ x <- NULL; x[[c(0,2)]] <- c(); x; }");
-        check("TestSimpleVectors_testNullUpdate_54147238425f466cc178d17eae76ceda");
+        check("TestSimpleVectors_testNullUpdateIgnore_54147238425f466cc178d17eae76ceda");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_9f6574f3776434274b3282c3b7cf4b9f() {
+    public void TestSimpleVectors_testNullUpdateIgnore_9f6574f3776434274b3282c3b7cf4b9f() {
         assertEval("{ x <- NULL; x[[0]] <- c(5); x; }");
-        check("TestSimpleVectors_testNullUpdate_9f6574f3776434274b3282c3b7cf4b9f");
+        check("TestSimpleVectors_testNullUpdateIgnore_9f6574f3776434274b3282c3b7cf4b9f");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_8cc751e6274d005bc4c6d552cc83eca0() {
-        assertEval("{ x <- NULL; x[[1]] <- c(5); x; }");
-        check("TestSimpleVectors_testNullUpdate_8cc751e6274d005bc4c6d552cc83eca0");
-    }
-
-    @Test
-    public void TestSimpleVectors_testNullUpdate_a2f92f0914beffd008980e24f8d926a3() {
+    public void TestSimpleVectors_testNullUpdateIgnore_a2f92f0914beffd008980e24f8d926a3() {
         assertEval("{ x <- NULL; x[[c(1,0)]] <- c(5); x; }");
-        check("TestSimpleVectors_testNullUpdate_a2f92f0914beffd008980e24f8d926a3");
+        check("TestSimpleVectors_testNullUpdateIgnore_a2f92f0914beffd008980e24f8d926a3");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_a0030d7c00203e4877a612e07291cd0b() {
+    public void TestSimpleVectors_testNullUpdateIgnore_a0030d7c00203e4877a612e07291cd0b() {
         assertEval("{ x <- NULL; x[[c(1,2)]] <- c(5); x; }");
-        check("TestSimpleVectors_testNullUpdate_a0030d7c00203e4877a612e07291cd0b");
+        check("TestSimpleVectors_testNullUpdateIgnore_a0030d7c00203e4877a612e07291cd0b");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_0dca78f42826ed2ca5c82bb0dfcfe98d() {
+    public void TestSimpleVectors_testNullUpdateIgnore_0dca78f42826ed2ca5c82bb0dfcfe98d() {
         assertEval("{ x <- NULL; x[[c(0,1)]] <- c(5); x; }");
-        check("TestSimpleVectors_testNullUpdate_0dca78f42826ed2ca5c82bb0dfcfe98d");
+        check("TestSimpleVectors_testNullUpdateIgnore_0dca78f42826ed2ca5c82bb0dfcfe98d");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_9286dc5a5e867285d67162938029e66a() {
+    public void TestSimpleVectors_testNullUpdateIgnore_9286dc5a5e867285d67162938029e66a() {
         assertEval("{ x <- NULL; x[[c(0,2)]] <- c(5); x; }");
-        check("TestSimpleVectors_testNullUpdate_9286dc5a5e867285d67162938029e66a");
+        check("TestSimpleVectors_testNullUpdateIgnore_9286dc5a5e867285d67162938029e66a");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_2ff2bb5063043781e2dd4a5643e76e3f() {
+    public void TestSimpleVectors_testNullUpdateIgnore_2ff2bb5063043781e2dd4a5643e76e3f() {
         assertEval("{ x <- NULL; x[[0]] <- c(1,5); x; }");
-        check("TestSimpleVectors_testNullUpdate_2ff2bb5063043781e2dd4a5643e76e3f");
+        check("TestSimpleVectors_testNullUpdateIgnore_2ff2bb5063043781e2dd4a5643e76e3f");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_b642a755473c66405719474adff409b5() {
+    public void TestSimpleVectors_testNullUpdateIgnore_b642a755473c66405719474adff409b5() {
         assertEval("{ x <- NULL; x[[1]] <- c(1,5); x; }");
-        check("TestSimpleVectors_testNullUpdate_b642a755473c66405719474adff409b5");
+        check("TestSimpleVectors_testNullUpdateIgnore_b642a755473c66405719474adff409b5");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_64931012b5b20bfc8a8cf3d64429f520() {
+    public void TestSimpleVectors_testNullUpdateIgnore_64931012b5b20bfc8a8cf3d64429f520() {
         assertEval("{ x <- NULL; x[[c(1,0)]] <- c(1,5); x; }");
-        check("TestSimpleVectors_testNullUpdate_64931012b5b20bfc8a8cf3d64429f520");
+        check("TestSimpleVectors_testNullUpdateIgnore_64931012b5b20bfc8a8cf3d64429f520");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_111c7e91a1ec07a73078de391361e157() {
+    public void TestSimpleVectors_testNullUpdateIgnore_111c7e91a1ec07a73078de391361e157() {
         assertEval("{ x <- NULL; x[[c(1,2)]] <- c(1,5); x; }");
-        check("TestSimpleVectors_testNullUpdate_111c7e91a1ec07a73078de391361e157");
+        check("TestSimpleVectors_testNullUpdateIgnore_111c7e91a1ec07a73078de391361e157");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_057fc7addb0f7dc3a0e6c02e64fa2100() {
+    public void TestSimpleVectors_testNullUpdateIgnore_057fc7addb0f7dc3a0e6c02e64fa2100() {
         assertEval("{ x <- NULL; x[[c(0,1)]] <- c(1,5); x; }");
-        check("TestSimpleVectors_testNullUpdate_057fc7addb0f7dc3a0e6c02e64fa2100");
+        check("TestSimpleVectors_testNullUpdateIgnore_057fc7addb0f7dc3a0e6c02e64fa2100");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_b10a18e2590314639aab86131ed765c9() {
+    public void TestSimpleVectors_testNullUpdateIgnore_b10a18e2590314639aab86131ed765c9() {
         assertEval("{ x <- NULL; x[[c(0,2)]] <- c(1,5); x; }");
-        check("TestSimpleVectors_testNullUpdate_b10a18e2590314639aab86131ed765c9");
+        check("TestSimpleVectors_testNullUpdateIgnore_b10a18e2590314639aab86131ed765c9");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_eead23a44fc9d89e024143584819856b() {
+    public void TestSimpleVectors_testNullUpdateIgnore_eead23a44fc9d89e024143584819856b() {
         assertEval("{ x <- NULL; x[0] <- c(); x; }");
-        check("TestSimpleVectors_testNullUpdate_eead23a44fc9d89e024143584819856b");
+        check("TestSimpleVectors_testNullUpdateIgnore_eead23a44fc9d89e024143584819856b");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_95c2d54d689c1811ed66aae4d8a4af71() {
+    public void TestSimpleVectors_testNullUpdateIgnore_95c2d54d689c1811ed66aae4d8a4af71() {
         assertEval("{ x <- NULL; x[1] <- c(); x; }");
-        check("TestSimpleVectors_testNullUpdate_95c2d54d689c1811ed66aae4d8a4af71");
+        check("TestSimpleVectors_testNullUpdateIgnore_95c2d54d689c1811ed66aae4d8a4af71");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_4c0165b06588940c8aa1d829ff87f93a() {
+    public void TestSimpleVectors_testNullUpdateIgnore_4c0165b06588940c8aa1d829ff87f93a() {
         assertEval("{ x <- NULL; x[c(1,0)] <- c(); x; }");
-        check("TestSimpleVectors_testNullUpdate_4c0165b06588940c8aa1d829ff87f93a");
+        check("TestSimpleVectors_testNullUpdateIgnore_4c0165b06588940c8aa1d829ff87f93a");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_a9d3ab6f0969676b3da1051c915b6f92() {
+    public void TestSimpleVectors_testNullUpdateIgnore_a9d3ab6f0969676b3da1051c915b6f92() {
         assertEval("{ x <- NULL; x[c(1,2)] <- c(); x; }");
-        check("TestSimpleVectors_testNullUpdate_a9d3ab6f0969676b3da1051c915b6f92");
+        check("TestSimpleVectors_testNullUpdateIgnore_a9d3ab6f0969676b3da1051c915b6f92");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_3af3768ad0bdc831c3045b43219067af() {
+    public void TestSimpleVectors_testNullUpdateIgnore_3af3768ad0bdc831c3045b43219067af() {
         assertEval("{ x <- NULL; x[c(0,1)] <- c(); x; }");
-        check("TestSimpleVectors_testNullUpdate_3af3768ad0bdc831c3045b43219067af");
+        check("TestSimpleVectors_testNullUpdateIgnore_3af3768ad0bdc831c3045b43219067af");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_950084e021745a08ae3e14d398be6b88() {
+    public void TestSimpleVectors_testNullUpdateIgnore_950084e021745a08ae3e14d398be6b88() {
         assertEval("{ x <- NULL; x[c(0,2)] <- c(); x; }");
-        check("TestSimpleVectors_testNullUpdate_950084e021745a08ae3e14d398be6b88");
+        check("TestSimpleVectors_testNullUpdateIgnore_950084e021745a08ae3e14d398be6b88");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_65d3b6d2fe5a6f900abe16f53b8c3597() {
+    public void TestSimpleVectors_testNullUpdateIgnore_65d3b6d2fe5a6f900abe16f53b8c3597() {
         assertEval("{ x <- NULL; x[0] <- c(5); x; }");
-        check("TestSimpleVectors_testNullUpdate_65d3b6d2fe5a6f900abe16f53b8c3597");
-    }
-
-    @Test
-    public void TestSimpleVectors_testNullUpdate_b3d51e938f7a8337dfdc84de7e9c7794() {
-        assertEval("{ x <- NULL; x[1] <- c(5); x; }");
-        check("TestSimpleVectors_testNullUpdate_b3d51e938f7a8337dfdc84de7e9c7794");
+        check("TestSimpleVectors_testNullUpdateIgnore_65d3b6d2fe5a6f900abe16f53b8c3597");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_551d3ebbb6ac9fe58e4d30355fd2ec74() {
+    public void TestSimpleVectors_testNullUpdateIgnore_551d3ebbb6ac9fe58e4d30355fd2ec74() {
         assertEval("{ x <- NULL; x[c(1,0)] <- c(5); x; }");
-        check("TestSimpleVectors_testNullUpdate_551d3ebbb6ac9fe58e4d30355fd2ec74");
+        check("TestSimpleVectors_testNullUpdateIgnore_551d3ebbb6ac9fe58e4d30355fd2ec74");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_6e81bd750316716655c2d14c6064ee61() {
-        assertEval("{ x <- NULL; x[c(1,2)] <- c(5); x; }");
-        check("TestSimpleVectors_testNullUpdate_6e81bd750316716655c2d14c6064ee61");
-    }
-
-    @Test
-    public void TestSimpleVectors_testNullUpdate_fbe98cd1ce1c05710193e4f8c95d6f1c() {
+    public void TestSimpleVectors_testNullUpdateIgnore_fbe98cd1ce1c05710193e4f8c95d6f1c() {
         assertEval("{ x <- NULL; x[c(0,1)] <- c(5); x; }");
-        check("TestSimpleVectors_testNullUpdate_fbe98cd1ce1c05710193e4f8c95d6f1c");
+        check("TestSimpleVectors_testNullUpdateIgnore_fbe98cd1ce1c05710193e4f8c95d6f1c");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_7257cb3decb49c4dac158dd8d90b5c09() {
+    public void TestSimpleVectors_testNullUpdateIgnore_7257cb3decb49c4dac158dd8d90b5c09() {
         assertEval("{ x <- NULL; x[c(0,2)] <- c(5); x; }");
-        check("TestSimpleVectors_testNullUpdate_7257cb3decb49c4dac158dd8d90b5c09");
+        check("TestSimpleVectors_testNullUpdateIgnore_7257cb3decb49c4dac158dd8d90b5c09");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_2bfe43cdec831af749d3ec2ef32287cb() {
+    public void TestSimpleVectors_testNullUpdateIgnore_2bfe43cdec831af749d3ec2ef32287cb() {
         assertEval("{ x <- NULL; x[0] <- c(1,5); x; }");
-        check("TestSimpleVectors_testNullUpdate_2bfe43cdec831af749d3ec2ef32287cb");
+        check("TestSimpleVectors_testNullUpdateIgnore_2bfe43cdec831af749d3ec2ef32287cb");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_d2e82b16d1a6c84e2b7aae9b8e297565() {
+    public void TestSimpleVectors_testNullUpdateIgnore_d2e82b16d1a6c84e2b7aae9b8e297565() {
         assertEval("{ x <- NULL; x[1] <- c(1,5); x; }");
-        check("TestSimpleVectors_testNullUpdate_d2e82b16d1a6c84e2b7aae9b8e297565");
+        check("TestSimpleVectors_testNullUpdateIgnore_d2e82b16d1a6c84e2b7aae9b8e297565");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_dd9025a6b2e780cc03a7f92800512f84() {
+    public void TestSimpleVectors_testNullUpdateIgnore_dd9025a6b2e780cc03a7f92800512f84() {
         assertEval("{ x <- NULL; x[c(1,0)] <- c(1,5); x; }");
-        check("TestSimpleVectors_testNullUpdate_dd9025a6b2e780cc03a7f92800512f84");
-    }
-
-    @Test
-    public void TestSimpleVectors_testNullUpdate_a0e0dbeaa4bbcce1c45933d0368aa77a() {
-        assertEval("{ x <- NULL; x[c(1,2)] <- c(1,5); x; }");
-        check("TestSimpleVectors_testNullUpdate_a0e0dbeaa4bbcce1c45933d0368aa77a");
+        check("TestSimpleVectors_testNullUpdateIgnore_dd9025a6b2e780cc03a7f92800512f84");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_1f8c18cc93d9cec8047e76c15e8c8eca() {
+    public void TestSimpleVectors_testNullUpdateIgnore_1f8c18cc93d9cec8047e76c15e8c8eca() {
         assertEval("{ x <- NULL; x[c(0,1)] <- c(1,5); x; }");
-        check("TestSimpleVectors_testNullUpdate_1f8c18cc93d9cec8047e76c15e8c8eca");
+        check("TestSimpleVectors_testNullUpdateIgnore_1f8c18cc93d9cec8047e76c15e8c8eca");
     }
 
     @Test
-    public void TestSimpleVectors_testNullUpdate_a2146a5c80766a6d5cc2f40c06202033() {
+    public void TestSimpleVectors_testNullUpdateIgnore_a2146a5c80766a6d5cc2f40c06202033() {
         assertEval("{ x <- NULL; x[c(0,2)] <- c(1,5); x; }");
-        check("TestSimpleVectors_testNullUpdate_a2146a5c80766a6d5cc2f40c06202033");
+        check("TestSimpleVectors_testNullUpdateIgnore_a2146a5c80766a6d5cc2f40c06202033");
     }
 
     @Test
@@ -2157,12 +2121,6 @@ public class FailingTests extends TestBase {
         check("TestrGenBuiltinDate2POSIXlt_testDate2POSIXlt9_bf3dde227e3258e44e9b499785adf609");
     }
 
-    @Test
-    public void TestrGenBuiltinEncoding_testEncoding1_4467cf1f6dabf42a77c4a7a6cf7d7bc7() {
-        assertEval("argv <- list('Byte Code Compiler'); .Internal(Encoding(argv[[1]]))");
-        check("TestrGenBuiltinEncoding_testEncoding1_4467cf1f6dabf42a77c4a7a6cf7d7bc7");
-    }
-
     @Test
     public void TestrGenBuiltinEncoding_testEncoding2_4e78ef1b1b4588f13ca257df54d0dca6() {
         assertEval("argv <- list(c('\\n', '\\n', '## These cannot be run by examples() but should be OK when pasted\\n', '## into an interactive R session with the tcltk package loaded\\n', '\\n', 'tt <- tktoplevel()\\n', 'tkpack(txt.w <- tktext(tt))\\n', 'tkinsert(txt.w, \\'0.0\\', \\'plot(1:10)\\')\\n', '\\n', '# callback function\\n', 'eval.txt <- function()\\n', '   eval(parse(text = tclvalue(tkget(txt.w, \\'0.0\\', \\'end\\'))))\\n', 'tkpack(but.w <- tkbutton(tt, text = \\'Submit\\', command = eval.txt))\\n', '\\n', '## Try pressing the button, edit the text and when finished:\\n', '\\n', 'tkdestroy(tt)\\n', '\\n', '\\n')); .Internal(Encoding(argv[[1]]))");
@@ -2199,12 +2157,6 @@ public class FailingTests extends TestBase {
         check("TestrGenBuiltinEncoding_testEncoding7_4d932eb25388709f0291f720f54a9c70");
     }
 
-    @Test
-    public void TestrGenBuiltinEncoding_testEncoding9_319db9824e5c4511b17d5729ea8df27d() {
-        assertEval("argv <- structure(list(x = 'abc'), .Names = 'x');do.call('Encoding', argv)");
-        check("TestrGenBuiltinEncoding_testEncoding9_319db9824e5c4511b17d5729ea8df27d");
-    }
-
     @Test
     public void TestrGenBuiltinEncodingassign__testEncodingassign_1_d9e73901a0a16c5e8e711375a3a2c926() {
         assertEval("argv <- structure(list(x = 'abc', value = 'UTF-8'), .Names = c('x',     'value'));do.call('Encoding<-', argv)");
@@ -2787,12 +2739,6 @@ public class FailingTests extends TestBase {
         check("TestrGenBuiltinallvars_testallvars1_639b4c2ec17d95b654fedb05e999dbab");
     }
 
-    @Test
-    public void TestrGenBuiltinand_octmode_testand_octmode1_4a7df79937a53ae14143411150f6cf7c() {
-        assertEval("argv <- structure(list(a = structure(integer(0), class = 'octmode'),     b = '400'), .Names = c('a', 'b'));do.call('&.octmode', argv)");
-        check("TestrGenBuiltinand_octmode_testand_octmode1_4a7df79937a53ae14143411150f6cf7c");
-    }
-
     @Test
     public void TestrGenBuiltinany_testany17_58be436b003b48508d76dfe0ba27580a() {
         assertEval("argv <- list('NA');do.call('any', argv)");
@@ -3207,30 +3153,6 @@ public class FailingTests extends TestBase {
         check("TestrGenBuiltinascall_testascall1_75dad11a1d07a7a5fd405091a76cfe2d");
     }
 
-    @Test
-    public void TestrGenBuiltinascall_testascall2_449d54ebb2b0ae08e77ca684b2cbd4ae() {
-        assertEval("argv <- list(list(quote(quote), FALSE));as.call(argv[[1]]);");
-        check("TestrGenBuiltinascall_testascall2_449d54ebb2b0ae08e77ca684b2cbd4ae");
-    }
-
-    @Test
-    public void TestrGenBuiltinascall_testascall3_576f6deb6494b95f0406b343929fc8a4() {
-        assertEval("argv <- list(list(quote(quote), list(NULL, c('time', 'status'))));as.call(argv[[1]]);");
-        check("TestrGenBuiltinascall_testascall3_576f6deb6494b95f0406b343929fc8a4");
-    }
-
-    @Test
-    public void TestrGenBuiltinascall_testascall5_051693b1bebf4f33d3241d651c72f4d3() {
-        assertEval("argv <- list(list(quote(quote), 80L));as.call(argv[[1]]);");
-        check("TestrGenBuiltinascall_testascall5_051693b1bebf4f33d3241d651c72f4d3");
-    }
-
-    @Test
-    public void TestrGenBuiltinascall_testascall6_a95ff22c9ef3ec6e77ee48b0335377c7() {
-        assertEval("argv <- list(list(quote(quote), NA));as.call(argv[[1]]);");
-        check("TestrGenBuiltinascall_testascall6_a95ff22c9ef3ec6e77ee48b0335377c7");
-    }
-
     @Test
     public void TestrGenBuiltinascharacter_testascharacter14_b618dc1d6e4030d027f9e589707f3220() {
         assertEval("argv <- list(structure('Estimates a probability density function,  \\n', Rd_tag = 'TEXT'));as.character(argv[[1]]);");
@@ -3453,12 +3375,6 @@ public class FailingTests extends TestBase {
         check("TestrGenBuiltinasdouble_testasdouble8_8eade01b937fb096c73488398e8454f4");
     }
 
-    @Test
-    public void TestrGenBuiltinasdoubledifftime_testasdoubledifftime1_2f442f4b40bf7b7ec96499b8c71bca24() {
-        assertEval("argv <- structure(list(x = structure(16351.8259046444, units = 'days',     class = 'difftime', origin = structure(0, class = c('POSIXct',         'POSIXt'), tzone = 'GMT'))), .Names = 'x');do.call('as.double.difftime', argv)");
-        check("TestrGenBuiltinasdoubledifftime_testasdoubledifftime1_2f442f4b40bf7b7ec96499b8c71bca24");
-    }
-
     @Test
     public void TestrGenBuiltinasin_testasin2_491c4b3e1cb2ac77763d88264422d3f4() {
         assertEval("argv <- list(c(2+0i, 2-0.0001i, -2+0i, -2+0.0001i));asin(argv[[1]]);");
@@ -4191,42 +4107,6 @@ public class FailingTests extends TestBase {
         check("TestrGenBuiltinbindtextdomain_testbindtextdomain2_8961295a914ee0581df6a90cb6841dd6");
     }
 
-    @Test
-    public void TestrGenBuiltinbitwiseAnd_testbitwiseAnd1_aa2f5a12e5456739afbe05df58e66002() {
-        assertEval("argv <- list(structure(c(420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 493L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 493L, 493L, 493L, 493L, 493L, 493L, 493L, 493L, 493L, 493L, 493L), class = 'octmode'), structure(256L, class = 'octmode')); .Internal(bitwiseAnd(argv[[1]], argv[[2]]))");
-        check("TestrGenBuiltinbitwiseAnd_testbitwiseAnd1_aa2f5a12e5456739afbe05df58e66002");
-    }
-
-    @Test
-    public void TestrGenBuiltinbitwiseAnd_testbitwiseAnd2_8337f9a47e6be7ee56fb9e4048479be1() {
-        assertEval("argv <- list(structure(integer(0), class = 'hexmode'), structure(integer(0), class = 'hexmode')); .Internal(bitwiseAnd(argv[[1]], argv[[2]]))");
-        check("TestrGenBuiltinbitwiseAnd_testbitwiseAnd2_8337f9a47e6be7ee56fb9e4048479be1");
-    }
-
-    @Test
-    public void TestrGenBuiltinbitwiseNot_testbitwiseNot1_6f4621a85f41aeed410087846823e620() {
-        assertEval("argv <- list(structure(numeric(0), .Dim = c(0L, 0L))); .Internal(bitwiseNot(argv[[1]]))");
-        check("TestrGenBuiltinbitwiseNot_testbitwiseNot1_6f4621a85f41aeed410087846823e620");
-    }
-
-    @Test
-    public void TestrGenBuiltinbitwiseOr_testbitwiseOr1_2fc068352a4607103b67148f6f3ad61c() {
-        assertEval("argv <- list(15L, 7L); .Internal(bitwiseOr(argv[[1]], argv[[2]]))");
-        check("TestrGenBuiltinbitwiseOr_testbitwiseOr1_2fc068352a4607103b67148f6f3ad61c");
-    }
-
-    @Test
-    public void TestrGenBuiltinbitwiseShiftR_testbitwiseShiftR1_ca7b2aa43f08bec7efe9c8fed9d5d0b7() {
-        assertEval("argv <- list(-1, 1:31); .Internal(bitwiseShiftR(argv[[1]], argv[[2]]))");
-        check("TestrGenBuiltinbitwiseShiftR_testbitwiseShiftR1_ca7b2aa43f08bec7efe9c8fed9d5d0b7");
-    }
-
-    @Test
-    public void TestrGenBuiltinbitwiseXor_testbitwiseXor1_67d355fb00ab2f9ad9cb963a329fe194() {
-        assertEval("argv <- list(-1L, 1L); .Internal(bitwiseXor(argv[[1]], argv[[2]]))");
-        check("TestrGenBuiltinbitwiseXor_testbitwiseXor1_67d355fb00ab2f9ad9cb963a329fe194");
-    }
-
     @Test
     public void TestrGenBuiltinbody_testbody1_10aef9003d5613516e7b26cc2253360b() {
         assertEval("argv <- list(function (x, y) {    c(x, y)}); .Internal(body(argv[[1]]))");
@@ -6057,18 +5937,6 @@ public class FailingTests extends TestBase {
         check("TestrGenBuiltinextract_parentasis_dataframe_testextract_parentasis_dataframe2_5a2ab0c147f4f04db1c0405c273b36bf");
     }
 
-    @Test
-    public void TestrGenBuiltinextract_parentasis_extract_parentasis_factor_testextract_parentasis_extract_parentasis_factor1_5fced93c42220fd5b3326690c2f82d6b() {
-        assertEval("argv <- structure(list(x = structure(2:4, .Label = c('A', 'B',     'C', 'D', 'E'), class = 'factor'), 2), .Names = c('x', ''));do.call('[[.factor', argv)");
-        check("TestrGenBuiltinextract_parentasis_extract_parentasis_factor_testextract_parentasis_extract_parentasis_factor1_5fced93c42220fd5b3326690c2f82d6b");
-    }
-
-    @Test
-    public void TestrGenBuiltinextract_parentasis_factor_testextract_parentasis_factor1_3ede514eacaf473da1f649221ef7a410() {
-        assertEval("argv <- structure(list(x = structure(c(111L, 88L, 93L, 74L, 138L,     103L, 46L, 114L, 112L, 24L, 99L, 97L, 57L, 40L, 86L, 37L,     124L, 9L, 20L, 54L, 145L, 3L, 7L, 134L, 98L, 143L, 131L,     47L, 128L, 116L, 137L, 5L, 132L, 21L, 81L, 58L, 108L, 17L,     107L, 126L, 2L, 18L, 75L, 4L, 63L, 121L, 84L, 101L, 123L,     102L, 36L, 48L, 12L, 105L, 100L, 90L, 34L, 55L, 68L, 10L,     52L, 91L, 146L, 127L, 1L, 29L, 106L, 26L, 115L, 118L, 25L,     82L, 16L, 45L, 95L, 69L, 72L, 15L, 120L, 104L, 125L, 6L,     140L, 65L, 62L, 39L, 35L, 38L, 83L, 117L, 42L, 13L, 87L,     22L, 53L, 41L, 113L, 73L, 133L, 23L, 80L, 8L, 19L, 78L, 60L,     31L, 33L, 147L, 139L, 56L, 130L, 64L, 71L, 43L, 136L, 89L,     94L, 96L, 70L, 59L, 129L, 27L, 92L, 51L, 77L, 50L, 66L, 119L,     135L, 110L, 144L, 109L, 67L, 44L, 32L, 141L, 76L, 79L, 49L,     142L, 30L, 14L, 85L, 28L, 11L, 61L, 122L), .Label = c('1415787_at',     '1415904_at', '1415993_at', '1416164_at', '1416181_at', '1416221_at',     '1416481_s_at', '1416812_at', '1416855_at', '1416949_s_at',     '1417129_a_at', '1417425_at', '1417447_at', '1417466_at',     '1417572_at', '1417624_at', '1417667_a_at', '1417964_at',     '1418084_at', '1418382_at', '1418424_at', '1418471_at', '1418479_at',     '1418486_at', '1418516_at', '1418560_at', '1418649_at', '1418835_at',     '1419361_at', '1419430_at', '1419686_at', '1419833_s_at',     '1420011_s_at', '1420643_at', '1420886_a_at', '1421045_at',     '1421180_at', '1421773_at', '1422018_at', '1422557_s_at',     '1422671_s_at', '1422809_at', '1422850_at', '1422979_at',     '1423095_s_at', '1423110_at', '1423123_at', '1423124_x_at',     '1423176_at', '1423319_at', '1423852_at', '1423924_s_at',     '1424107_at', '1424186_at', '1424212_at', '1424243_at', '1424474_a_at',     '1424749_at', '1425494_s_at', '1425534_at', '1425779_a_at',     '1426083_a_at', '1426295_at', '1426371_at', '1426485_at',     '1426510_at', '1426628_at', '1426845_at', '1427120_at', '1427208_at',     '1427256_at', '1427314_at', '1427672_a_at', '1428922_at',     '1428942_at', '1429177_x_at', '1429514_at', '1429859_a_at',     '1431830_at', '1433512_at', '1434326_x_at', '1434485_a_at',     '1434831_a_at', '1434920_a_at', '1435129_at', '1435327_at',     '1435357_at', '1436392_s_at', '1436528_at', '1436886_x_at',     '1437163_x_at', '1437223_s_at', '1437434_a_at', '1437455_a_at',     '1438312_s_at', '1438651_a_at', '1439148_a_at', '1439373_x_at',     '1439381_x_at', '1439962_at', '1448131_at', '1448143_at',     '1448147_at', '1448259_at', '1448269_a_at', '1448466_at',     '1448601_s_at', '1448630_a_at', '1448823_at', '1448943_at',     '1448995_at', '1449059_a_at', '1449376_at', '1449623_at',     '1449630_s_at', '1449697_s_at', '1449699_s_at', '1449755_at',     '1449773_s_at', '1449885_at', '1450070_s_at', '1450723_at',     '1450846_at', '1450857_a_at', '1450941_at', '1451103_at',     '1451266_at', '1451317_at', '1451332_at', '1451415_at', '1451418_a_at',     '1451532_s_at', '1451536_at', '1452003_at', '1452110_at',     '1452183_a_at', '1452665_at', '1452671_s_at', '1452869_at',     '1453030_at', '1455056_at', '1455517_at', '1456174_x_at',     '1456393_at', '1456434_x_at', '1460260_s_at', '1460359_at'),     class = 'factor'), 1:25), .Names = c('x', ''));do.call('[.factor', argv)");
-        check("TestrGenBuiltinextract_parentasis_factor_testextract_parentasis_factor1_3ede514eacaf473da1f649221ef7a410");
-    }
-
     @Test
     public void TestrGenBuiltinfileinfo_testfileinfo1_a99b095a177ec7e9005fb967dfaec9a9() {
         assertEval("argv <- list('/home/lzhao/hg/r-instrumented/library/codetools/data'); .Internal(file.info(argv[[1]]))");
@@ -6495,12 +6363,6 @@ public class FailingTests extends TestBase {
         check("TestrGenBuiltinformatPOSIXlt_testformatPOSIXlt9_513125df94e8f7e95e17d9524967da07");
     }
 
-    @Test
-    public void TestrGenBuiltinformatdifftime_testformatdifftime1_b67b6a7d49df06d569ab1cab65dc1c58() {
-        assertEval("argv <- structure(list(x = structure(c(0, 30, 60), units = 'mins',     class = 'difftime')), .Names = 'x');do.call('format.difftime', argv)");
-        check("TestrGenBuiltinformatdifftime_testformatdifftime1_b67b6a7d49df06d569ab1cab65dc1c58");
-    }
-
     @Test
     public void TestrGenBuiltinformatinfo_testformatinfo1_b142f7c9c7c086832b3e99225b1af15c() {
         assertEval("argv <- list(c(0.099999994, 0.2), 7L, 0L); .Internal(format.info(argv[[1]], argv[[2]], argv[[3]]))");
@@ -8535,12 +8397,6 @@ public class FailingTests extends TestBase {
         check("TestrGenBuiltinmeandefault_testmeandefault1_aff5510f988974e3de95c8cf8b010743");
     }
 
-    @Test
-    public void TestrGenBuiltinmeandifftime_testmeandifftime1_8c979d698513e418dd8055b2c9a377b9() {
-        assertEval("argv <- structure(list(x = structure(c(31, NA, NA, 31), units = 'days',     class = 'difftime'), na.rm = TRUE), .Names = c('x', 'na.rm'));do.call('mean.difftime', argv)");
-        check("TestrGenBuiltinmeandifftime_testmeandifftime1_8c979d698513e418dd8055b2c9a377b9");
-    }
-
     @Test
     public void TestrGenBuiltinmemDecompress_testmemDecompress1_e671c3385759ba61495ddb5408e18509() {
         assertEval("argv <- structure(list(from = as.raw(c(253, 55, 122, 88, 90,     0, 0, 1, 105, 34, 222, 54, 2, 0, 33, 1, 28, 0, 0, 0, 16,     207, 88, 204, 224, 7, 207, 0, 28, 93, 0, 24, 140, 130, 182,     196, 17, 52, 92, 78, 225, 221, 115, 179, 63, 98, 20, 119,     183, 90, 101, 43, 5, 112, 179, 75, 69, 222, 0, 0, 155, 136,     185, 16, 0, 1, 52, 208, 15, 0, 0, 0, 105, 254, 40, 141, 62,     48, 13, 139, 2, 0, 0, 0, 0, 1, 89, 90)), type = 'xz', asChar = TRUE),     .Names = c('from', 'type', 'asChar'));do.call('memDecompress', argv)");
@@ -8919,12 +8775,6 @@ public class FailingTests extends TestBase {
         check("TestrGenBuiltinoperators_testoperators168_9356a73e37f1d5b19b01f02fad7cfd07");
     }
 
-    @Test
-    public void TestrGenBuiltinoperators_testoperators169_f1b2742960c9b0c8374d37ebe067c38e() {
-        assertEval("argv <- list(structure(1:3, .Label = c('1', '2', NA), class = 'factor'), structure(1:3, .Label = c('1', '2', NA), class = 'factor'));`!=`(argv[[1]],argv[[2]]);");
-        check("TestrGenBuiltinoperators_testoperators169_f1b2742960c9b0c8374d37ebe067c38e");
-    }
-
     @Test
     public void TestrGenBuiltinoperators_testoperators171_e4cdd0497655c9b378c2cbdbe765935b() {
         assertEval("argv <- list(structure(c(1960.08433333333, 1960.16766666667, 1960.251, 1960.33433333333, 1960.41766666667, 1960.501, 1960.58433333333, 1960.66766666667, 1960.751, 1960.83433333333, 1960.91766666667, 1961.001, 1961.08433333333, 1961.16766666667, 1961.251, 1961.33433333333, 1961.41766666667, 1961.501, 1961.58433333333, 1961.66766666667), .Tsp = c(1960.08333333333, 1961.66666666667, 12), class = 'ts'), 1);`%%`(argv[[1]],argv[[2]]);");
@@ -9303,12 +9153,6 @@ public class FailingTests extends TestBase {
         check("TestrGenBuiltinoperators_testoperators312_f0e28dda5fd6a79f4fce4f88da41e681");
     }
 
-    @Test
-    public void TestrGenBuiltinoperators_testoperators314_9be667d83c3750672072fb07114a3b67() {
-        assertEval("argv <- list(structure(120L, class = 'octmode'), '644');`|`(argv[[1]],argv[[2]]);");
-        check("TestrGenBuiltinoperators_testoperators314_9be667d83c3750672072fb07114a3b67");
-    }
-
     @Test
     public void TestrGenBuiltinoperators_testoperators315_56ce43a2563e7f87e2d356df25867b95() {
         assertEval("argv <- list(structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1), .Dim = c(9L, 5L), .Dimnames = list(c('1', '2', '3', '4', '5', '6', '7', '8', '9'), c('(Intercept)', 'outcome2', 'outcome3', 'treatment2', 'treatment3')), assign = c(0L, 1L, 1L, 2L, 2L), contrasts = structure(list(outcome = 'contr.treatment', treatment = 'contr.treatment'), .Names = c('outcome', 'treatment'))), c(3.04452243772342, -0.454255272277594, -0.292987124681473, 1.33790930192987e-15, 1.42108546079721e-15));`%*%`(argv[[1]],argv[[2]]);");
@@ -9411,12 +9255,6 @@ public class FailingTests extends TestBase {
         check("TestrGenBuiltinoperators_testoperators341_7aebbf647e9c2fe68e5efbab86240d11");
     }
 
-    @Test
-    public void TestrGenBuiltinoperators_testoperators343_3d4847ee88a4b4979dc54cafab35e84a() {
-        assertEval("argv <- list(structure(508L, class = 'octmode'), '755');`&`(argv[[1]],argv[[2]]);");
-        check("TestrGenBuiltinoperators_testoperators343_3d4847ee88a4b4979dc54cafab35e84a");
-    }
-
     @Test
     public void TestrGenBuiltinoperators_testoperators345_a476b48d092a98b21d8ad887beeed08d() {
         assertEval("argv <- list(structure(c(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE), .Names = c('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100', '101', '102', '103', '104', '105', '106', '107', '108', '109', '110', '111', '112', '113', '114', '115', '116', '117', '118', '119', '120', '121', '122', '123', '124', '125', '126', '127', '128', '129', '130', '131', '132', '133', '134', '135', '136', '137', '138', '139', '140', '141', '142', '143', '144', '145', '146')));`(`(argv[[1]]);");
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleBuiltins.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleBuiltins.java
index 6d38492a880bd47c39ef342ca0209707cb531124..cc040a664effd194e05236c03ffe4f6fa7a0e600 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleBuiltins.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleBuiltins.java
@@ -1155,11 +1155,6 @@ public class TestSimpleBuiltins extends TestBase {
         assertEval("{ outer(1:3,1:2, function(x,y,z) { x*y*z }, 10) }");
         assertEval("{ outer(1:2, 1:3, \"<\") }");
         assertEval("{ outer(1:2, 1:3, '<') }");
-    }
-
-    @Test
-    @Ignore
-    public void testOuterIgnore() {
         assertEval("{ foo <- function (x,y) { x + y * 1i } ; outer(3,3,\"foo\") }");
     }
 
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleLoop.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleLoop.java
index d1a3889384140a3666f1afb6cc551e4f3e2c9bec..17553261fd30f9876a0664c8b339e359a59a421f 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleLoop.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleLoop.java
@@ -86,11 +86,6 @@ public class TestSimpleLoop extends TestBase {
 
         assertEval("{ l <- quote({ for(i in c(1,2,3,4)) { if (i == 1) { next } ; if (i==3) { break } ; x <- i ; if (i==4) { x <- 10 } } ; x }) ; f <- function() { eval(l) } ; f()  }");
         assertEval("{ l <- quote({ for(i in 1:4) { if (i == 1) { next } ; if (i==3) { break } ; x <- i ; if (i==4) { x <- 10 } } ; x }) ; f <- function() { eval(l) } ; f()  }");
-    }
-
-    @Test
-    @Ignore
-    public void testLoops3Ignore() {
         assertEval("{ l <- quote(for(i in s) { x <- i }) ; s <- 1:3 ; eval(l) ; s <- NULL ; eval(l) ; x }");
     }
 
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleVectors.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleVectors.java
index 04bfe34b38a69eeda132dced0658214e404ab68a..6889df44efc5935f673893095512659bd0f3265d 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleVectors.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleVectors.java
@@ -789,7 +789,6 @@ public class TestSimpleVectors extends TestBase {
         assertEvalError("{ x<-list(1,2,3,4); dim(x)<-c(2,2); x[as.raw(1), 1]<-integer() }");
         assertEvalError("{ x<-list(1,2,3,4); dim(x)<-c(2,2); x[as.raw(1), 1]<-7 }");
         assertEvalError("{ x<-list(1,2,3,4); dim(x)<-c(2,2); x[as.raw(1), 1]<-c(7,42) }");
-
     }
 
     @Test
@@ -936,8 +935,8 @@ public class TestSimpleVectors extends TestBase {
     @Ignore
     public void testListIndexIgnore() {
         assertEvalError("{ z<-1:4; z[[list()]]<-NULL }");
-        assertEvalError("{ z<-list(1,2,3,4); z[[list(1)]]<-NULL }");
         assertEvalError("{ z<-1:4; z[[list(1)]]<-NULL }");
+        assertEvalError("{ z<-list(1,2,3,4); z[[list(1)]]<-NULL }");
     }
 
     @Test
@@ -2079,8 +2078,16 @@ public class TestSimpleVectors extends TestBase {
     }
 
     @Test
-    @Ignore
     public void testNullUpdate() {
+        assertEval("{ x <- NULL; x[[1]] <- c(5); x; }");
+        assertEval("{ x <- NULL; x[1] <- c(5); x; }");
+        assertEval("{ x <- NULL; x[c(1,2)] <- c(5); x; }");
+        assertEval("{ x <- NULL; x[c(1,2)] <- c(1,5); x; }");
+    }
+
+    @Test
+    @Ignore
+    public void testNullUpdateIgnore() {
         assertEval("{ x <- NULL; x[[0]] <- c(); x; }");
         assertEval("{ x <- NULL; x[[1]] <- c(); x; }");
         assertEval("{ x <- NULL; x[[c(1,0)]] <- c(); x; }");
@@ -2088,7 +2095,6 @@ public class TestSimpleVectors extends TestBase {
         assertEval("{ x <- NULL; x[[c(0,1)]] <- c(); x; }");
         assertEval("{ x <- NULL; x[[c(0,2)]] <- c(); x; }");
         assertEval("{ x <- NULL; x[[0]] <- c(5); x; }");
-        assertEval("{ x <- NULL; x[[1]] <- c(5); x; }");
         assertEval("{ x <- NULL; x[[c(1,0)]] <- c(5); x; }");
         assertEval("{ x <- NULL; x[[c(1,2)]] <- c(5); x; }");
         assertEval("{ x <- NULL; x[[c(0,1)]] <- c(5); x; }");
@@ -2106,15 +2112,12 @@ public class TestSimpleVectors extends TestBase {
         assertEval("{ x <- NULL; x[c(0,1)] <- c(); x; }");
         assertEval("{ x <- NULL; x[c(0,2)] <- c(); x; }");
         assertEval("{ x <- NULL; x[0] <- c(5); x; }");
-        assertEval("{ x <- NULL; x[1] <- c(5); x; }");
         assertEval("{ x <- NULL; x[c(1,0)] <- c(5); x; }");
-        assertEval("{ x <- NULL; x[c(1,2)] <- c(5); x; }");
         assertEval("{ x <- NULL; x[c(0,1)] <- c(5); x; }");
         assertEval("{ x <- NULL; x[c(0,2)] <- c(5); x; }");
         assertEval("{ x <- NULL; x[0] <- c(1,5); x; }");
         assertEval("{ x <- NULL; x[1] <- c(1,5); x; }");
         assertEval("{ x <- NULL; x[c(1,0)] <- c(1,5); x; }");
-        assertEval("{ x <- NULL; x[c(1,2)] <- c(1,5); x; }");
         assertEval("{ x <- NULL; x[c(0,1)] <- c(1,5); x; }");
         assertEval("{ x <- NULL; x[c(0,2)] <- c(1,5); x; }");
     }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinEncoding.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinEncoding.java
index 6610b00d24812bfb6ca507b55667eb8d0d2d950e..85e0368735fe01dacce78e7eb49d76ff0488713d 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinEncoding.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinEncoding.java
@@ -2,9 +2,9 @@
  * This material is distributed under the GNU General Public License
  * Version 2. You may review the terms of this license at
  * http://www.gnu.org/licenses/gpl-2.0.html
- * 
+ *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -18,7 +18,6 @@ import com.oracle.truffle.r.test.*;
 public class TestrGenBuiltinEncoding extends TestBase {
 
     @Test
-    @Ignore
     public void testEncoding1() {
         assertEval("argv <- list(\'Byte Code Compiler\'); .Internal(Encoding(argv[[1]]))");
     }
@@ -59,12 +58,9 @@ public class TestrGenBuiltinEncoding extends TestBase {
         assertEval("argv <- list(c(\'* Edit the help file skeletons in 'man', possibly combining help files for multiple functions.\', \'* Edit the exports in 'NAMESPACE', and add necessary imports.\', \'* Put any C/C++/Fortran code in 'src'.\', \'* If you have compiled code, add a useDynLib() directive to 'NAMESPACE'.\', \'* Run R CMD build to build the package tarball.\', \'* Run R CMD check to check the package tarball.\', \'\', \'Read \\\'Writing R Extensions\\\' for more information.\')); .Internal(Encoding(argv[[1]]))");
     }
 
-	@Test
-    @Ignore
-	public void testEncoding9() {
-		assertEval("argv <- structure(list(x = \'abc\'), .Names = \'x\');"+
-			"do.call(\'Encoding\', argv)");
-	}
+    @Test
+    public void testEncoding9() {
+        assertEval("argv <- structure(list(x = \'abc\'), .Names = \'x\');" + "do.call(\'Encoding\', argv)");
+    }
 
 }
-
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinand_octmode.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinand_octmode.java
index d9f086e4eaf3877b93dcc1d450da286a098e48a3..690ad5e460ab5cb2e4b768f19cdba1fc4ed59f17 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinand_octmode.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinand_octmode.java
@@ -2,9 +2,9 @@
  * This material is distributed under the GNU General Public License
  * Version 2. You may review the terms of this license at
  * http://www.gnu.org/licenses/gpl-2.0.html
- * 
+ *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
  * All rights reserved.
  */
 package com.oracle.truffle.r.test.testrgen;
@@ -15,14 +15,11 @@ import com.oracle.truffle.r.test.*;
 
 // Checkstyle: stop line length check
 
-                                                                 public class TestrGenBuiltinand_octmode extends TestBase {
+public class TestrGenBuiltinand_octmode extends TestBase {
 
-	@Test
-    @Ignore
-	public void testand_octmode1() {
-		assertEval("argv <- structure(list(a = structure(integer(0), class = \'octmode\'),     b = \'400\'), .Names = c(\'a\', \'b\'));"+
-			"do.call(\'&.octmode\', argv)");
-	}
+    @Test
+    public void testand_octmode1() {
+        assertEval("argv <- structure(list(a = structure(integer(0), class = \'octmode\'),     b = \'400\'), .Names = c(\'a\', \'b\'));" + "do.call(\'&.octmode\', argv)");
+    }
 
 }
-
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinascall.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinascall.java
index 352ba104bfd1c52a432da0a13516f64034331fb6..616b1c77777439caf3c7fdaa797e0509434d278f 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinascall.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinascall.java
@@ -24,13 +24,11 @@ public class TestrGenBuiltinascall extends TestBase {
     }
 
     @Test
-    @Ignore
     public void testascall2() {
         assertEval("argv <- list(list(quote(quote), FALSE));as.call(argv[[1]]);");
     }
 
     @Test
-    @Ignore
     public void testascall3() {
         assertEval("argv <- list(list(quote(quote), list(NULL, c(\'time\', \'status\'))));as.call(argv[[1]]);");
     }
@@ -41,13 +39,11 @@ public class TestrGenBuiltinascall extends TestBase {
     }
 
     @Test
-    @Ignore
     public void testascall5() {
         assertEval("argv <- list(list(quote(quote), 80L));as.call(argv[[1]]);");
     }
 
     @Test
-    @Ignore
     public void testascall6() {
         assertEval("argv <- list(list(quote(quote), NA));as.call(argv[[1]]);");
     }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinasdoubledifftime.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinasdoubledifftime.java
index ed579d27fb3d21055be89c402d7e5d3f959ff544..119b196d19f1d2fa7ccd13148cc401af90dddefa 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinasdoubledifftime.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinasdoubledifftime.java
@@ -2,9 +2,9 @@
  * This material is distributed under the GNU General Public License
  * Version 2. You may review the terms of this license at
  * http://www.gnu.org/licenses/gpl-2.0.html
- * 
+ *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
  * All rights reserved.
  */
 package com.oracle.truffle.r.test.testrgen;
@@ -15,14 +15,12 @@ import com.oracle.truffle.r.test.*;
 
 // Checkstyle: stop line length check
 
-                                                                 public class TestrGenBuiltinasdoubledifftime extends TestBase {
+public class TestrGenBuiltinasdoubledifftime extends TestBase {
 
-	@Test
-    @Ignore
-	public void testasdoubledifftime1() {
-		assertEval("argv <- structure(list(x = structure(16351.8259046444, units = \'days\',     class = \'difftime\', origin = structure(0, class = c(\'POSIXct\',         \'POSIXt\'), tzone = \'GMT\'))), .Names = \'x\');"+
-			"do.call(\'as.double.difftime\', argv)");
-	}
+    @Test
+    public void testasdoubledifftime1() {
+        assertEval("argv <- structure(list(x = structure(16351.8259046444, units = \'days\',     class = \'difftime\', origin = structure(0, class = c(\'POSIXct\',         \'POSIXt\'), tzone = \'GMT\'))), .Names = \'x\');"
+                        + "do.call(\'as.double.difftime\', argv)");
+    }
 
 }
-
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseAnd.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseAnd.java
index 64320f4fdac61a25854a8e1f8585fb73ddbec972..4ac30cceccb15ffb756e108964047410f6559f83 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseAnd.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseAnd.java
@@ -2,9 +2,9 @@
  * This material is distributed under the GNU General Public License
  * Version 2. You may review the terms of this license at
  * http://www.gnu.org/licenses/gpl-2.0.html
- * 
+ *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -18,15 +18,12 @@ import com.oracle.truffle.r.test.*;
 public class TestrGenBuiltinbitwiseAnd extends TestBase {
 
     @Test
-    @Ignore
     public void testbitwiseAnd1() {
         assertEval("argv <- list(structure(c(420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 493L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 420L, 493L, 493L, 493L, 493L, 493L, 493L, 493L, 493L, 493L, 493L, 493L), class = \'octmode\'), structure(256L, class = \'octmode\')); .Internal(bitwiseAnd(argv[[1]], argv[[2]]))");
     }
 
     @Test
-    @Ignore
     public void testbitwiseAnd2() {
         assertEval("argv <- list(structure(integer(0), class = \'hexmode\'), structure(integer(0), class = \'hexmode\')); .Internal(bitwiseAnd(argv[[1]], argv[[2]]))");
     }
 }
-
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseNot.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseNot.java
index f236feb6af5f9dc10872a6fa30889a15be1b107f..cc08b4fa562ee41ac5628527f20a9638e3ffeee7 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseNot.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseNot.java
@@ -2,9 +2,9 @@
  * This material is distributed under the GNU General Public License
  * Version 2. You may review the terms of this license at
  * http://www.gnu.org/licenses/gpl-2.0.html
- * 
+ *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -18,9 +18,7 @@ import com.oracle.truffle.r.test.*;
 public class TestrGenBuiltinbitwiseNot extends TestBase {
 
     @Test
-    @Ignore
     public void testbitwiseNot1() {
         assertEval("argv <- list(structure(numeric(0), .Dim = c(0L, 0L))); .Internal(bitwiseNot(argv[[1]]))");
     }
 }
-
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseOr.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseOr.java
index 657d97a0015efc9193ab547202a4a13722d4e991..a8e524552732bf544b367127519a5064165b01c0 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseOr.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseOr.java
@@ -2,9 +2,9 @@
  * This material is distributed under the GNU General Public License
  * Version 2. You may review the terms of this license at
  * http://www.gnu.org/licenses/gpl-2.0.html
- * 
+ *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -18,9 +18,7 @@ import com.oracle.truffle.r.test.*;
 public class TestrGenBuiltinbitwiseOr extends TestBase {
 
     @Test
-    @Ignore
     public void testbitwiseOr1() {
         assertEval("argv <- list(15L, 7L); .Internal(bitwiseOr(argv[[1]], argv[[2]]))");
     }
 }
-
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseShiftR.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseShiftR.java
index f4b3d27edebd7c2bf73a6ef0b3e9ea0b3141c32f..a7dfad9eaf71e92288704643f2f7647f1293dca4 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseShiftR.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseShiftR.java
@@ -2,9 +2,9 @@
  * This material is distributed under the GNU General Public License
  * Version 2. You may review the terms of this license at
  * http://www.gnu.org/licenses/gpl-2.0.html
- * 
+ *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -18,9 +18,7 @@ import com.oracle.truffle.r.test.*;
 public class TestrGenBuiltinbitwiseShiftR extends TestBase {
 
     @Test
-    @Ignore
     public void testbitwiseShiftR1() {
         assertEval("argv <- list(-1, 1:31); .Internal(bitwiseShiftR(argv[[1]], argv[[2]]))");
     }
 }
-
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseXor.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseXor.java
index 830900d1624b4a4a50d78cc3c064d0ae697e9e28..72b257158031c31aa9237ec0934d108b6721384d 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseXor.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinbitwiseXor.java
@@ -2,9 +2,9 @@
  * This material is distributed under the GNU General Public License
  * Version 2. You may review the terms of this license at
  * http://www.gnu.org/licenses/gpl-2.0.html
- * 
+ *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -18,9 +18,7 @@ import com.oracle.truffle.r.test.*;
 public class TestrGenBuiltinbitwiseXor extends TestBase {
 
     @Test
-    @Ignore
     public void testbitwiseXor1() {
         assertEval("argv <- list(-1L, 1L); .Internal(bitwiseXor(argv[[1]], argv[[2]]))");
     }
 }
-
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinextract_parentasis_extract_parentasis_factor.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinextract_parentasis_extract_parentasis_factor.java
index 139de4b4acb60e2ea907e27a677cef8cf8ae3bdc..50937a5c4aa13f3375f14c9981f1eea9f24dd64c 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinextract_parentasis_extract_parentasis_factor.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinextract_parentasis_extract_parentasis_factor.java
@@ -2,9 +2,9 @@
  * This material is distributed under the GNU General Public License
  * Version 2. You may review the terms of this license at
  * http://www.gnu.org/licenses/gpl-2.0.html
- * 
+ *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
  * All rights reserved.
  */
 package com.oracle.truffle.r.test.testrgen;
@@ -15,14 +15,10 @@ import com.oracle.truffle.r.test.*;
 
 // Checkstyle: stop line length check
 
-                                                                 public class TestrGenBuiltinextract_parentasis_extract_parentasis_factor extends TestBase {
-
-	@Test
-    @Ignore
-	public void testextract_parentasis_extract_parentasis_factor1() {
-		assertEval("argv <- structure(list(x = structure(2:4, .Label = c(\'A\', \'B\',     \'C\', \'D\', \'E\'), class = \'factor\'), 2), .Names = c(\'x\', \'\'));"+
-			"do.call(\'[[.factor\', argv)");
-	}
+public class TestrGenBuiltinextract_parentasis_extract_parentasis_factor extends TestBase {
 
+    @Test
+    public void testextract_parentasis_extract_parentasis_factor1() {
+        assertEval("argv <- structure(list(x = structure(2:4, .Label = c(\'A\', \'B\',     \'C\', \'D\', \'E\'), class = \'factor\'), 2), .Names = c(\'x\', \'\'));" + "do.call(\'[[.factor\', argv)");
+    }
 }
-
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinextract_parentasis_factor.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinextract_parentasis_factor.java
index acd279586cbdb3f2df56f7fd7b3d632b09393663..bd75284b8d379e76cf459a86031a3d134d5a7fb2 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinextract_parentasis_factor.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinextract_parentasis_factor.java
@@ -2,9 +2,9 @@
  * This material is distributed under the GNU General Public License
  * Version 2. You may review the terms of this license at
  * http://www.gnu.org/licenses/gpl-2.0.html
- * 
+ *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
  * All rights reserved.
  */
 package com.oracle.truffle.r.test.testrgen;
@@ -15,14 +15,11 @@ import com.oracle.truffle.r.test.*;
 
 // Checkstyle: stop line length check
 
-                                                                 public class TestrGenBuiltinextract_parentasis_factor extends TestBase {
-
-	@Test
-    @Ignore
-	public void testextract_parentasis_factor1() {
-		assertEval("argv <- structure(list(x = structure(c(111L, 88L, 93L, 74L, 138L,     103L, 46L, 114L, 112L, 24L, 99L, 97L, 57L, 40L, 86L, 37L,     124L, 9L, 20L, 54L, 145L, 3L, 7L, 134L, 98L, 143L, 131L,     47L, 128L, 116L, 137L, 5L, 132L, 21L, 81L, 58L, 108L, 17L,     107L, 126L, 2L, 18L, 75L, 4L, 63L, 121L, 84L, 101L, 123L,     102L, 36L, 48L, 12L, 105L, 100L, 90L, 34L, 55L, 68L, 10L,     52L, 91L, 146L, 127L, 1L, 29L, 106L, 26L, 115L, 118L, 25L,     82L, 16L, 45L, 95L, 69L, 72L, 15L, 120L, 104L, 125L, 6L,     140L, 65L, 62L, 39L, 35L, 38L, 83L, 117L, 42L, 13L, 87L,     22L, 53L, 41L, 113L, 73L, 133L, 23L, 80L, 8L, 19L, 78L, 60L,     31L, 33L, 147L, 139L, 56L, 130L, 64L, 71L, 43L, 136L, 89L,     94L, 96L, 70L, 59L, 129L, 27L, 92L, 51L, 77L, 50L, 66L, 119L,     135L, 110L, 144L, 109L, 67L, 44L, 32L, 141L, 76L, 79L, 49L,     142L, 30L, 14L, 85L, 28L, 11L, 61L, 122L), .Label = c(\'1415787_at\',     \'1415904_at\', \'1415993_at\', \'1416164_at\', \'1416181_at\', \'1416221_at\',     \'1416481_s_at\', \'1416812_at\', \'1416855_at\', \'1416949_s_at\',     \'1417129_a_at\', \'1417425_at\', \'1417447_at\', \'1417466_at\',     \'1417572_at\', \'1417624_at\', \'1417667_a_at\', \'1417964_at\',     \'1418084_at\', \'1418382_at\', \'1418424_at\', \'1418471_at\', \'1418479_at\',     \'1418486_at\', \'1418516_at\', \'1418560_at\', \'1418649_at\', \'1418835_at\',     \'1419361_at\', \'1419430_at\', \'1419686_at\', \'1419833_s_at\',     \'1420011_s_at\', \'1420643_at\', \'1420886_a_at\', \'1421045_at\',     \'1421180_at\', \'1421773_at\', \'1422018_at\', \'1422557_s_at\',     \'1422671_s_at\', \'1422809_at\', \'1422850_at\', \'1422979_at\',     \'1423095_s_at\', \'1423110_at\', \'1423123_at\', \'1423124_x_at\',     \'1423176_at\', \'1423319_at\', \'1423852_at\', \'1423924_s_at\',     \'1424107_at\', \'1424186_at\', \'1424212_at\', \'1424243_at\', \'1424474_a_at\',     \'1424749_at\', \'1425494_s_at\', \'1425534_at\', \'1425779_a_at\',     \'1426083_a_at\', \'1426295_at\', \'1426371_at\', \'1426485_at\',     \'1426510_at\', \'1426628_at\', \'1426845_at\', \'1427120_at\', \'1427208_at\',     \'1427256_at\', \'1427314_at\', \'1427672_a_at\', \'1428922_at\',     \'1428942_at\', \'1429177_x_at\', \'1429514_at\', \'1429859_a_at\',     \'1431830_at\', \'1433512_at\', \'1434326_x_at\', \'1434485_a_at\',     \'1434831_a_at\', \'1434920_a_at\', \'1435129_at\', \'1435327_at\',     \'1435357_at\', \'1436392_s_at\', \'1436528_at\', \'1436886_x_at\',     \'1437163_x_at\', \'1437223_s_at\', \'1437434_a_at\', \'1437455_a_at\',     \'1438312_s_at\', \'1438651_a_at\', \'1439148_a_at\', \'1439373_x_at\',     \'1439381_x_at\', \'1439962_at\', \'1448131_at\', \'1448143_at\',     \'1448147_at\', \'1448259_at\', \'1448269_a_at\', \'1448466_at\',     \'1448601_s_at\', \'1448630_a_at\', \'1448823_at\', \'1448943_at\',     \'1448995_at\', \'1449059_a_at\', \'1449376_at\', \'1449623_at\',     \'1449630_s_at\', \'1449697_s_at\', \'1449699_s_at\', \'1449755_at\',     \'1449773_s_at\', \'1449885_at\', \'1450070_s_at\', \'1450723_at\',     \'1450846_at\', \'1450857_a_at\', \'1450941_at\', \'1451103_at\',     \'1451266_at\', \'1451317_at\', \'1451332_at\', \'1451415_at\', \'1451418_a_at\',     \'1451532_s_at\', \'1451536_at\', \'1452003_at\', \'1452110_at\',     \'1452183_a_at\', \'1452665_at\', \'1452671_s_at\', \'1452869_at\',     \'1453030_at\', \'1455056_at\', \'1455517_at\', \'1456174_x_at\',     \'1456393_at\', \'1456434_x_at\', \'1460260_s_at\', \'1460359_at\'),     class = \'factor\'), 1:25), .Names = c(\'x\', \'\'));"+
-			"do.call(\'[.factor\', argv)");
-	}
+public class TestrGenBuiltinextract_parentasis_factor extends TestBase {
 
+    @Test
+    public void testextract_parentasis_factor1() {
+        assertEval("argv <- structure(list(x = structure(c(111L, 88L, 93L, 74L, 138L,     103L, 46L, 114L, 112L, 24L, 99L, 97L, 57L, 40L, 86L, 37L,     124L, 9L, 20L, 54L, 145L, 3L, 7L, 134L, 98L, 143L, 131L,     47L, 128L, 116L, 137L, 5L, 132L, 21L, 81L, 58L, 108L, 17L,     107L, 126L, 2L, 18L, 75L, 4L, 63L, 121L, 84L, 101L, 123L,     102L, 36L, 48L, 12L, 105L, 100L, 90L, 34L, 55L, 68L, 10L,     52L, 91L, 146L, 127L, 1L, 29L, 106L, 26L, 115L, 118L, 25L,     82L, 16L, 45L, 95L, 69L, 72L, 15L, 120L, 104L, 125L, 6L,     140L, 65L, 62L, 39L, 35L, 38L, 83L, 117L, 42L, 13L, 87L,     22L, 53L, 41L, 113L, 73L, 133L, 23L, 80L, 8L, 19L, 78L, 60L,     31L, 33L, 147L, 139L, 56L, 130L, 64L, 71L, 43L, 136L, 89L,     94L, 96L, 70L, 59L, 129L, 27L, 92L, 51L, 77L, 50L, 66L, 119L,     135L, 110L, 144L, 109L, 67L, 44L, 32L, 141L, 76L, 79L, 49L,     142L, 30L, 14L, 85L, 28L, 11L, 61L, 122L), .Label = c(\'1415787_at\',     \'1415904_at\', \'1415993_at\', \'1416164_at\', \'1416181_at\', \'1416221_at\',     \'1416481_s_at\', \'1416812_at\', \'1416855_at\', \'1416949_s_at\',     \'1417129_a_at\', \'1417425_at\', \'1417447_at\', \'1417466_at\',     \'1417572_at\', \'1417624_at\', \'1417667_a_at\', \'1417964_at\',     \'1418084_at\', \'1418382_at\', \'1418424_at\', \'1418471_at\', \'1418479_at\',     \'1418486_at\', \'1418516_at\', \'1418560_at\', \'1418649_at\', \'1418835_at\',     \'1419361_at\', \'1419430_at\', \'1419686_at\', \'1419833_s_at\',     \'1420011_s_at\', \'1420643_at\', \'1420886_a_at\', \'1421045_at\',     \'1421180_at\', \'1421773_at\', \'1422018_at\', \'1422557_s_at\',     \'1422671_s_at\', \'1422809_at\', \'1422850_at\', \'1422979_at\',     \'1423095_s_at\', \'1423110_at\', \'1423123_at\', \'1423124_x_at\',     \'1423176_at\', \'1423319_at\', \'1423852_at\', \'1423924_s_at\',     \'1424107_at\', \'1424186_at\', \'1424212_at\', \'1424243_at\', \'1424474_a_at\',     \'1424749_at\', \'1425494_s_at\', \'1425534_at\', \'1425779_a_at\',     \'1426083_a_at\', \'1426295_at\', \'1426371_at\', \'1426485_at\',     \'1426510_at\', \'1426628_at\', \'1426845_at\', \'1427120_at\', \'1427208_at\',     \'1427256_at\', \'1427314_at\', \'1427672_a_at\', \'1428922_at\',     \'1428942_at\', \'1429177_x_at\', \'1429514_at\', \'1429859_a_at\',     \'1431830_at\', \'1433512_at\', \'1434326_x_at\', \'1434485_a_at\',     \'1434831_a_at\', \'1434920_a_at\', \'1435129_at\', \'1435327_at\',     \'1435357_at\', \'1436392_s_at\', \'1436528_at\', \'1436886_x_at\',     \'1437163_x_at\', \'1437223_s_at\', \'1437434_a_at\', \'1437455_a_at\',     \'1438312_s_at\', \'1438651_a_at\', \'1439148_a_at\', \'1439373_x_at\',     \'1439381_x_at\', \'1439962_at\', \'1448131_at\', \'1448143_at\',     \'1448147_at\', \'1448259_at\', \'1448269_a_at\', \'1448466_at\',     \'1448601_s_at\', \'1448630_a_at\', \'1448823_at\', \'1448943_at\',     \'1448995_at\', \'1449059_a_at\', \'1449376_at\', \'1449623_at\',     \'1449630_s_at\', \'1449697_s_at\', \'1449699_s_at\', \'1449755_at\',     \'1449773_s_at\', \'1449885_at\', \'1450070_s_at\', \'1450723_at\',     \'1450846_at\', \'1450857_a_at\', \'1450941_at\', \'1451103_at\',     \'1451266_at\', \'1451317_at\', \'1451332_at\', \'1451415_at\', \'1451418_a_at\',     \'1451532_s_at\', \'1451536_at\', \'1452003_at\', \'1452110_at\',     \'1452183_a_at\', \'1452665_at\', \'1452671_s_at\', \'1452869_at\',     \'1453030_at\', \'1455056_at\', \'1455517_at\', \'1456174_x_at\',     \'1456393_at\', \'1456434_x_at\', \'1460260_s_at\', \'1460359_at\'),     class = \'factor\'), 1:25), .Names = c(\'x\', \'\'));"
+                        + "do.call(\'[.factor\', argv)");
+    }
 }
-
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinformatdifftime.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinformatdifftime.java
index ddacc21f3b17900239ff66a910cd9702d90b9c47..c2e8963200ce4f1d8495775fd3e50214e888ed6c 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinformatdifftime.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinformatdifftime.java
@@ -2,9 +2,9 @@
  * This material is distributed under the GNU General Public License
  * Version 2. You may review the terms of this license at
  * http://www.gnu.org/licenses/gpl-2.0.html
- * 
+ *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
  * All rights reserved.
  */
 package com.oracle.truffle.r.test.testrgen;
@@ -15,14 +15,11 @@ import com.oracle.truffle.r.test.*;
 
 // Checkstyle: stop line length check
 
-                                                                 public class TestrGenBuiltinformatdifftime extends TestBase {
+public class TestrGenBuiltinformatdifftime extends TestBase {
 
-	@Test
-    @Ignore
-	public void testformatdifftime1() {
-		assertEval("argv <- structure(list(x = structure(c(0, 30, 60), units = \'mins\',     class = \'difftime\')), .Names = \'x\');"+
-			"do.call(\'format.difftime\', argv)");
-	}
+    @Test
+    public void testformatdifftime1() {
+        assertEval("argv <- structure(list(x = structure(c(0, 30, 60), units = \'mins\',     class = \'difftime\')), .Names = \'x\');" + "do.call(\'format.difftime\', argv)");
+    }
 
 }
-
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinmeandifftime.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinmeandifftime.java
index 0ae491d2ebb48ee70ae7385d2b9c05dcd0449ec2..5beb0d33aa30182fef9694cae64c438ff58a8f51 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinmeandifftime.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinmeandifftime.java
@@ -2,9 +2,9 @@
  * This material is distributed under the GNU General Public License
  * Version 2. You may review the terms of this license at
  * http://www.gnu.org/licenses/gpl-2.0.html
- * 
+ *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
  * All rights reserved.
  */
 package com.oracle.truffle.r.test.testrgen;
@@ -15,14 +15,12 @@ import com.oracle.truffle.r.test.*;
 
 // Checkstyle: stop line length check
 
-                                                                 public class TestrGenBuiltinmeandifftime extends TestBase {
+public class TestrGenBuiltinmeandifftime extends TestBase {
 
-	@Test
-    @Ignore
-	public void testmeandifftime1() {
-		assertEval("argv <- structure(list(x = structure(c(31, NA, NA, 31), units = \'days\',     class = \'difftime\'), na.rm = TRUE), .Names = c(\'x\', \'na.rm\'));"+
-			"do.call(\'mean.difftime\', argv)");
-	}
+    @Test
+    public void testmeandifftime1() {
+        assertEval("argv <- structure(list(x = structure(c(31, NA, NA, 31), units = \'days\',     class = \'difftime\'), na.rm = TRUE), .Names = c(\'x\', \'na.rm\'));"
+                        + "do.call(\'mean.difftime\', argv)");
+    }
 
 }
-
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinoperators.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinoperators.java
index 33bdda04429aee20b2e12650cf8b31164ae4afd8..94c8ab02fdbea80afea324aea1ca160d2489ef09 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinoperators.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/testrgen/TestrGenBuiltinoperators.java
@@ -912,7 +912,6 @@ public class TestrGenBuiltinoperators extends TestBase {
     }
 
     @Test
-    @Ignore
     public void testoperators169() {
         assertEval("argv <- list(structure(1:3, .Label = c(\'1\', \'2\', NA), class = \'factor\'), structure(1:3, .Label = c(\'1\', \'2\', NA), class = \'factor\'));`!=`(argv[[1]],argv[[2]]);");
     }
@@ -1667,7 +1666,6 @@ public class TestrGenBuiltinoperators extends TestBase {
     }
 
     @Test
-    @Ignore
     public void testoperators314() {
         assertEval("argv <- list(structure(120L, class = \'octmode\'), \'644\');`|`(argv[[1]],argv[[2]]);");
     }
@@ -1828,7 +1826,6 @@ public class TestrGenBuiltinoperators extends TestBase {
     }
 
     @Test
-    @Ignore
     public void testoperators343() {
         assertEval("argv <- list(structure(508L, class = \'octmode\'), \'755\');`&`(argv[[1]],argv[[2]]);");
     }
diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides
index d4326de562b53dba84eb39cb0a03f2ad396459a5..2340747b25a217a99783a97c5c4039508750a40f 100644
--- a/mx.fastr/copyrights/overrides
+++ b/mx.fastr/copyrights/overrides
@@ -46,17 +46,10 @@ com.oracle.truffle.r.native/library/utils/src/utils.h,no.copyright
 com.oracle.truffle.r.native/library/utils/src/init.c,no.copyright
 com.oracle.truffle.r.native/run/R.sh,gnu_r.copyright
 com.oracle.truffle.r.native/run/Rscript.sh,gnu_r.copyright
-com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/BinaryOpsGroupDispatchNode.java,purdue.copyright
-com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/DispatchNode.java,purdue.copyright
-com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/DispatchedCallNode.java,purdue.copyright
+com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java,purdue.copyright
 com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GroupDispatchNode.java,purdue.copyright
-com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GroupDispatchCallNode.java,purdue.copyright
-com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/NextMethodDispatchNode.java,purdue.copyright
-com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/OpsGroupDispatchNode.java,purdue.copyright
-com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3DispatchNode.java,purdue.copyright
-com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3MethodDispatch.java,purdue.copyright
-com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UnaryOpsGroupDispatchNode.java,purdue.copyright
-com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodDispatchNode.java,purdue.copyright
+com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/S3FunctionLookupNode.java,purdue.copyright
+com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodInternalNode.java,purdue.copyright
 com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/CastTypeNode.java,purdue.copyright
 com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/runtime/RASTDeparse.java,gnu_r.copyright
 com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/IsFactorNode.java,purdue.copyright
@@ -80,7 +73,6 @@ com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/E
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java,gnu_r.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ForeignFunctions.java,gnu_r.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetClass.java,purdue.copyright
-com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NextMethod.java,purdue.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Inherits.java,purdue.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsArray.java,purdue.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LoadFunctions.java,gnu_r_gentleman_ihaka.copyright
@@ -92,6 +84,7 @@ com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/P
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RepeatLength.java,purdue.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RowMeans.java,purdue.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RowSums.java,purdue.copyright
+com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/S3DispatchFunctions.java,purdue.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Sample.java,gnu_r_sample.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Scan.java,gnu_r_scan.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java,purdue.copyright
@@ -101,7 +94,6 @@ com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/U
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java,purdue.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java,purdue.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java,purdue.copyright
-com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UseMethod.java,purdue.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java,purdue.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Switch.java,purdue.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Format.java,gnu_r.copyright
diff --git a/mx.fastr/imports b/mx.fastr/imports
index 068dca2910c7a26c9d222fc3cb97a43548e99257..c8508b52a6b231e591a2ec8858e4b56686282ede 100644
--- a/mx.fastr/imports
+++ b/mx.fastr/imports
@@ -1 +1 @@
-graal,575d7607f827484827e290d7a8143ce919fdca37,http://hg.openjdk.java.net/graal/graal
+graal,9912bc54ec0fe2a9667a9fb31eee8c156f9a439d,http://hg.openjdk.java.net/graal/graal