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
index cbbb234aaf098b800b6c815bb94cb655b696b8af..650ab72158da049cc6119b59bdd5d7a7f471fade 100644
--- 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
@@ -27,7 +27,6 @@ import com.oracle.truffle.r.nodes.access.variables.LocalReadVariableNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.function.CallMatcherNode;
 import com.oracle.truffle.r.nodes.function.ClassHierarchyNode;
-import com.oracle.truffle.r.nodes.function.ClassHierarchyNodeGen;
 import com.oracle.truffle.r.nodes.function.PromiseHelperNode;
 import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseCheckHelperNode;
 import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode;
@@ -96,7 +95,7 @@ public abstract class S3DispatchFunctions {
          * ignored and a warning is generated.
          */
 
-        @Child private ClassHierarchyNode classHierarchyNode = ClassHierarchyNodeGen.create(true, true);
+        @Child private ClassHierarchyNode classHierarchyNode = ClassHierarchyNode.createForDispatch(true);
         @Child private PromiseCheckHelperNode promiseCheckHelper;
         @Child private Helper helper = new Helper(false);
 
@@ -294,7 +293,7 @@ public abstract class S3DispatchFunctions {
             }
             if (hierarchy == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                hierarchy = insert(ClassHierarchyNode.createWithImplicit());
+                hierarchy = insert(ClassHierarchyNode.createForDispatch(false));
             }
             return hierarchy.execute(arg);
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java
index d5d8e0ad914e3e3c63f99e54fdf451f147224c65..1d8fccff965444f3ffc3f9f100a442e4dfab6db3 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java
@@ -136,7 +136,7 @@ public abstract class AccessSlotNode extends RBaseNode {
                     @Cached("create()") GetClassAttributeNode getClassNode) {
         RStringVector classAttr = getClassNode.getClassAttr(object);
         if (classAttr == null) {
-            RStringVector implicitClassVec = ImplicitClassHierarchyNode.getImplicitClass(object);
+            RStringVector implicitClassVec = ImplicitClassHierarchyNode.getImplicitClass(object, false);
             assert implicitClassVec.getLength() > 0;
             throw RError.error(this, RError.Message.SLOT_BASIC_CLASS, name, implicitClassVec.getDataAt(0));
         } else {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java
index 6a51aee479340ec59fb5b49bf3c6818c11f65971..7e8564b4ecffa5f5b5fb7e88e6c2c72bb18df1fd 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java
@@ -37,6 +37,7 @@ import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNa
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode;
+import com.oracle.truffle.r.nodes.function.PromiseHelperNode;
 import com.oracle.truffle.r.nodes.profile.AlwaysOnBranchProfile;
 import com.oracle.truffle.r.nodes.profile.VectorLengthProfile;
 import com.oracle.truffle.r.runtime.RError;
@@ -49,6 +50,7 @@ import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RLogical;
 import com.oracle.truffle.r.runtime.data.RNull;
+import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RString;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RTypedValue;
@@ -86,6 +88,7 @@ final class CachedExtractVectorNode extends CachedVectorNode {
     @Child private ExtractDimNamesNode extractDimNames;
 
     private final ConditionProfile resultHasDimensions = ConditionProfile.createBinaryProfile();
+    private final ConditionProfile promiseInEnvironment = ConditionProfile.createBinaryProfile();
 
     /**
      * Profile if any metadata was applied at any point in time. This is useful extract primitive
@@ -254,6 +257,9 @@ final class CachedExtractVectorNode extends CachedVectorNode {
         String positionString = tryCastSingleString(positionsCheckNode, positions);
         if (positionString != null) {
             Object obj = env.get(positionString);
+            if (promiseInEnvironment.profile(obj instanceof RPromise)) {
+                obj = PromiseHelperNode.evaluateSlowPath(null, (RPromise) obj);
+            }
             return obj == null ? RNull.instance : obj;
         }
         throw error(RError.Message.WRONG_ARGS_SUBSET_ENV);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/InternalNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/InternalNode.java
index 7fceec433df39e63feb9c9b22ecee7b34d0a9d07..7b9821cf939a82abfaf28afd57fa7eda7a5fad15 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/InternalNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/InternalNode.java
@@ -43,6 +43,7 @@ import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.REmpty;
 import com.oracle.truffle.r.runtime.data.RFunction;
+import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.nodes.RBaseNode;
 import com.oracle.truffle.r.runtime.nodes.RNode;
@@ -245,6 +246,7 @@ public abstract class InternalNode extends OperatorNode {
             Object[] args = new Object[arguments.length];
             for (int i = 0; i < args.length; i++) {
                 args[i] = arguments[i].execute(frame);
+                assert !(args[i] instanceof RPromise);
             }
             return args;
         }
@@ -273,6 +275,7 @@ public abstract class InternalNode extends OperatorNode {
                     value = forcePromises(frame, (RArgsValuesAndNames) value);
                 }
                 args[i] = value;
+                assert !(args[i] instanceof RPromise);
             }
             return args;
         }
@@ -281,6 +284,7 @@ public abstract class InternalNode extends OperatorNode {
             Object[] array = new Object[varArgs.getLength()];
             for (int i = 0; i < array.length; i++) {
                 array[i] = promiseHelper.checkEvaluate(frame, varArgs.getArgument(i));
+                assert !(array[i] instanceof RPromise);
             }
             return new RArgsValuesAndNames(array, varArgs.getSignature());
         }
@@ -303,10 +307,12 @@ public abstract class InternalNode extends OperatorNode {
 
             for (int i = 0; i < args.length - 1; i++) {
                 args[i] = arguments[i].execute(frame);
+                assert !(args[i] instanceof RPromise);
             }
             Object[] varArgs = new Object[arguments.length - (factory.getSignature().getLength() - 1)];
             for (int i = 0; i < varArgs.length; i++) {
                 varArgs[i] = arguments[args.length - 1 + i].execute(frame);
+                assert !(varArgs[i] instanceof RPromise);
             }
             args[args.length - 1] = new RArgsValuesAndNames(varArgs, ArgumentsSignature.empty(varArgs.length));
             return args;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java
index 29c1453ada068b616d66acff9b7c3d097a92095e..3400150763e1a8d057b8f1d9b6ccda5526c2028c 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java
@@ -67,7 +67,7 @@ public abstract class ClassHierarchyNode extends UnaryNode {
         RStringVector result = null;
         if (value instanceof RAttributable) {
             Object v = ((RAttributable) value).getAttr(RRuntime.CLASS_ATTR_KEY);
-            result = v instanceof RStringVector ? (RStringVector) v : ImplicitClassHierarchyNode.getImplicitClass(value);
+            result = v instanceof RStringVector ? (RStringVector) v : ImplicitClassHierarchyNode.getImplicitClass(value, false);
         }
 
         return result != null ? result : RDataFactory.createEmptyStringVector();
@@ -95,13 +95,20 @@ public abstract class ClassHierarchyNode extends UnaryNode {
 
     private final boolean withImplicitTypes;
     private final boolean withS4;
+    private final boolean forDispatch;
     private final ConditionProfile noAttributesProfile = ConditionProfile.createBinaryProfile();
     private final ConditionProfile nullAttributeProfile = ConditionProfile.createBinaryProfile();
     private final ConditionProfile isS4Profile = ConditionProfile.createBinaryProfile();
 
-    protected ClassHierarchyNode(boolean withImplicitTypes, boolean withS4) {
+    protected ClassHierarchyNode(boolean withImplicitTypes, boolean withS4, boolean forDispatch) {
+        assert !forDispatch || withImplicitTypes : "forDispatch requires withImplicitTypes";
         this.withImplicitTypes = withImplicitTypes;
         this.withS4 = withS4;
+        this.forDispatch = forDispatch;
+    }
+
+    protected ClassHierarchyNode(boolean withImplicitTypes, boolean withS4) {
+        this(withImplicitTypes, withS4, false);
     }
 
     public static ClassHierarchyNode create() {
@@ -112,51 +119,60 @@ public abstract class ClassHierarchyNode extends UnaryNode {
         return ClassHierarchyNodeGen.create(true, false);
     }
 
+    /*
+     * Creates node that return result, which is meant to be used for S3 dispatch, in such case the
+     * "numeric" class will be preceeded by "integer" or "double" classes. This seems to be not used
+     * anywhere else than for the dispatch.
+     */
+    public static ClassHierarchyNode createForDispatch(boolean withS4) {
+        return ClassHierarchyNodeGen.create(true, withS4, true);
+    }
+
     public abstract RStringVector execute(Object arg);
 
     @Specialization
     protected RStringVector getClassHr(@SuppressWarnings("unused") byte arg) {
-        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Logical) : null;
+        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Logical, forDispatch) : null;
     }
 
     @Specialization
     protected RStringVector getClassHr(@SuppressWarnings("unused") String arg) {
-        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Character) : null;
+        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Character, forDispatch) : null;
     }
 
     @Specialization
     protected RStringVector getClassHr(@SuppressWarnings("unused") int arg) {
-        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Integer) : null;
+        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Integer, forDispatch) : null;
     }
 
     @Specialization
     protected RStringVector getClassHr(@SuppressWarnings("unused") double arg) {
-        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Double) : null;
+        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Double, forDispatch) : null;
     }
 
     @Specialization
     protected RStringVector getClassHr(@SuppressWarnings("unused") RComplex arg) {
-        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Complex) : null;
+        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Complex, forDispatch) : null;
     }
 
     @Specialization
     protected RStringVector getClassHr(@SuppressWarnings("unused") RRaw arg) {
-        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Raw) : null;
+        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Raw, forDispatch) : null;
     }
 
     @Specialization
     protected RStringVector getClassHr(@SuppressWarnings("unused") RNull arg) {
-        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Null) : null;
+        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Null, forDispatch) : null;
     }
 
     @Specialization
     protected RStringVector getClassHr(@SuppressWarnings("unused") RInteropScalar arg) {
-        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(arg.getRType()) : null;
+        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(arg.getRType(), forDispatch) : null;
     }
 
     @Specialization
     protected RStringVector getClassHr(@SuppressWarnings("unused") REmpty arg) {
-        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Null) : null;
+        return withImplicitTypes ? ImplicitClassHierarchyNode.getImplicitClass(RType.Null, forDispatch) : null;
     }
 
     @Specialization
