private IStackItem DeserializeStackItem(IExecutionEngine engine, BinaryReader reader)
        {
            EStackItemType type = (EStackItemType)reader.ReadByte();

            switch (type)
            {
            case EStackItemType.ByteArray:
                return(engine.CreateByteArray(reader.ReadVarBytes()));

            case EStackItemType.Bool:
                return(engine.CreateBool(reader.ReadBoolean()));

            case EStackItemType.Integer:
                return(engine.CreateInteger(new BigInteger(reader.ReadVarBytes())));

            case EStackItemType.Array:
            case EStackItemType.Struct:
            {
                IArrayStackItem array;

                if (type == EStackItemType.Struct)
                {
                    array = engine.CreateStruct();
                }
                else
                {
                    array = engine.CreateArray();
                }

                ulong count = reader.ReadVarInt();
                while (count-- > 0)
                {
                    array.Add(DeserializeStackItem(engine, reader));
                }

                return(array);
            }

            case EStackItemType.Map:
            {
                IMapStackItem map = engine.CreateMap();

                ulong count = reader.ReadVarInt();
                while (count-- > 0)
                {
                    IStackItem key   = DeserializeStackItem(engine, reader);
                    IStackItem value = DeserializeStackItem(engine, reader);

                    map[key] = value;

                    key.Dispose();
                    value.Dispose();
                }

                return(map);
            }

            default: throw new FormatException();
            }
        }
        private bool Runtime_Serialize(IExecutionEngine engine)
        {
            using (var context = engine.CurrentContext)
            {
                if (context == null)
                {
                    return(false);
                }

                if (!context.EvaluationStack.TryPop(out IStackItem it))
                {
                    return(false);
                }

                using (it)
                {
                    using (MemoryStream ms = new MemoryStream())
                        using (BinaryWriter writer = new BinaryWriter(ms))
                        {
                            try
                            {
                                SerializeStackItem(it, writer);
                            }
                            catch
                            {
                                return(false);
                            }

                            writer.Flush();

                            using (var bi = engine.CreateByteArray(ms.ToArray()))
                                context.EvaluationStack.Push(bi);
                        }
                }
            }

            return(true);
        }