             encodeString("");
         }
 
-        context.oRef.table[object] = context.oRef.ix ++;
-    }
-
-
-    private static function encodeByteArray (context :Context, bytes :ByteArray) :void
-    {
-        if (context.oRef.table[object] !== undefined) {
-            encodeInteger(context.oRef.table[object] << 1);
+        _ctx.oRef.table[object] = _ctx.oRef.ix ++;
+    }
+
+
+    private static function encodeByteArray (bytes :ByteArray) :void
+    {
+        if (_ctx.oRef.table[bytes] !== undefined) {
+            encodeInteger(_ctx.oRef.table[bytes] << 1);
             return;
         }
 
         // a byte array consists of a 1 bit, followed by the byte count
         encodeInteger(1 | (bytes.length << 1));
         // and then just... all the bytes
-        context.bytes.writeBytes(bytes);
-
-        context.oRef.table[object] = context.oRef.ix ++;
-    }
-}
-}
+        _ctx.bytes.writeBytes(bytes);
+
+        _ctx.oRef.table[bytes] = _ctx.oRef.ix ++;
+    }
+
+    private static var _ctx :Context;
+}
+}
+
+import flash.utils.ByteArray;
+import flash.utils.Dictionary;
 
 class Context
 {

            }
            // if so, just stream them out
            encodeString(String(prop));
            encodeValue(context, arr[prop]);
        }
        encodeString("");

        // finally send the dense values
        for (var ii :int = 0; ii < denseEnd; ii ++) {
            encodeValue(context, arr[ii]);
        }

        context.oRef.table[value] = context.oRef.ix ++;
    }

    private static function encodeObject (context :Context, object :Object) :void
    {
        if (context.oRef.table[object] !== undefined) {
            encodeInteger(context.oRef.table[object] << 1);
            return;
        }

        // enumerate the sealed types
        var vars :Array = Domain.currentDomain.getVariables(type);
        for (var ii :int = 0; ii < vars.length; ii ++) {
            varSet[vars[ii]] = true;
        }

        // then whatever's left, if anything, is dynamic
        for (var prop :String in type) {
            if (varSet[prop] === undefined) {
                dynVars.push(prop);
            }

            }

            if (doublify) {
                _ctx.bytes.writeByte(0x05);
                encodeDouble(value);
            } else {
                _ctx.bytes.writeByte(0x04);
                encodeInteger(uint(value));
            }

        } else if (value is String) {
            _ctx.bytes.writeByte(0x06);
            encodeString(value as String);

        /* } else if (value is XMLNode) { ... } // we don't even define the legacy XML types */

        } else if (value is Date) {
            // 0x08
            throw new Error("Date serialization not supported");

        } else if (value is Array) {
            _ctx.bytes.writeByte(0x09);
            encodeArray(value as Array);

        } else if ((value is XML) || (value is XMLList)) {
            // 0x0b
            throw new Error("XML serialization not supported");

        } else {
            var className :String = getQualifiedClassName(value);
            if (className == "flash.utils.ByteArray") {
                _ctx.bytes.writeByte(0x0c);
                encodeByteArray(value as ByteArray);
                return;
            }

            // Tamarin/Thane doesn't even have an IExternalizable type to test for

            _ctx.bytes.writeByte(0x0a);
            encodeObject(value as Object);
        }
    }

    private static function encodeInteger (n :uint) :void
    {
        if (n < 0x80) {
            _ctx.bytes.writeByte(0x00 | n);

        } else if (n < 0x4000) {
            _ctx.bytes.writeByte(0x80 | (n >> 7));
            _ctx.bytes.writeByte(0x00 | (n & 0x7F));

        } else if (n < 0x200000) {
            _ctx.bytes.writeByte(0x80 | (n >> 14));
            _ctx.bytes.writeByte(0x80 | ((n >> 7) & 0x7F));
            _ctx.bytes.writeByte(0x00 | (n & 0x7F));

        } else if (n < 0x3FFFFFFF) {
            _ctx.bytes.writeByte(0x80 | (n >> 21));
            _ctx.bytes.writeByte(0x80 | ((n >> 14) & 0x7F));
            _ctx.bytes.writeByte(0x80 | ((n >> 7) & 0x7F));
            _ctx.bytes.writeByte(0x00 | (n & 0x7F));

        } else {
            throw new Error("Internal error - numerical overflow: " + n);
