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 a28f47de137f5aa79972bdf9af6aef0b4dae09eb..eda8d1fee8af05be6eb5d8add2d77776f0b80202 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
@@ -33,6 +33,10 @@ import com.oracle.truffle.api.CompilerAsserts;
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.RootCallTarget;
+import com.oracle.truffle.api.frame.Frame;
+import com.oracle.truffle.api.frame.FrameDescriptor;
+import com.oracle.truffle.api.frame.FrameSlot;
+import com.oracle.truffle.api.frame.FrameSlotKind;
 import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.object.DynamicObject;
 import com.oracle.truffle.r.runtime.conn.RConnection;
@@ -71,6 +75,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
+import com.oracle.truffle.r.runtime.env.frame.ActiveBinding;
 import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
 import com.oracle.truffle.r.runtime.ffi.DLL;
 import com.oracle.truffle.r.runtime.gnur.SEXPTYPE;
@@ -115,6 +120,7 @@ public class RSerialize {
         static final int LEVELS_SHIFT = 12;
         static final int CACHED_MASK = 1 << 5;
         static final int HASHASH_MASK = 1;
+        static final int IS_ACTIVE_BINDING_MASK = 1 << 15;
 
         private Flags() {
             // prevent construction
@@ -142,6 +148,10 @@ public class RSerialize {
             return (flagsValue & HAS_TAG_BIT_MASK) != 0;
         }
 
+        public static boolean isActiveBinding(int levs) {
+            return (levs & IS_ACTIVE_BINDING_MASK) != 0;
+        }
+
         public static int packFlags(SEXPTYPE type, int gpbits, boolean isObj, boolean hasAttr, boolean hasTag) {
             int val = type.code;
             int levs = gpbits & (~(CACHED_MASK | HASHASH_MASK));
@@ -490,14 +500,13 @@ public class RSerialize {
                                 if (val == RNull.instance) {
                                     continue;
                                 }
-                                RPairList pl = (RPairList) val;
-                                env.safePut(((RSymbol) pl.getTag()).getName(), pl.car());
+                                safePutToEnv(env, (RPairList) val);
                             }
                         }
                     } else {
                         while (frame != RNull.instance) {
                             RPairList pl = (RPairList) frame;
-                            env.safePut(((RSymbol) pl.getTag()).getName(), pl.car());
+                            safePutToEnv(env, pl);
                             frame = pl.cdr();
                         }
                     }
@@ -534,8 +543,14 @@ public class RSerialize {
                     Object attrItem = RNull.instance;
                     Object tagItem = RNull.instance;
                     if (Flags.hasAttr(flags)) {
+                        // create new language parsing context
+                        int safedLangDepth = langDepth;
+                        langDepth = 0;
                         attrItem = readItem();
 
+                        // restore language parsing context
+                        langDepth = safedLangDepth;
+
                     }
                     if (Flags.hasTag(flags)) {
                         tagItem = readItem();
@@ -622,6 +637,10 @@ public class RSerialize {
                         }
 
                         case LISTSXP:
+                            if (Flags.isActiveBinding(levs)) {
+                                assert carItem instanceof RFunction;
+                                carItem = new ActiveBinding(RType.Any, (RFunction) carItem);
+                            }
                             RPairList pairList = RDataFactory.createPairList(carItem, cdrItem, tagItem, type);
                             result = pairList;
                             if (attrItem != RNull.instance) {
@@ -829,6 +848,17 @@ public class RSerialize {
             return checkResult(result);
         }
 
+        private static void safePutToEnv(REnvironment env, RPairList pl) {
+            String name = ((RSymbol) pl.getTag()).getName();
+            Object car = pl.car();
+            if (ActiveBinding.isActiveBinding(car)) {
+                FrameSlot frameSlot = FrameSlotChangeMonitor.findOrAddFrameSlot(env.getFrame().getFrameDescriptor(), name, FrameSlotKind.Object);
+                FrameSlotChangeMonitor.setActiveBinding(env.getFrame(), frameSlot, (ActiveBinding) car, false, null);
+            } else {
+                env.safePut(name, car);
+            }
+        }
+
         private static Object checkResult(Object result) {
             assert result != null;
             return result;
@@ -1422,7 +1452,7 @@ public class RSerialize {
                          */
                         String[] bindings = env.ls(true, null, false).getDataWithoutCopying();
                         for (String binding : bindings) {
-                            Object value = env.get(binding);
+                            Object value = getValueIgnoreActiveBinding(env.getFrame(), binding);
                             writePairListEntry(binding, value);
                         }
                         terminatePairList();
@@ -1655,6 +1685,16 @@ public class RSerialize {
             } while (tailCall);
         }
 
+        private static Object getValueIgnoreActiveBinding(Frame frame, String key) {
+            FrameDescriptor fd = frame.getFrameDescriptor();
+            FrameSlot slot = fd.findFrameSlot(key);
+            if (slot == null) {
+                return null;
+            } else {
+                return frame.getValue(slot);
+            }
+        }
+
         private Object getPersistentName(Object obj) {
             if (hook == null) {
                 return RNull.instance;
@@ -1728,7 +1768,8 @@ public class RSerialize {
         }
 
         private void writePairListEntry(String name, Object value) throws IOException {
-            stream.writeInt(Flags.packFlags(SEXPTYPE.LISTSXP, 0, false, false, true));
+            boolean isActiveBinding = ActiveBinding.isActiveBinding(value);
+            stream.writeInt(Flags.packFlags(SEXPTYPE.LISTSXP, isActiveBinding ? Flags.IS_ACTIVE_BINDING_MASK : 0, false, false, true));
             RSymbol sym = state.findSymbol(name);
             int refIndex;
             if ((refIndex = getRefIndex(sym)) != -1) {
@@ -1736,7 +1777,11 @@ public class RSerialize {
             } else {
                 writeSymbol(sym);
             }
-            writeItem(value);
+            if (isActiveBinding) {
+                writeItem(((ActiveBinding) value).getFunction());
+            } else {
+                writeItem(value);
+            }
         }
 
         private void writeSymbol(RSymbol name) throws IOException {
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 339c40082612ed69f404d3c2ba5bc212fcaed989..d76ce00c5a4d851e37d926f7ed2e88e5ffa47357 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
@@ -425,6 +425,26 @@ Slots:
 Name:        j
 Class: numeric
 
+##com.oracle.truffle.r.test.S4.TestS4.testClassCreation#
+#{ setClass('foo', contains='standardGeneric'); getClass('foo') }
+Class "foo" [in ".GlobalEnv"]
+
+Slots:
+
+Name:           .Data        generic        package          group
+Class:       function      character      character           list
+
+Name:      valueClass      signature        default       skeleton
+Class:      character      character optionalMethod           call
+
+Extends:
+Class "standardGeneric", directly
+Class "genericFunction", by class "standardGeneric", distance 2
+Class "function", by class "standardGeneric", distance 3
+Class "OptionalFunction", by class "standardGeneric", distance 4
+Class "PossibleMethod", by class "standardGeneric", distance 4
+Class "optionalMethod", by class "standardGeneric", distance 5
+
 ##com.oracle.truffle.r.test.S4.TestS4.testConversions#
 #{  asS4(7:42) }
  [1]  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
@@ -62325,6 +62345,35 @@ Error in seq.int(NaN) : 'from' cannot be NA, NaN or infinite
 #argv <- list(from = 0, to = 0.793110173512391, length.out = FALSE);do.call('seq.int', argv);
 integer(0)
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize#
+#options(keep.source=FALSE); fc <- setClass('FooSerial1', representation(a = 'call')); serialize(fc, connection=NULL)
+  [1] 58 0a 00 00 00 02 00 03 03 02 00 02 03 00 00 01 07 03 00 00 04 02 00 00 00
+ [26] 01 00 04 00 09 00 00 00 09 63 6c 61 73 73 4e 61 6d 65 00 00 02 10 00 00 00
+ [51] 01 00 04 00 09 00 00 00 0a 46 6f 6f 53 65 72 69 61 6c 31 00 00 04 02 00 00
+ [76] 00 01 00 04 00 09 00 00 00 07 70 61 63 6b 61 67 65 00 00 00 10 00 00 00 01
+[101] 00 04 00 09 00 00 00 0a 2e 47 6c 6f 62 61 6c 45 6e 76 00 00 00 fe 00 00 04
+[126] 02 00 00 02 ff 00 00 00 10 00 00 00 01 00 04 00 09 00 00 00 0a 2e 47 6c 6f
+[151] 62 61 6c 45 6e 76 00 00 04 02 00 00 00 01 00 04 00 09 00 00 00 05 63 6c 61
+[176] 73 73 00 00 02 10 00 00 00 01 00 04 00 09 00 00 00 16 63 6c 61 73 73 47 65
+[201] 6e 65 72 61 74 6f 72 46 75 6e 63 74 69 6f 6e 00 00 04 02 00 00 02 ff 00 00
+[226] 00 10 00 00 00 01 00 04 00 09 00 00 00 07 6d 65 74 68 6f 64 73 00 00 00 fe
+[251] 00 00 00 fe 00 00 00 fd 00 00 04 02 00 00 00 01 00 04 00 09 00 00 00 03 2e
+[276] 2e 2e 00 00 00 fb 00 00 00 fe 00 00 00 06 00 00 00 01 00 04 00 09 00 00 00
+[301] 03 6e 65 77 00 00 00 02 00 00 02 10 00 00 00 01 00 04 00 09 00 00 00 0a 46
+[326] 6f 6f 53 65 72 69 61 6c 31 00 00 04 02 00 00 02 ff 00 00 00 10 00 00 00 01
+[351] 00 04 00 09 00 00 00 0a 2e 47 6c 6f 62 61 6c 45 6e 76 00 00 00 fe 00 00 00
+[376] 06 00 00 04 ff 00 00 00 fe
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize#
+#options(keep.source=FALSE); mc <- setClass('FooSerial0', representation(a = 'call')); obj <- new('FooSerial0'); serialize(obj, connection=NULL)
+  [1] 58 0a 00 00 00 02 00 03 03 02 00 02 03 00 00 01 03 19 00 00 04 02 00 00 00
+ [26] 01 00 04 00 09 00 00 00 01 61 00 00 00 06 00 00 00 01 00 04 00 09 00 00 00
+ [51] 07 3c 75 6e 64 65 66 3e 00 00 00 fe 00 00 04 02 00 00 00 01 00 04 00 09 00
+ [76] 00 00 05 63 6c 61 73 73 00 00 02 10 00 00 00 01 00 04 00 09 00 00 00 0a 46
+[101] 6f 6f 53 65 72 69 61 6c 30 00 00 04 02 00 00 00 01 00 04 00 09 00 00 00 07
+[126] 70 61 63 6b 61 67 65 00 00 00 10 00 00 00 01 00 04 00 09 00 00 00 0a 2e 47
+[151] 6c 6f 62 61 6c 45 6e 76 00 00 00 fe 00 00 00 fe
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize#
 #options(keep.source=FALSE); serialize('asdf', connection=NULL)
  [1] 58 0a 00 00 00 02 00 03 03 02 00 02 03 00 00 00 00 10 00 00 00 01 00 04 00
@@ -62759,6 +62808,20 @@ integer(0)
 [51] 00 00 00 01 00 04 00 09 00 00 00 05 6e 61 6d 65 73 00 00 00 10 00 00 00 01
 [76] 00 04 00 09 00 00 00 06 65 6e 63 6c 6f 73 00 00 00 fe
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize#
+#options(keep.source=FALSE); val <- new.env(hash=FALSE); makeActiveBinding('a', function(x) print('hello'), val); data <- serialize(val, connection=NULL); newenv <- unserialize(rawConnection(data)); newenv$a
+[1] "hello"
+[1] "hello"
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize#
+#options(keep.source=FALSE); val <- new.env(hash=FALSE); makeActiveBinding('a', function(x) print('hello'), val); serialize(val, connection=NULL)
+  [1] 58 0a 00 00 00 02 00 03 03 02 00 02 03 00 00 00 00 04 00 00 00 00 00 00 00
+ [26] fd 08 00 04 02 00 00 00 01 00 04 00 09 00 00 00 01 61 00 00 04 03 00 00 00
+ [51] fd 00 00 04 02 00 00 00 01 00 04 00 09 00 00 00 01 78 00 00 00 fb 00 00 00
+ [76] fe 00 00 00 06 00 00 00 01 00 04 00 09 00 00 00 05 70 72 69 6e 74 00 00 00
+[101] 02 00 00 00 10 00 00 00 01 00 04 00 09 00 00 00 05 68 65 6c 6c 6f 00 00 00
+[126] fe 00 00 00 fe 00 00 00 fe 00 00 00 fe
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize#
 #options(keep.source=FALSE); val <- new.env(hash=FALSE); serialize(val, connection=NULL)
  [1] 58 0a 00 00 00 02 00 03 03 02 00 02 03 00 00 00 00 04 00 00 00 00 00 00 00
@@ -62812,6 +62875,13 @@ integer(0)
 [151] 63 6b 61 67 65 00 00 00 10 00 00 00 01 00 04 00 09 00 00 00 0a 2e 47 6c 6f
 [176] 62 61 6c 45 6e 76 00 00 00 fe 00 00 00 fe
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize#
+#{ options(keep.source=FALSE); f <- function() NULL; attributes(f) <- list(skeleton=quote(`<undef>`())); data <- serialize(f, conn=NULL); unserialize(conn=data) }
+function ()
+NULL
+attr(,"skeleton")
+`<undef>`()
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_setEncoding.testsetEncoding1#
 #argv <- list('abc', 'UTF-8'); .Internal(setEncoding(argv[[1]], argv[[2]]))
 [1] "abc"
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/TestS4.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/TestS4.java
index d5cf915d84ec92569f0f9b2bdfa78e0c3a658104..09a616189e15189fd7188d9615be5e467b2a548a 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/TestS4.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/TestS4.java
@@ -103,6 +103,7 @@ public class TestS4 extends TestRBase {
     public void testClassCreation() {
         assertEval("{ setClass(\"foo\", representation(j=\"numeric\")); getClass(\"foo\") }");
         assertEval("{ setClass(\"foo\"); setClass(\"bar\", representation(j = \"numeric\"), contains = \"foo\"); is.null(getClass(\"foo\")@prototype) }");
+        assertEval("{ setClass('foo', contains='standardGeneric'); getClass('foo') }");
     }
 
     @Test
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_serialize.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_serialize.java
index 0679742b3e203e2e39342a53b5ff4a00193b7722..3e031ad10ee498a5d31a0b7b12cf40732aa86c79 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_serialize.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_serialize.java
@@ -101,5 +101,14 @@ public class TestBuiltin_serialize extends TestBase {
         assertEval("options(keep.source=FALSE); val <- new.env(hash=FALSE); val$d <- TRUE; serialize(val, connection=NULL)");
         assertEval("options(keep.source=FALSE); val <- new.env(hash=FALSE); val$e <- 5+9i; serialize(val, connection=NULL)");
         assertEval("options(keep.source=FALSE); val <- new.env(hash=FALSE); val$f <- NA; serialize(val, connection=NULL)");
+
+        // active bindings
+        assertEval("options(keep.source=FALSE); val <- new.env(hash=FALSE); makeActiveBinding('a', function(x) print('hello'), val); serialize(val, connection=NULL)");
+        assertEval("options(keep.source=FALSE); val <- new.env(hash=FALSE); makeActiveBinding('a', function(x) print('hello'), val); data <- serialize(val, connection=NULL); newenv <- unserialize(rawConnection(data)); newenv$a");
+
+        assertEval("options(keep.source=FALSE); mc <- setClass('FooSerial0', representation(a = 'call')); obj <- new('FooSerial0'); serialize(obj, connection=NULL)");
+        assertEval(Ignored.ImplementationError, "options(keep.source=FALSE); fc <- setClass('FooSerial1', representation(a = 'call')); serialize(fc, connection=NULL)");
+
+        assertEval("{ options(keep.source=FALSE); f <- function() NULL; attributes(f) <- list(skeleton=quote(`<undef>`())); data <- serialize(f, conn=NULL); unserialize(conn=data) }");
     }
 }