private Push decodePush(int offset, int end, ActionFactory factory)
		{
			Push p;
			do 
			{
				int pushType = reader.readUI8();
				switch (pushType)
				{
					case Flash.Swf.ActionConstants.kPushStringType:  // string
						p = ActionFactory.createPush(reader.readString());
						break;
					
					case Flash.Swf.ActionConstants.kPushFloatType:  // float
                        byte[] floatBytes = new byte[4];
                        reader.read(floatBytes, 0, 4);
						p = ActionFactory.createPush(BitConverter.ToSingle(floatBytes, 0)); // value
						break;
					
					case Flash.Swf.ActionConstants.kPushNullType:  // null
						p = ActionFactory.createPushNull();
						break;
					
					case Flash.Swf.ActionConstants.kPushUndefinedType:  // undefined
						p = ActionFactory.createPushUndefined();
						break;
					
					case Flash.Swf.ActionConstants.kPushRegisterType:  // register
						p = ActionFactory.createPushRegister(reader.readUI8());
						break;
					
					case Flash.Swf.ActionConstants.kPushBooleanType:  // boolean
						p = ActionFactory.createPush(reader.readUI8() != 0);
						break;
					
					case Flash.Swf.ActionConstants.kPushDoubleType:  // double
						// read two 32 bit little-endian values in big-endian order.  weird.
                        byte[] doubleBytes = new byte[8];
                        reader.read(doubleBytes, 4, 4);
                        reader.read(doubleBytes, 0, 4);
                        p = ActionFactory.createPush(BitConverter.ToDouble(doubleBytes, 0));
						break;
					
					case Flash.Swf.ActionConstants.kPushIntegerType:  // integer
						p = ActionFactory.createPush((int) reader.readUI32());
						break;
					
					case Flash.Swf.ActionConstants.kPushConstant8Type:  // 8-bit cpool reference
						p = ActionFactory.createPushCpool(reader.readUI8());
						break;
					
					case Flash.Swf.ActionConstants.kPushConstant16Type:  // 16-bit cpool reference
						p = ActionFactory.createPushCpool(reader.readUI16());
						break;
					
					default: 
						throw new SwfFormatException("Unknown push data type " + pushType);
					
				}
				factory.setAction(offset, p);
				offset = reader.Offset;
			}
			while (offset < end);
			return p;
		}
        private Push decodePush(int offset, int end, ActionFactory factory)
        {
            Push p;

            do
            {
                int pushType = reader.readUI8();
                switch (pushType)
                {
                case Flash.Swf.ActionConstants.kPushStringType:                          // string
                    p = ActionFactory.createPush(reader.readString());
                    break;

                case Flash.Swf.ActionConstants.kPushFloatType:                          // float
                    byte[] floatBytes = new byte[4];
                    reader.read(floatBytes, 0, 4);
                    p = ActionFactory.createPush(BitConverter.ToSingle(floatBytes, 0));                             // value
                    break;

                case Flash.Swf.ActionConstants.kPushNullType:                          // null
                    p = ActionFactory.createPushNull();
                    break;

                case Flash.Swf.ActionConstants.kPushUndefinedType:                          // undefined
                    p = ActionFactory.createPushUndefined();
                    break;

                case Flash.Swf.ActionConstants.kPushRegisterType:                          // register
                    p = ActionFactory.createPushRegister(reader.readUI8());
                    break;

                case Flash.Swf.ActionConstants.kPushBooleanType:                          // boolean
                    p = ActionFactory.createPush(reader.readUI8() != 0);
                    break;

                case Flash.Swf.ActionConstants.kPushDoubleType:                          // double
                    // read two 32 bit little-endian values in big-endian order.  weird.
                    byte[] doubleBytes = new byte[8];
                    reader.read(doubleBytes, 4, 4);
                    reader.read(doubleBytes, 0, 4);
                    p = ActionFactory.createPush(BitConverter.ToDouble(doubleBytes, 0));
                    break;

                case Flash.Swf.ActionConstants.kPushIntegerType:                          // integer
                    p = ActionFactory.createPush((int)reader.readUI32());
                    break;

                case Flash.Swf.ActionConstants.kPushConstant8Type:                          // 8-bit cpool reference
                    p = ActionFactory.createPushCpool(reader.readUI8());
                    break;

                case Flash.Swf.ActionConstants.kPushConstant16Type:                          // 16-bit cpool reference
                    p = ActionFactory.createPushCpool(reader.readUI16());
                    break;

                default:
                    throw new SwfFormatException("Unknown push data type " + pushType);
                }
                factory.setAction(offset, p);
                offset = reader.Offset;
            }while (offset < end);
            return(p);
        }
		private void  decodeAction(int opcode, int offset, ActionFactory factory)
		{
			LineRecord line = debug != null?debug.getLine(offset):null;
			if (line != null)
			{
				factory.setLine(offset, line);
			}
			
			// interleave register records in the action list
			RegisterRecord record = (debug != null)?debug.getRegisters(offset):null;
			if (record != null)
			{
				factory.setRegister(offset, record);
			}
			
			Action a;
			if (opcode < 0x80)
			{
				a = ActionFactory.createAction(opcode);
				factory.setAction(offset, a);
				return ;
			}
			
			int len = reader.readUI16();
			int pos = offset + 3;
			
			switch (opcode)
			{
				
				case Flash.Swf.ActionConstants.sactionDefineFunction: 
					a = decodeDefineFunction(pos, len);
					factory.setAction(offset, a);
					return ;
				
				
				case Flash.Swf.ActionConstants.sactionDefineFunction2: 
					a = decodeDefineFunction2(pos, len);
					factory.setAction(offset, a);
					return ;
				
				
				case Flash.Swf.ActionConstants.sactionWith: 
					a = decodeWith(factory);
					break;
				
				
				case Flash.Swf.ActionConstants.sactionTry: 
					a = decodeTry(factory);
					break;
				
				
				case Flash.Swf.ActionConstants.sactionPush: 
					Push p = decodePush(offset, pos + len, factory);
					checkConsumed(pos, len, p);
					return ;
				
				
				case Flash.Swf.ActionConstants.sactionStrictMode: 
					a = decodeStrictMode();
					break;
				
				
				case Flash.Swf.ActionConstants.sactionCall: 
					// this actions opcode has the high bit set, but there is no length.  considered a permanent bug.
					a = ActionFactory.createCall();
					break;
				
				
				case Flash.Swf.ActionConstants.sactionGotoFrame: 
					a = decodeGotoFrame();
					break;
				
				
				case Flash.Swf.ActionConstants.sactionGetURL: 
					a = decodeGetURL();
					break;
				
				
				case Flash.Swf.ActionConstants.sactionStoreRegister: 
					a = decodeStoreRegister();
					break;
				
				
				case Flash.Swf.ActionConstants.sactionConstantPool: 
					a = decodeConstantPool();
					break;
				
				
				case Flash.Swf.ActionConstants.sactionWaitForFrame: 
					a = decodeWaitForFrame(opcode, factory);
					break;
				
				
				case Flash.Swf.ActionConstants.sactionSetTarget: 
					a = decodeSetTarget();
					break;
				
				
				case Flash.Swf.ActionConstants.sactionGotoLabel: 
					a = decodeGotoLabel();
					break;
				
				
				case Flash.Swf.ActionConstants.sactionWaitForFrame2: 
					a = decodeWaitForFrame(opcode, factory);
					break;
				
				
				case Flash.Swf.ActionConstants.sactionGetURL2: 
					a = decodeGetURL2();
					break;
				
				
				case Flash.Swf.ActionConstants.sactionJump: 
				case Flash.Swf.ActionConstants.sactionIf: 
					a = decodeBranch(opcode, factory);
					break;
				
				
				case Flash.Swf.ActionConstants.sactionGotoFrame2: 
					a = decodeGotoFrame2();
					break;
				
				
				default: 
					a = decodeUnknown(opcode, len);
					break;
				
			}
			checkConsumed(pos, len, a);
			factory.setAction(offset, a);
		}
        private void  decodeAction(int opcode, int offset, ActionFactory factory)
        {
            LineRecord line = debug != null?debug.getLine(offset) : null;

            if (line != null)
            {
                factory.setLine(offset, line);
            }

            // interleave register records in the action list
            RegisterRecord record = (debug != null)?debug.getRegisters(offset):null;

            if (record != null)
            {
                factory.setRegister(offset, record);
            }

            Action a;

            if (opcode < 0x80)
            {
                a = ActionFactory.createAction(opcode);
                factory.setAction(offset, a);
                return;
            }

            int len = reader.readUI16();
            int pos = offset + 3;

            switch (opcode)
            {
            case Flash.Swf.ActionConstants.sactionDefineFunction:
                a = decodeDefineFunction(pos, len);
                factory.setAction(offset, a);
                return;


            case Flash.Swf.ActionConstants.sactionDefineFunction2:
                a = decodeDefineFunction2(pos, len);
                factory.setAction(offset, a);
                return;


            case Flash.Swf.ActionConstants.sactionWith:
                a = decodeWith(factory);
                break;


            case Flash.Swf.ActionConstants.sactionTry:
                a = decodeTry(factory);
                break;


            case Flash.Swf.ActionConstants.sactionPush:
                Push p = decodePush(offset, pos + len, factory);
                checkConsumed(pos, len, p);
                return;


            case Flash.Swf.ActionConstants.sactionStrictMode:
                a = decodeStrictMode();
                break;


            case Flash.Swf.ActionConstants.sactionCall:
                // this actions opcode has the high bit set, but there is no length.  considered a permanent bug.
                a = ActionFactory.createCall();
                break;


            case Flash.Swf.ActionConstants.sactionGotoFrame:
                a = decodeGotoFrame();
                break;


            case Flash.Swf.ActionConstants.sactionGetURL:
                a = decodeGetURL();
                break;


            case Flash.Swf.ActionConstants.sactionStoreRegister:
                a = decodeStoreRegister();
                break;


            case Flash.Swf.ActionConstants.sactionConstantPool:
                a = decodeConstantPool();
                break;


            case Flash.Swf.ActionConstants.sactionWaitForFrame:
                a = decodeWaitForFrame(opcode, factory);
                break;


            case Flash.Swf.ActionConstants.sactionSetTarget:
                a = decodeSetTarget();
                break;


            case Flash.Swf.ActionConstants.sactionGotoLabel:
                a = decodeGotoLabel();
                break;


            case Flash.Swf.ActionConstants.sactionWaitForFrame2:
                a = decodeWaitForFrame(opcode, factory);
                break;


            case Flash.Swf.ActionConstants.sactionGetURL2:
                a = decodeGetURL2();
                break;


            case Flash.Swf.ActionConstants.sactionJump:
            case Flash.Swf.ActionConstants.sactionIf:
                a = decodeBranch(opcode, factory);
                break;


            case Flash.Swf.ActionConstants.sactionGotoFrame2:
                a = decodeGotoFrame2();
                break;


            default:
                a = decodeUnknown(opcode, len);
                break;
            }
            checkConsumed(pos, len, a);
            factory.setAction(offset, a);
        }