@@ -194,7 +210,7 @@ public abstract class ClassHierarchyNode extends UnaryNode {
         if (withImplicitTypes) {
             if (implicit == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                implicit = insert(ImplicitClassHierarchyNodeGen.create());
+                implicit = insert(ImplicitClassHierarchyNodeGen.create(forDispatch));
             }
             return implicit.execute(arg);
         } else {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ImplicitClassHierarchyNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ImplicitClassHierarchyNode.java
index 88e4949d7df687b0ce6a2ed613a15f299f2cf969..11da7440437b0245aadd3e2767eeffd3be4f1359 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ImplicitClassHierarchyNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ImplicitClassHierarchyNode.java
@@ -43,9 +43,24 @@ public abstract class ImplicitClassHierarchyNode extends UnaryNode {
 
     private static final RStringVector implicitArrayClass = ShareObjectNode.sharePermanent(RDataFactory.createStringVector("array"));
     private static final RStringVector implicitMatrixClass = ShareObjectNode.sharePermanent(RDataFactory.createStringVector("matrix"));
+    private static final RStringVector dispatchDoubleImplicitClass = ShareObjectNode.sharePermanent(RDataFactory.createStringVector(new String[]{"double", "numeric"}, RDataFactory.COMPLETE_VECTOR));
+    private static final RStringVector dispatchIntegerImplicitClass = ShareObjectNode.sharePermanent(RDataFactory.createStringVector(new String[]{"integer", "numeric"}, RDataFactory.COMPLETE_VECTOR));
     @CompilationFinal(dimensions = 1) private static final RStringVector[] implicitClasses = new RStringVector[RType.values().length];
 
-    public static RStringVector getImplicitClass(RType type) {
+    private final boolean forDispatch;
+
+    protected ImplicitClassHierarchyNode(boolean forDispatch) {
+        this.forDispatch = forDispatch;
+    }
+
+    public static RStringVector getImplicitClass(RType type, boolean forDispatch) {
+        if (forDispatch) {
+            if (type == RType.Double) {
+                return dispatchDoubleImplicitClass;
+            } else if (type == RType.Integer) {
+                return dispatchIntegerImplicitClass;
+            }
+        }
         RStringVector result = implicitClasses[type.ordinal()];
         if (result == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -57,27 +72,27 @@ public abstract class ImplicitClassHierarchyNode extends UnaryNode {
     public abstract RStringVector execute(Object arg);
 
     @Specialization
-    protected static RStringVector get(@SuppressWarnings("unused") int value) {
-        return getImplicitClass(RType.Integer);
+    protected RStringVector get(@SuppressWarnings("unused") int value) {
+        return getImplicitClass(RType.Integer, forDispatch);
     }
 
     @Specialization
-    protected static RStringVector get(@SuppressWarnings("unused") double value) {
-        return getImplicitClass(RType.Double);
+    protected RStringVector get(@SuppressWarnings("unused") double value) {
+        return getImplicitClass(RType.Double, forDispatch);
     }
 
     @Specialization
-    protected static RStringVector get(@SuppressWarnings("unused") String value) {
-        return getImplicitClass(RType.Character);
+    protected RStringVector get(@SuppressWarnings("unused") String value) {
+        return getImplicitClass(RType.Character, forDispatch);
     }
 
     @Specialization
-    protected static RStringVector get(@SuppressWarnings("unused") byte value) {
-        return getImplicitClass(RType.Logical);
+    protected RStringVector get(@SuppressWarnings("unused") byte value) {
+        return getImplicitClass(RType.Logical, forDispatch);
     }
 
     @Specialization(limit = "5", guards = "value.getClass() == valueClass")
-    protected static RStringVector getCachedClass(RTypedValue value,
+    protected RStringVector getCachedClass(RTypedValue value,
                     @Cached("value.getClass()") Class<? extends RTypedValue> valueClass,
                     @Cached("createBinaryProfile()") ConditionProfile isArray,
                     @Cached("createBinaryProfile()") ConditionProfile isMatrix,
@@ -86,7 +101,7 @@ public abstract class ImplicitClassHierarchyNode extends UnaryNode {
     }
 
     @Specialization(replaces = "getCachedClass", limit = "5", guards = "value.getRType() == type")
-    protected static RStringVector getCachedType(RTypedValue value,
+    protected RStringVector getCachedType(RTypedValue value,
                     @Cached("value.getRType()") RType type,
                     @Cached("createBinaryProfile()") ConditionProfile isArray,
                     @Cached("createBinaryProfile()") ConditionProfile isMatrix,
@@ -97,28 +112,28 @@ public abstract class ImplicitClassHierarchyNode extends UnaryNode {
         } else if (isArray.profile(GetDimAttributeNode.isArray(dimensions))) {
             return implicitArrayClass;
         } else {
-            return getImplicitClass(type);
+            return getImplicitClass(type, forDispatch);
         }
     }
 
     @Specialization(replaces = {"getCachedClass", "getCachedType"})
-    protected static RStringVector get(RTypedValue value,
+    protected RStringVector get(RTypedValue value,
                     @Cached("createBinaryProfile()") ConditionProfile isArray,
                     @Cached("createBinaryProfile()") ConditionProfile isMatrix,
                     @Cached("create()") GetDimAttributeNode getDim) {
         return getCachedType(value, value.getRType(), isArray, isMatrix, getDim);
     }
 
-    public static RStringVector getImplicitClass(Object value) {
+    public static RStringVector getImplicitClass(Object value, boolean forDispatch) {
         CompilerAsserts.neverPartOfCompilation();
         if (value instanceof Integer) {
-            return getImplicitClass(RType.Integer);
+            return getImplicitClass(RType.Integer, forDispatch);
         } else if (value instanceof Double) {
-            return getImplicitClass(RType.Double);
+            return getImplicitClass(RType.Double, forDispatch);
         } else if (value instanceof String) {
-            return getImplicitClass(RType.Character);
+            return getImplicitClass(RType.Character, forDispatch);
         } else if (value instanceof Byte) {
-            return getImplicitClass(RType.Logical);
+            return getImplicitClass(RType.Logical, forDispatch);
         } else if (value instanceof RAttributable) {
             RAttributable attributable = (RAttributable) value;
             RIntVector dim = (RIntVector) attributable.getAttr(RRuntime.DIM_ATTR_KEY);
@@ -131,6 +146,6 @@ public abstract class ImplicitClassHierarchyNode extends UnaryNode {
                 }
             }
         }
-        return getImplicitClass(((RTypedValue) value).getRType());
+        return getImplicitClass(((RTypedValue) value).getRType(), forDispatch);
     }
 }
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 ad6a7f6d381ca1e8949a34b3864d8283eab9cbc3..78cd51bfc5abb28cd3a220a3ed4a84150c667475 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
@@ -77395,6 +77395,13 @@ $named$e
 
 
 
+##com.oracle.truffle.r.test.functions.TestS3Dispatch.runRSourceTests#
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/functions/S3/R/numericTypes.R") }
+integer
+double
+logical
+default
+
 ##com.oracle.truffle.r.test.functions.TestS3Dispatch.testComplexGroupDispatch#
 #{x<--7+2i;class(x)<-"foo";Complex.foo<-function(z){1;};Im(x);}
 [1] 1
@@ -78617,6 +78624,14 @@ Error in rm("foo", envir = baseenv()) :
 #{ x <- 1; lockBinding("x", globalenv()); x <- 1 }
 Error: cannot change value of locked binding for 'x'
 
+##com.oracle.truffle.r.test.library.base.TestEnvironments.testFrameToEnv#
+#{ makefun <- function(f) function(a) f(a); .Internal(islistfactor(environment(makefun(function(b) 2*b))$f, F)); }
+[1] FALSE
+
+##com.oracle.truffle.r.test.library.base.TestEnvironments.testFrameToEnv#
+#{ makefun <- function(f,s) function(a) f(a); s <- function() cat('side effect'); .Internal(islistfactor(environment(makefun(function(b) 2*b, s()))$f, F)); }
+[1] FALSE
+
 ##com.oracle.truffle.r.test.library.base.TestEnvironments.testFrames#
 #{ t1 <- function() {  aa <- 1; t2 <- function() { cat("current frame is", sys.nframe(), "; "); cat("parents are frame numbers", sys.parents(), "; "); print(ls(envir = sys.frame(-1))) };  t2() }; t1() }
 current frame is 2 ; parents are frame numbers 0 1 ; [1] "aa" "t2"
@@ -130688,7 +130703,7 @@ Error in attr(to, "a") <- "a" : external object cannot be attributed
 #if (length(grep("FastR", R.Version()$version.string)) != 1) { cat('Error in attr(to, which = "a") : external object cannot be attributed<<<NEWLINE>>>') } else { to <- .fastr.interop.new(.fastr.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass')); attr(to, which = 'a') }
 Error in attr(to, which = "a") : external object cannot be attributed
 
-##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testClassAsParameter#
+##com.oracle.truffle.r.test.library.fastr.TestJavaInterop.testClassAsParameter#Ignored.ImplementationError#
 #if (length(grep("FastR", R.Version()$version.string)) != 1) { "com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass" } else { tc <- .fastr.java.class('com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass'); t <- .fastr.interop.new(tc); t$classAsArg(tc) }
 [1] "com.oracle.truffle.r.test.library.fastr.TestJavaInterop$TestClass"
 
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/functions/S3/R/numericTypes.R b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/functions/S3/R/numericTypes.R
new file mode 100644
index 0000000000000000000000000000000000000000..839f61e27ca93de48854330011a291cb241eb1b5
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/functions/S3/R/numericTypes.R
@@ -0,0 +1,30 @@
+# Copyright (c) 2013, 2016, 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.
+foo <- function(x) UseMethod('foo')
+foo.integer <- function(x) 'integer'
+foo.double <- function(x) 'double'
+foo.logical <- function(x) 'logical'
+foo.numeric <- function(x) 'numeric'
+foo.default <- function(x) 'default'
+cat(foo(1L), "\n")
+cat(foo(3.14), "\n")
+cat(foo(T), "\n")
+cat(foo(quote(a)), "\n")
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestEnvironments.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestEnvironments.java
index 44ac9c7cfa00022ca8a01c1cd5293600ad42b13c..31bbd86d488af757a81cc21e81cce170db3c3cf0 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestEnvironments.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestEnvironments.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2012-2014, Purdue University
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -285,4 +285,12 @@ public class TestEnvironments extends TestBase {
         assertEval("{ e <- new.env(); assign(\"x\", 1, e); attach(e, 2); x; detach(2); x }");
         assertEval("{ detach(\"missing\"); x }");
     }
+
+    @Test
+    public void testFrameToEnv() {
+        // Note: islistfactor is internal and should fail if it gets promise directly
+        assertEval("{ makefun <- function(f) function(a) f(a); .Internal(islistfactor(environment(makefun(function(b) 2*b))$f, F)); }");
+        // Turning frame into an environment should not evaluate all the promises:
+        assertEval("{ makefun <- function(f,s) function(a) f(a); s <- function() cat('side effect'); .Internal(islistfactor(environment(makefun(function(b) 2*b, s()))$f, F)); }");
+    }
 }