/// <summary>
        /// Read <see cref="SwfOp.ByteCode.Actions.ActionPushList">ActionDefineFunction</see> from swf.
        /// including inner actions
        /// </summary>
        private ActionDefineFunction ReadActionDefineFunction(BinaryReader br)
        {
            int start = Convert.ToInt32(br.BaseStream.Position);

            // read block length
            int len = Convert.ToInt32(br.ReadUInt16());

            string name      = BinaryStringRW.ReadString(br);
            int    numParams = Convert.ToInt32(br.ReadUInt16());

            string[] parameterList = new string[numParams];
            for (int i = 0; i < numParams; i++)
            {
                parameterList[i] = BinaryStringRW.ReadString(br);
            }

            int blockSize = Convert.ToInt32(br.ReadUInt16());

            // read function body
            ArrayList            InnerActions = ReadActions(br.ReadBytes(blockSize));
            ActionDefineFunction a            = new ActionDefineFunction(name, parameterList, InnerActions);

            int end = Convert.ToInt32(br.BaseStream.Position);

            //a.ByteSize = end-start +1;

            return(a);
        }
        /// <summary>
        /// Read <see cref="SwfOp.ByteCode.Actions.ActionSetTarget">ActionSetTarget</see> from swf.
        /// </summary>
        private ActionSetTarget ReadActionSetTarget(BinaryReader br)
        {
            int len = Convert.ToInt32(br.ReadUInt16());

            ActionSetTarget a = new ActionSetTarget(BinaryStringRW.ReadString(br));

            //a.ByteSize = len+3;

            return(a);
        }
        /// <summary>
        /// Read <see cref="SwfOp.ByteCode.Actions.ActionGotoLabel">ActionGotoLabel</see> from swf.
        /// </summary>
        private ActionGotoLabel ReadActionGotoLabel(BinaryReader br)
        {
            int    len   = Convert.ToInt32(br.ReadUInt16());
            string label = BinaryStringRW.ReadString(br);

            ActionGotoLabel a = new ActionGotoLabel(label);

            //a.ByteSize = len+3;

            return(a);
        }
        /// <summary>
        /// Read <see cref="SwfOp.ByteCode.Actions.ActionGetUrl">ActionGetUrl</see> from swf.
        /// </summary>
        private ActionGetUrl ReadActionGetUrl(BinaryReader br)
        {
            int len = Convert.ToInt32(br.ReadUInt16());

            string urlStr    = BinaryStringRW.ReadString(br);
            string targetStr = BinaryStringRW.ReadString(br);

            ActionGetUrl a = new ActionGetUrl(urlStr, targetStr);

            //a.ByteSize = len+3;

            return(a);
        }
        /// <summary>
        /// Read <see cref="SwfOp.ByteCode.Actions.ActionPushList">ActionDefineFunction2</see> from swf.
        /// including inner actions
        /// </summary>
        private ActionDefineFunction2 ReadActionDefineFunction2(BinaryReader br)
        {
            int start = Convert.ToInt32(br.BaseStream.Position);
            // read block length
            int len = Convert.ToInt32(br.ReadUInt16());

            string name      = BinaryStringRW.ReadString(br);
            int    numParams = Convert.ToInt32(br.ReadUInt16());
            int    numRegs   = Convert.ToInt32(br.ReadByte());
            byte   flags1    = br.ReadByte();
            byte   flags2    = br.ReadByte();

            ActionDefineFunction2.VariableFlagSet f
                = new ActionDefineFunction2.VariableFlagSet(
                      (flags1 & 0x80) == 0x80,
                      (flags1 & 0x40) == 0x40,
                      (flags1 & 0x20) == 0x20,
                      (flags1 & 0x10) == 0x10,
                      (flags1 & 0x08) == 0x08,
                      (flags1 & 0x04) == 0x04,
                      (flags1 & 0x02) == 0x02,
                      (flags1 & 0x01) == 0x01,
                      (flags2 & 0x01) == 0x01
                      );

            // read parameters
            ActionDefineFunction2.RegParamPair[] paramList = new ActionDefineFunction2.RegParamPair[numParams];

            for (int i = 0; i < numParams; i++)
            {
                int    r = Convert.ToInt32(br.ReadByte());
                string p = BinaryStringRW.ReadString(br);
                paramList[i] = new ActionDefineFunction2.RegParamPair(r, p);
            }
            int blockSize = Convert.ToInt32(br.ReadUInt16());

            // read function body
            ArrayList             InnerActions = ReadActions(br.ReadBytes(blockSize));
            ActionDefineFunction2 a            = new ActionDefineFunction2(name, paramList, numRegs, f, InnerActions);

            int end = Convert.ToInt32(br.BaseStream.Position);

            ////a.ByteSize = len+3+blockSize;
            //a.ByteSize = end-start+1;

            return(a);
        }
        /// <summary>
        /// Read <see cref="SwfOp.ByteCode.Actions.ActionConstantPool">constant pool</see> action from swf. the constant pool is not parsed.
        /// </summary>
        private ActionConstantPool ReadActionConstantPool(BinaryReader br)
        {
            // read block length
            int len = Convert.ToInt32(br.ReadUInt16());

            int constCount = Convert.ToInt32(br.ReadUInt16());

            string[] constantPool = new string[constCount];

            for (int i = 0; i < constCount; i++)
            {
                constantPool[i] = BinaryStringRW.ReadString(br);
            }
            ActionConstantPool a = new ActionConstantPool(constantPool);

            //a.ByteSize = len+3;
            return(a);
        }
        /// <summary>
        /// Read try/catch block from swf and create corresponding
        /// <see cref="SwfOp.ByteCode.Actions.ActionTry">ActionTry</see>,
        /// <see cref="SwfOp.ByteCode.Actions.ActionCatch">ActionCatch</see>,
        /// <see cref="SwfOp.ByteCode.Actions.ActionFinally">ActionFinally</see>,
        /// <see cref="SwfOp.ByteCode.Actions.ActionEndTryBlock">ActionEndTryBlock</see>
        /// actions.
        /// </summary>
        private ActionTry ReadActionTry(BinaryReader br)
        {
            br.ReadUInt16();

            long startStream = br.BaseStream.Position;

            byte flags = br.ReadByte();

            bool catchInRegister = ((flags & 0x04) == 0x04);
            bool finallyFlag     = ((flags & 0x02) == 0x02);
            bool catchFlag       = ((flags & 0x01) == 0x01);

            ushort trySize     = br.ReadUInt16();
            ushort catchSize   = br.ReadUInt16();
            ushort finallySize = br.ReadUInt16();

            string catchName     = "";
            byte   catchRegister = 0;

            if (catchInRegister)
            {
                catchRegister = br.ReadByte();
            }
            else
            {
                catchName = BinaryStringRW.ReadString(br);
            }

            int len = Convert.ToInt32(br.BaseStream.Position - startStream);

            ActionTry a = new ActionTry(catchInRegister, finallyFlag, catchFlag,
                                        trySize, catchSize, finallySize,
                                        catchName, catchRegister);

            //a.ByteSize = len+3;

            return(a);
        }
        /// <summary>
        /// Read multiply push action action as <see cref="SwfOp.ByteCode.Actions.ActionPushList">ActionPushList</see> from swf.
        /// </summary>
        private ActionPushList ReadActionPush(BinaryReader br)
        {
            // read block length
            int       len      = Convert.ToInt32(br.ReadUInt16());
            int       i        = 0;
            ArrayList pushList = new ArrayList();

            while (i < len)
            {
                int pushType = Convert.ToInt32(br.ReadByte());
                i++;

                object val = new object();

                switch (pushType)
                {
                case 0: string str = BinaryStringRW.ReadString(br);
                    i  += str.Length + 1;
                    val = str;
                    break;

                case 1: val = (object)br.ReadSingle();
                    i      += 4;
                    break;

                case 2: val = null;
                    break;

                case 3: val = null;
                    break;

                case 4: val = (object)Convert.ToInt32(br.ReadByte());
                    i++;
                    break;

                case 5: val = (object )br.ReadBoolean();
                    i++;
                    break;

                case 6: byte[] b0 = br.ReadBytes(4);
                    byte[]     b1 = br.ReadBytes(4);
                    byte[]     b  = new byte[8];
                    b0.CopyTo(b, 4);
                    b1.CopyTo(b, 0);
                    val = (object)BitConverter.ToDouble(b, 0);
                    i  += 8;
                    break;

                case 7: val = (object)br.ReadInt32();
                    i      += 4;
                    break;

                case 8: val = (object)Convert.ToInt32(br.ReadByte());
                    i++;
                    break;

                case 9: val = (object)Convert.ToInt32(br.ReadUInt16());
                    i      += 2;
                    break;
                }

                ActionPush p = new ActionPush(pushType, val);
                pushList.Add(p);
            }

            ActionPush[] pList = new ActionPush[pushList.Count];
            pushList.CopyTo(pList, 0);
            ActionPushList a = new ActionPushList(pList);

            //a.ByteSize = len+3;
            return(a);
        }