diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
index 1ce4dba99c396ca5e9a4bb6923dca210d8f7c020..d3871d27be24f6105aa6adb51ee81c45046fd98b 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
@@ -116,6 +116,8 @@ import com.oracle.truffle.r.nodes.builtin.fastr.FastRTree;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRTreeNodeGen;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRTreeStats;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRTreeStatsNodeGen;
+import com.oracle.truffle.r.nodes.builtin.fastr.FastRTry;
+import com.oracle.truffle.r.nodes.builtin.fastr.FastRTryNodeGen;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastrDqrls;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastrDqrlsNodeGen;
 import com.oracle.truffle.r.nodes.unary.UnaryNotNode;
@@ -344,6 +346,7 @@ public class BasePackage extends RBuiltinPackage {
         add(FastrDqrls.class, FastrDqrlsNodeGen::create);
         add(FastRDebug.class, FastRDebugNodeGen::create);
         add(FastRIdentity.class, FastRIdentityNodeGen::create);
+        add(FastRTry.class, FastRTryNodeGen::create);
         add(FastRInspect.class, FastRInspectNodeGen::create);
         add(FastRInterop.Eval.class, FastRInteropFactory.EvalNodeGen::create);
         add(FastRInterop.Export.class, FastRInteropFactory.ExportNodeGen::create);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java
index d09327df33adcbcc37d12ec61d6e45381f840780..f1a329fcac628d268a1adc5fe061ed14f7e8df4c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java
@@ -111,32 +111,50 @@ public abstract class Identical extends RBuiltinNode {
     @SuppressWarnings("unused")
     @Specialization(guards = "isRNull(x) || isRNull(y)")
     protected byte doInternalIdenticalNull(Object x, Object y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment) {
-        return x == y ? RRuntime.LOGICAL_TRUE : RRuntime.LOGICAL_FALSE;
+        return RRuntime.asLogical(x == y);
     }
 
     @SuppressWarnings("unused")
     @Specialization(guards = "isRMissing(x) || isRMissing(y)")
     protected byte doInternalIdenticalMissing(Object x, Object y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment) {
-        return x == y ? RRuntime.LOGICAL_TRUE : RRuntime.LOGICAL_FALSE;
+        return RRuntime.asLogical(x == y);
     }
 
     @SuppressWarnings("unused")
     @Specialization
     protected byte doInternalIdentical(byte x, byte y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment) {
-        return x == y ? RRuntime.LOGICAL_TRUE : RRuntime.LOGICAL_FALSE;
+        return RRuntime.asLogical(x == y);
     }
 
     @SuppressWarnings("unused")
     @Specialization
     protected byte doInternalIdentical(String x, String y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment) {
-        return x.equals(y) ? RRuntime.LOGICAL_TRUE : RRuntime.LOGICAL_FALSE;
+        return RRuntime.asLogical(x.equals(y));
     }
 
     @SuppressWarnings("unused")
     @Specialization
     protected byte doInternalIdentical(double x, double y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment) {
-        boolean truth = numEq ? x == y : Double.doubleToRawLongBits(x) == Double.doubleToRawLongBits(y);
-        return truth ? RRuntime.LOGICAL_TRUE : RRuntime.LOGICAL_FALSE;
+        if (singleNA) {
+            if (RRuntime.isNA(x)) {
+                return RRuntime.asLogical(RRuntime.isNA(y));
+            } else if (RRuntime.isNA(y)) {
+                return RRuntime.LOGICAL_FALSE;
+            } else if (Double.isNaN(x)) {
+                return RRuntime.asLogical(Double.isNaN(y));
+            } else if (Double.isNaN(y)) {
+                return RRuntime.LOGICAL_FALSE;
+            }
+        }
+        if (numEq) {
+            if (!singleNA) {
+                if (Double.isNaN(x) || Double.isNaN(y)) {
+                    return RRuntime.asLogical(Double.doubleToRawLongBits(x) == Double.doubleToRawLongBits(y));
+                }
+            }
+            return RRuntime.asLogical(x == y);
+        }
+        return RRuntime.asLogical(Double.doubleToRawLongBits(x) == Double.doubleToRawLongBits(y));
     }
 
     private byte identicalAttr(RAttributable x, RAttributable y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment) {
@@ -182,14 +200,14 @@ public abstract class Identical extends RBuiltinNode {
     @Specialization
     protected byte doInternalIdentical(REnvironment x, REnvironment y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment) {
         // reference equality for environments
-        return x == y ? RRuntime.LOGICAL_TRUE : RRuntime.LOGICAL_FALSE;
+        return RRuntime.asLogical(x == y);
     }
 
     @SuppressWarnings("unused")
     @Specialization
     protected byte doInternalIdentical(RSymbol x, RSymbol y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment) {
         assert Utils.isInterned(x.getName()) && Utils.isInterned(y.getName());
-        return x.getName() == y.getName() ? RRuntime.LOGICAL_TRUE : RRuntime.LOGICAL_FALSE;
+        return RRuntime.asLogical(x.getName() == y.getName());
     }
 
     @Specialization
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTry.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTry.java
new file mode 100644
index 0000000000000000000000000000000000000000..071ef08d2a93304f80ef7f32d0c3661722fef431
--- /dev/null
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTry.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+package com.oracle.truffle.r.nodes.builtin.fastr;
+
+import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
+import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
+
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.frame.FrameSlot;
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.r.nodes.access.FrameSlotNode;
+import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.nodes.function.RCallBaseNode;
+import com.oracle.truffle.r.nodes.function.RCallNode;
+import com.oracle.truffle.r.runtime.RRuntime;
+import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
+import com.oracle.truffle.r.runtime.data.RFunction;
+
+/**
+ * Allows to be 100% robust even in the case of FastR errors like runtime exceptions. The argument
+ * must be a single parameter-less function. The return value is true on success, otherwise error
+ * message.
+ */
+@RBuiltin(name = ".fastr.try", kind = PRIMITIVE, parameterNames = {""}, behavior = COMPLEX)
+public abstract class FastRTry extends RBuiltinNode {
+    private final Object argsIdentifier = new Object();
+    @Child private RCallBaseNode call = RCallNode.createExplicitCall(argsIdentifier);
+    @Child private FrameSlotNode slot = FrameSlotNode.createTemp(argsIdentifier, true);
+
+    @Specialization
+    public Object tryFunc(VirtualFrame frame, RFunction func) {
+        FrameSlot frameSlot = slot.executeFrameSlot(frame);
+        try {
+            frame.setObject(frameSlot, RArgsValuesAndNames.EMPTY);
+            call.execute(frame, func);
+        } catch (Throwable ex) {
+            return String.format("Exception %s, message: %s", ex.getClass().getSimpleName(), ex.getMessage());
+        } finally {
+            frame.setObject(frameSlot, null);
+        }
+        return RRuntime.LOGICAL_TRUE;
+    }
+}
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 091a74bf33a0039c83ba9da968ebbd63b7efaf81..0511c8d585f61a5d9907da2693d1cd95b17c2ce7 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
@@ -22205,6 +22205,70 @@ attr(,"Rd_tag")
 #x <- 1; y <- 1; attr(x, "f") <- 2; attr(x, "g") <- 1; attr(y, "g") <- 1; attr(y, "f") <- 2; identical(x, y)
 [1] TRUE
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testDoubles#
+#identical(0/-1, NaN, num.eq=F, single.NA=F)
+[1] FALSE
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testDoubles#
+#identical(0/-1, NaN, num.eq=F, single.NA=T)
+[1] FALSE
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testDoubles#
+#identical(0/-1, NaN, num.eq=T, single.NA=F)
+[1] FALSE
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testDoubles#
+#identical(0/-1, NaN, num.eq=T, single.NA=T)
+[1] FALSE
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testDoubles#
+#identical(0/0, NaN, num.eq=F, single.NA=F)
+[1] FALSE
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testDoubles#
+#identical(0/0, NaN, num.eq=F, single.NA=T)
+[1] TRUE
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testDoubles#
+#identical(0/0, NaN, num.eq=T, single.NA=F)
+[1] FALSE
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testDoubles#
+#identical(0/0, NaN, num.eq=T, single.NA=T)
+[1] TRUE
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testDoubles#
+#identical(NA, NA, num.eq=F, single.NA=F)
+[1] TRUE
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testDoubles#
+#identical(NA, NA, num.eq=F, single.NA=T)
+[1] TRUE
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testDoubles#
+#identical(NA, NA, num.eq=T, single.NA=F)
+[1] TRUE
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testDoubles#
+#identical(NA, NA, num.eq=T, single.NA=T)
+[1] TRUE
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testDoubles#
+#identical(NaN, NaN, num.eq=F, single.NA=F)
+[1] TRUE
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testDoubles#
+#identical(NaN, NaN, num.eq=F, single.NA=T)
+[1] TRUE
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testDoubles#
+#identical(NaN, NaN, num.eq=T, single.NA=F)
+[1] TRUE
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testDoubles#
+#identical(NaN, NaN, num.eq=T, single.NA=T)
+[1] TRUE
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testIdentical#Ignored.ImplementationError#
 #{ f1 <- function() {}; f2 <- function() {}; identical(f1, f2) }
 [1] FALSE
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_identical.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_identical.java
index 86e31f2ae4c3f25e469ed2ca906d821807ffb256..6811de383289d6f4fd895805930c125ee5e77f33 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_identical.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_identical.java
@@ -263,4 +263,13 @@ public class TestBuiltin_identical extends TestBase {
         assertEval(Ignored.ImplementationError, "{ identical(function() 42, function() 42) }");
 
     }
+
+    @Test
+    public void testDoubles() {
+        assertEval(template("identical(%0, num.eq=%1, single.NA=%2)", new String[][]{
+                        new String[]{"NA, NA", "NaN, NaN", "0/0, NaN", "0/-1, NaN"},
+                        new String[]{"T", "F"},
+                        new String[]{"T", "F"}
+        }));
+    }
 }