package org.zozuar.volumetrics {
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.*;

    /**
    * The EffectContainer class creates a volumetric light effect (also known as crepuscular or "god" rays).
    * This is done in 2D with some bitmap processing of an emission object, and optionally an occlusion object.
    */
    public class EffectContainer extends Sprite {
        /**
        * When true a blur filter is applied to the final effect bitmap (can help when colorIntegrity == true).
        */
        public var blur:Boolean = false;
        /**
        * Selects rendering method; when set to true colors won't be distorted and performance will be
        * a little worse. Also, this might make the final output appear grainier.
        */
        public var colorIntegrity:Boolean = false;
        /**
        * Light intensity.
        */
        public var intensity:Number = 4;
        /**
        * Number of passes applied to buffer. Lower numbers mean lower quality but better performance,
        * anything above 8 is probably overkill.
        */
        public var passes:uint = 6;
        /**
        * Set this to one of the StageQuality constants to use this quality level when drawing bitmaps, or to
        * null to use the current stage quality. Mileage may vary on different platforms and player versions.
        * I think it should only be used when stage.quality is LOW (set this to BEST to get reasonable results).
        */
        public var rasterQuality:String = null;
        /**
        * Final scale of emission. Should always be more than 1.
        */
        public var scale:Number = 2;
        /**
        * Smooth scaling of the effect's final output bitmap.
        */
        public var smoothing:Boolean = true;
        /**
        * Light source x.
        * @default viewport center (set in constructor).
        */
        public var srcX:Number;
        /**
        * Light source y.
        * @default viewport center (set in constructor).
        */
        public var srcY:Number;

        protected var _blurFilter:BlurFilter = new BlurFilter(2, 2);
        protected var _emission:DisplayObject;
        protected var _occlusion:DisplayObject;
        protected var _ct:ColorTransform = new ColorTransform;
        protected var _halve:ColorTransform = new ColorTransform(0.5, 0.5, 0.5);
        protected var _occlusionLoResBmd:BitmapData;
        protected var _occlusionLoResBmp:Bitmap;
        protected var _baseBmd:BitmapData;
        protected var _bufferBmd:BitmapData;
        protected var _lightBmp:Bitmap = new Bitmap;
        protected var _bufferSize:uint = 0x8000;
        protected var _bufferWidth:uint;
        protected var _bufferHeight:uint;
        protected var _viewportWidth:uint;
        protected var _viewportHeight:uint;
        protected var _mtx:Matrix = new Matrix;

        /**
        * Creates a new effect container.
        *
        * @param width Viewport width in pixels.
        * @param height Viewport height in pixels.
        * @param emission A DisplayObject to which the effect will be applied. This object will be
        * added as a child of the container. When applying the effect the object's filters and color
        * transform are ignored, if you want to use filters or a color transform put your content in
        * another object and addChild it to this one instead.
        * @param occlusion An optional occlusion object, handled the same way as the emission object.
        */
        public function EffectContainer(width:uint, height:uint, emission:DisplayObject, occlusion:DisplayObject = null) {
            if(!emission) throw(new Error("emission DisplayObject must not be null."));
            addChild(_emission = emission);
            if(occlusion) addChild(_occlusion = occlusion);
            setViewportSize(width, height);
            _lightBmp.blendMode = BlendMode.ADD;
            addChild(_lightBmp);
            srcX = width / 2;
            srcY = height / 2;
        }

        /**
        * Sets the container's size. This method recreates internal buffers (slow), do not call this on
        * every frame.
        *
        * @param width Viewport width in pixels
        * @param height Viewport height in pixels
        */
        public function setViewportSize(width:uint, height:uint):void {
            _viewportWidth = width;
            _viewportHeight = height;
            scrollRect = new Rectangle(0, 0, width, height);
            _updateBuffers();
        }

        /**
        * Sets the approximate size (in pixels) of the effect's internal buffers. Smaller number means lower
        * quality and better performance. This method recreates internal buffers (slow), do not call this on
        * every frame.
        *
        * @param size Buffer size in pixels
        */
        public function setBufferSize(size:uint):void {
            _bufferSize = size;
            _updateBuffers();
        }

        protected function _updateBuffers():void {
            var aspect:Number = _viewportWidth / _viewportHeight;
            _bufferHeight = Math.max(1, Math.sqrt(_bufferSize / aspect));
            _bufferWidth  = Math.max(1, _bufferHeight * aspect);
            dispose();
            _baseBmd           = new BitmapData(_bufferWidth, _bufferHeight, false, 0);
            _bufferBmd         = new BitmapData(_bufferWidth, _bufferHeight, false, 0);
            _occlusionLoResBmd = new BitmapData(_bufferWidth, _bufferHeight, true, 0);
            _occlusionLoResBmp = new Bitmap(_occlusionLoResBmd);
        }

        /**
        * Render a single frame.
        *
        * @param e In case you want to make this an event listener.
        */
        public function render(e:Event = null):void {
            if(!(_lightBmp.visible = intensity > 0)) return;
            var savedQuality:String = stage.quality;
            if(rasterQuality) stage.quality = rasterQuality;
            var mul:Number = colorIntegrity ? intensity : intensity/(1<<passes);
            _ct.redMultiplier = _ct.greenMultiplier = _ct.blueMultiplier = mul;
            _drawLoResEmission();
            if(_occlusion) _eraseLoResOcclusion();
            if(rasterQuality) stage.quality = savedQuality;
            var s:Number = 1 + (scale-1) / (1 << passes);
            var tx:Number = srcX/_viewportWidth*_bufferWidth;
            var ty:Number = srcY/_viewportHeight*_bufferHeight;
            _mtx.identity();
            _mtx.translate(-tx, -ty);
            _mtx.scale(s, s);
            _mtx.translate(tx, ty);
            _applyEffect(_baseBmd, _bufferBmd, _mtx, passes);
            _lightBmp.bitmapData = _baseBmd;
            _lightBmp.width = _viewportWidth;
            _lightBmp.height = _viewportHeight;
            _lightBmp.smoothing = smoothing;
        }

        /**
        * Draws a scaled-down emission on _baseBmd.
        */
        protected function _drawLoResEmission():void {
            _copyMatrix(_emission.transform.matrix, _mtx);
            _mtx.scale(_bufferWidth / _viewportWidth, _bufferHeight / _viewportHeight);
            _baseBmd.fillRect(_baseBmd.rect, 0);
            _baseBmd.draw(_emission, _mtx, colorIntegrity ? null : _ct);
        }

        /**
        * Draws a scaled-down occlusion on _occlusionLoResBmd and erases it from _baseBmd.
        */
        protected function _eraseLoResOcclusion():void {
            _occlusionLoResBmd.fillRect(_occlusionLoResBmd.rect, 0);
            _copyMatrix(_occlusion.transform.matrix, _mtx);
            _mtx.scale(_bufferWidth / _viewportWidth, _bufferHeight / _viewportHeight);
            _occlusionLoResBmd.draw(_occlusion, _mtx);
            _baseBmd.draw(_occlusionLoResBmp, null, null, BlendMode.ERASE);
        }

        /**
        * Render the effect on every frame until stopRendering is called.
        */
        public function startRendering():void {
            addEventListener(Event.ENTER_FRAME, render);
        }

        /**
        * Stop rendering on every frame.
        */
        public function stopRendering():void {
            removeEventListener(Event.ENTER_FRAME, render);
        }

        /**
        * Low-level workhorse, applies the lighting effect to a bitmap. This function modifies the bmd and buffer
        * bitmaps and its mtx argument.
        *
        * @param bmd The BitmapData to apply the effect on.
        * @param buffer Another BitmapData object for temporary storage. Must be the same size as bmd.
        * @param mtx Effect matrix.
        * @param passes Number of passes to make.
        */
        protected function _applyEffect(bmd:BitmapData, buffer:BitmapData, mtx:Matrix, passes:uint):void {
            while(passes--) {
                if(colorIntegrity) bmd.colorTransform(bmd.rect, _halve);
                buffer.copyPixels(bmd, bmd.rect, bmd.rect.topLeft);
                bmd.draw(buffer, mtx, null, BlendMode.ADD, null, true);
                mtx.concat(mtx);
            }
            if(colorIntegrity) bmd.colorTransform(bmd.rect, _ct);
            if(blur) bmd.applyFilter(bmd, bmd.rect, bmd.rect.topLeft, _blurFilter);
        }

        /**
        * Dispose of all intermediate buffers. After calling this the EffectContainer object will be unusable.
        */
        public function dispose():void {
            if(_baseBmd) _baseBmd.dispose();
            if(_occlusionLoResBmd) _occlusionLoResBmd.dispose();
            if(_bufferBmd) _bufferBmd.dispose();
            _baseBmd = _occlusionLoResBmd = _bufferBmd = _lightBmp.bitmapData = null;
        }

        protected function _copyMatrix(src:Matrix, dst:Matrix):void {
            dst.a = src.a;
            dst.b = src.b;
            dst.c = src.c;
            dst.d = src.d;
            dst.tx = src.tx;
            dst.ty = src.ty;
        }
    }
}

package org.zozuar.volumetrics {
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.*;

    /**
    * The EffectContainer class creates a volumetric light effect (also known as crepuscular or "god" rays).
    * This is done in 2D with some bitmap processing of an emission object, and optionally an occlusion object.
    */
    public class EffectContainer extends Sprite {
        /**
        * When true a blur filter is applied to the final effect bitmap (can help when colorIntegrity == true).
        */
        public var blur:Boolean = false;
        /**
        * Selects rendering method; when set to true colors won't be distorted and performance will be
        * a little worse. Also, this might make the final output appear grainier.
        */
        public var colorIntegrity:Boolean = false;
        /**
        * Light intensity.
        */
        public var intensity:Number = 4;
        /**
        * Number of passes applied to buffer. Lower numbers mean lower quality but better performance,
        * anything above 8 is probably overkill.
        */
        public var passes:uint = 6;
        /**
        * Set this to one of the StageQuality constants to use this quality level when drawing bitmaps, or to
        * null to use the current stage quality. Mileage may vary on different platforms and player versions.
        * I think it should only be used when stage.quality is LOW (set this to BEST to get reasonable results).
        */
        public var rasterQuality:String = null;
        /**
        * Final scale of emission. Should always be more than 1.
        */
        public var scale:Number = 2;
        /**
        * Smooth scaling of the effect's final output bitmap.
        */
        public var smoothing:Boolean = true;
        /**
        * Light source x.
        * @default viewport center (set in constructor).
        */
        public var srcX:Number;
        /**
        * Light source y.
        * @default viewport center (set in constructor).
        */
        public var srcY:Number;

        protected var _blurFilter:BlurFilter = new BlurFilter(2, 2);
        protected var _emission:DisplayObject;
        protected var _occlusion:DisplayObject;
        protected var _ct:ColorTransform = new ColorTransform;
        protected var _halve:ColorTransform = new ColorTransform(0.5, 0.5, 0.5);
        protected var _occlusionLoResBmd:BitmapData;
        protected var _occlusionLoResBmp:Bitmap;
        protected var _baseBmd:BitmapData;
        protected var _bufferBmd:BitmapData;
        protected var _lightBmp:Bitmap = new Bitmap;
        protected var _bufferSize:uint = 0x8000;
        protected var _bufferWidth:uint;
        protected var _bufferHeight:uint;
        protected var _bufferRect:Rectangle = new Rectangle;
        protected var _viewportWidth:uint;
        protected var _viewportHeight:uint;
        protected var _mtx:Matrix = new Matrix;
        protected var _zero:Point = new Point;

        /**
        * Creates a new effect container.
        *
        * @param width Viewport width in pixels.
        * @param height Viewport height in pixels.
        * @param emission A DisplayObject to which the effect will be applied. This object will be
        * added as a child of the container. When applying the effect the object's filters and color
        * transform are ignored, if you want to use filters or a color transform put your content in
        * another object and addChild it to this one instead.
        * @param occlusion An optional occlusion object, handled the same way as the emission object.
        */
        public function EffectContainer(width:uint, height:uint, emission:DisplayObject, occlusion:DisplayObject = null) {
            if(!emission) throw(new Error("emission DisplayObject must not be null."));
            addChild(_emission = emission);
            if(occlusion) addChild(_occlusion = occlusion);
            setViewportSize(width, height);
            _lightBmp.blendMode = BlendMode.ADD;
            addChild(_lightBmp);
            srcX = width / 2;
            srcY = height / 2;
        }

        /**
        * Sets the container's size. This method recreates internal buffers (slow), do not call this on
        * every frame.
        *
        * @param width Viewport width in pixels
        * @param height Viewport height in pixels
        */
        public function setViewportSize(width:uint, height:uint):void {
            _viewportWidth = width;
            _viewportHeight = height;
            scrollRect = new Rectangle(0, 0, width, height);
            _updateBuffers();
        }

        /**
        * Sets the approximate size (in pixels) of the effect's internal buffers. Smaller number means lower
        * quality and better performance. This method recreates internal buffers (slow), do not call this on
        * every frame.
        *
        * @param size Buffer size in pixels
        */
        public function setBufferSize(size:uint):void {
            _bufferSize = size;
            _updateBuffers();
        }

        protected function _updateBuffers():void {
            var aspect:Number = _viewportWidth / _viewportHeight;
            _bufferHeight = Math.max(1, Math.sqrt(_bufferSize / aspect));
            _bufferWidth  = Math.max(1, _bufferHeight * aspect);
            dispose();
            _baseBmd           = new BitmapData(_bufferWidth, _bufferHeight, false, 0);
            _bufferBmd         = new BitmapData(_bufferWidth, _bufferHeight, false, 0);
            _occlusionLoResBmd = new BitmapData(_bufferWidth, _bufferHeight, true, 0);
            _occlusionLoResBmp = new Bitmap(_occlusionLoResBmd);
            _bufferRect.height = _bufferHeight;
            _bufferRect.width  = _bufferWidth;
        }

        /**
        * Render a single frame.
        *
        * @param e In case you want to make this an event listener.
        */
        public function render(e:Event = null):void {
            if(!(_lightBmp.visible = intensity > 0)) return;
            var savedQuality:String = stage.quality;
            if(rasterQuality) stage.quality = rasterQuality;
            var mul:Number = colorIntegrity ? intensity : intensity/(1<<passes);
            _ct.redMultiplier = _ct.greenMultiplier = _ct.blueMultiplier = mul;
            _drawLoResEmission();
            if(_occlusion) _eraseLoResOcclusion();
            if(rasterQuality) stage.quality = savedQuality;
            var s:Number = 1 + (scale-1) / (1 << passes);
            var tx:Number = srcX/_viewportWidth*_bufferWidth;
            var ty:Number = srcY/_viewportHeight*_bufferHeight;
            _mtx.identity();
            _mtx.translate(-tx, -ty);
            _mtx.scale(s, s);
            _mtx.translate(tx, ty);
            _applyEffect(_baseBmd, _bufferRect, _bufferBmd, _mtx, passes);
            _lightBmp.bitmapData = _baseBmd;
            _lightBmp.width = _viewportWidth;
            _lightBmp.height = _viewportHeight;
            _lightBmp.smoothing = smoothing;
        }

        /**
        * Draws a scaled-down emission on _baseBmd.
        */
        protected function _drawLoResEmission():void {
            _copyMatrix(_emission.transform.matrix, _mtx);
            _mtx.scale(_bufferWidth / _viewportWidth, _bufferHeight / _viewportHeight);
            _baseBmd.fillRect(_bufferRect, 0);
            _baseBmd.draw(_emission, _mtx, colorIntegrity ? null : _ct);
        }

        /**
        * Draws a scaled-down occlusion on _occlusionLoResBmd and erases it from _baseBmd.
        */
        protected function _eraseLoResOcclusion():void {
            _occlusionLoResBmd.fillRect(_bufferRect, 0);
            _copyMatrix(_occlusion.transform.matrix, _mtx);
            _mtx.scale(_bufferWidth / _viewportWidth, _bufferHeight / _viewportHeight);
            _occlusionLoResBmd.draw(_occlusion, _mtx);
            _baseBmd.draw(_occlusionLoResBmp, null, null, BlendMode.ERASE);
        }

        /**
        * Render the effect on every frame until stopRendering is called.
        */
        public function startRendering():void {
            addEventListener(Event.ENTER_FRAME, render);
        }

        /**
        * Stop rendering on every frame.
        */
        public function stopRendering():void {
            removeEventListener(Event.ENTER_FRAME, render);
        }

        /**
        * Low-level workhorse, applies the lighting effect to a bitmap. This function modifies the bmd and buffer
        * bitmaps and its mtx argument.
        *
        * @param bmd The BitmapData to apply the effect on.
        * @param rect BitmapData rectangle.
        * @param buffer Another BitmapData object for temporary storage. Must be the same size as bmd.
        * @param mtx Effect matrix.
        * @param passes Number of passes to make.
        */
        protected function _applyEffect(bmd:BitmapData, rect:Rectangle, buffer:BitmapData, mtx:Matrix, passes:uint):void {
            while(passes--) {
                if(colorIntegrity) bmd.colorTransform(rect, _halve);
                buffer.copyPixels(bmd, rect, _zero);
                bmd.draw(buffer, mtx, null, BlendMode.ADD, null, true);
                mtx.concat(mtx);
            }
            if(colorIntegrity) bmd.colorTransform(rect, _ct);
            if(blur) bmd.applyFilter(bmd, rect, _zero, _blurFilter);
        }

        /**
        * Dispose of all intermediate buffers. After calling this the EffectContainer object will be unusable.
        */
        public function dispose():void {
            if(_baseBmd) _baseBmd.dispose();
            if(_occlusionLoResBmd) _occlusionLoResBmd.dispose();
            if(_bufferBmd) _bufferBmd.dispose();
            _baseBmd = _occlusionLoResBmd = _bufferBmd = _lightBmp.bitmapData = null;
        }

        protected function _copyMatrix(src:Matrix, dst:Matrix):void {
            dst.a = src.a;
            dst.b = src.b;
            dst.c = src.c;
            dst.d = src.d;
            dst.tx = src.tx;
            dst.ty = src.ty;
        }
    }
}

patch from makc - https://github.com/yonatan/volumetrics/pull/1


package org.flexunit.cases
{
	import flexunit.framework.AssertionFailedError;

	import org.flexunit.Assert;

	public class AssertCase
	{
		protected var asserterCalled:int = 0;

		[Test(description="Ensure that the assertWithApply function correctly runs the function with the parameter array")]
		public function testAssertWithApply():void {
			asserterCalled = 0;
			Assert.assertWithApply( test, [new Object()] );
			Assert.assertEquals( 1, asserterCalled );
		}

		[Test(description="Ensure that the assertWith function correct runs the function with the list of paramters")]
		public function testAssertWith():void {
			asserterCalled = 0;
			Assert.assertWith( test, new Object() );
			Assert.assertEquals( 1, asserterCalled );
		}

		[Test(description="Ensure that the assertionsMade property returns the correct assertCount")]
		public function testAssertionsMade():void {
			//Reset the fields to ensure the the count is accurate
			Assert.resetAssertionsFields();
			Assert.assertEquals( 0, 0 );
			Assert.assertEquals( Assert.assertionsMade, 1 );
		}

		[Test(description="Ensure that the resetAssertionsFields function correctly resets the assertCount")]
		public function testResetAssertionsFields():void {
			Assert.assertEquals( 0, 0 );
			//Ensure that the number of assertions are greater than zero
			Assert.assertTrue( Assert.assertionsMade > 0 );
			//Reset the assertions
			Assert.resetAssertionsFields();
			Assert.assertEquals( Assert.assertionsMade, 0 );
		}

		[Test(description="Ensure that the assertEquals function correctly determines if two non-strictly equal items are equal")]
		public function testAssertEquals():void {
			var o:Object = new Object();

			Assert.assertEquals( null, null );
			Assert.assertEquals( o, o );
			Assert.assertEquals( 5, 5 );
			Assert.assertEquals( "5", "5" );
			Assert.assertEquals( 5, "5" );
		}

		[Test(description="Ensure that the assertEquals function correctly determines if two non-strictly equal items are equal when a message is provided")]
		public function testAssertEqualsWithMessage():void {
			Assert.assertEquals( "Assert equals fail", "5", 5 );
		}

		[Test(description="Ensure that the assertEquals function fails when two items are not equal")]
		public function testAssertEqualsFails():void {
			var failed:Boolean = false;

			try {
				Assert.assertEquals( 2, 4 );
			} catch (error:AssertionFailedError) {
				failed = true;
				Assert.assertEquals( "expected:<2> but was:<4>", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert equals didn't fail" );
			}
		}

		[Test(description="Ensure that the assertEquals function fails when two items are not equal and the proper passed message is displayed")]
		public function testAssertEqualsWithMessageFails():void {
			var message:String = "Assert equals fail";
			var failed:Boolean = false;

			try {
				Assert.assertEquals( message, 2, 4 );
			// if we get an error with the right message we pass
			} catch (error:AssertionFailedError) {
				failed = true;
				Assert.assertEquals( message + " - expected:<2> but was:<4>", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert equals didn't fail" );
			}
		}

		[Test(description="Ensure that the failNotEquals function correctly determines if two non-strictly equal values are equal")]
		public function testFailNotEquals():void {
			Assert.failNotEquals( "Failure", "5", 5 );
		}

		[Test(description="Ensure that the failNotEqula function fails when two values are not equal",
			expects="flexunit.framework.AssertionFailedError")]
		public function testFailNotEqualsFails():void {
			Assert.failNotEquals( "Failure", 2, 4 );
		}

		[Test(description="Ensure that the assertStrictlyEquals function correctly determines if two values are strictly equal")]
		public function testAssertStrictlyEquals():void {
			var o:Object = new Object();
			Assert.assertStrictlyEquals( o, o );
		}

		[Test(description="Ensure that the assertStrictlyEquals function correctly determines if two values are strictly equal when a message is provided")]
		public function testAssertStrictlyEqualsWithMessage():void {
			var o:Object = new Object();
			Assert.assertStrictlyEquals( "Assert strictly equals fail", o, o );
		}

		[Test(description="Ensure that the assertStrictlyEquals function fails when two items are not strictly equal")]
		public function testAssertStrictlyEqualsFails():void {
			var failed:Boolean = false;

			try {
				Assert.assertStrictlyEquals( 5, "5" );
			} catch (error:AssertionFailedError) {
				failed = true;
				Assert.assertEquals( "expected:<5> but was:<5>", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert strictly equals didn't fail" );
			}
		}

		[Test(description="Ensure that the assertStrictlyEquals function fails when two items are not strictly euqal and the proper passed message is displayed")]
		public function testAssertStrictlyEqualsWithMessageFails():void {
			var message:String = "Assert strictly equals fail";
			var failed:Boolean = false;

			try {
				Assert.assertStrictlyEquals( message, 5, "5" );
				// if we get an error with the right message we pass
			} catch (error:AssertionFailedError) {
				failed = true;
				Assert.assertEquals( message + " - expected:<5> but was:<5>", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert strictly equals didn't fail" );
			}
		}

		[Test(description="Ensure that the failNotStrictlyEquals function correctly works when two strictly equal values are provided")]
		public function testFailNotStrictlyEquals():void {
			var o:Object = new Object();
			Assert.failNotStrictlyEquals( "Assert strictly equals fail", o, o );
		}
//TODO:: This test is not complete. Errors in my build prevented completion.
		[Test(description="Ensure that the failNotStrictlyEquals function fails when two non-strictly equal values are provided")]
		public function testFailNotStrictlyEqualsFails():void {
			var failed:Boolean = false;
/*
			try {
				Assert.failNotStrictlyEquals( "Assert strictly equals fail", 5, "5" );
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( "expected true but was false", error.message );
			}
*/
			if ( !failed ) {
				Assert.fail( "Assert strictly equals didn't fail" );
			}
		}

		[Test(description="Ensure that the assertTrue fucntion correctly works when a true value is provided")]
		public function testAssertTrue():void {
			Assert.assertTrue( true );
		}

		[Test(description="Ensure that the assertTrue function correctly works when a true value and a message are provided")]
		public function testAssertTrueWithMessage():void {
			Assert.assertTrue( "Assert true fail", true );
		}

		[Test(description="Ensure that the assertTrue function fails when a false value is provided")]
		public function testAssertTrueFails():void {
			var failed:Boolean = false;

			try {
				Assert.assertTrue( false )
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( "expected true but was false", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert true didn't fail" );
			}
		}

		[Test(description="Ensure that the assertTrue functions fails when a false value is provided and the proper passed message is displayed")]
		public function testAssertTrueWithMessageFails():void {
			var message:String = "Assert true fail";
			var failed:Boolean = false;

			try {
				Assert.assertTrue( message, false )
				// if we get an error with the right message we pass
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( message + " - expected true but was false", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert true didn't fail" );
			}
		}

		[Test(description="Ensure that the failNotTrue function correctly works when a value of true is provided")]
		public function testFailNotTrue():void {
			Assert.failNotTrue( "Fail not true fail", true );
		}

		[Test(description="Ensure that the failNotTrue function fails when a value of false is provided",
			expects="flexunit.framework.AssertionFailedError")]
		public function testFailNotTrueFails():void {
			Assert.failNotTrue( "Fail not true fail", false );
		}

		[Test(description="Ensure that the assertFalse function correctly works when a value of false is provided")]
		public function testAssertFalse():void {
			Assert.assertFalse( false );
		}

		[Test(description="Ensure that the assertFalse function correctly works when a value of false and a message are provided")]
		public function testAssertFalseWithMessage():void {
			Assert.assertFalse( "Assert false fail", false );
		}

		[Test(description="Ensure that the assertFalse function fails when a value of true is provided")]
		public function testAssertFalseFails():void {
			var failed:Boolean = false;

			try {
				Assert.assertFalse( true )
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( "expected false but was true", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert false didn't fail" );
			}
		}

		[Test(description="Ensure that the assertFalse function fails when a value of true is provided and the proper message is displayed")]
		public function testAssertFalseWithMessageFails():void {
			var message:String = "Assert false fail";
			var failed:Boolean = false;

			try {
				Assert.assertFalse( message, true )
				// if we get an error with the right message we pass
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( message + " - expected false but was true", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert false didn't fail" );
			}
		}

		[Test(description="Ensure that the failTrue function correctly works when a value of false is provided")]
		public function testFailTrue():void {
			Assert.failTrue( "Fail true fail", false );
		}

		[Test(description="Ensure that the failTrue function fails when a value of true is provided",
			expects="flexunit.framework.AssertionFailedError")]
		public function testFailTrueFails():void {
			Assert.failTrue( "Fail true fail", true );
		}

		[Test(description="Ensure that the assertNull function correctly works when a value of null is provided")]
		public function testAssertNull():void {
			Assert.assertNull( null );
		}

		[Test(description="Ensure that the assertNull function correctly works when a value of null and a message are provided")]
		public function testAssertNullWithMessage():void {
			Assert.assertNull( "Assert null fail", null );
		}

		[Test(description="Ensure that the assertNull function fails when a non-null value is provided")]
		public function testAssertNullFails():void {
			var o:Object = new Object();
			var failed:Boolean = false;

			try {
				Assert.assertNull( o )
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( "object was not null: [object Object]", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert null didn't fail" );
			}
		}

		[Test(description="Ensure that the assertNull functions fails when a non-null value is provided an the proper message is displayed")]
		public function testAssertNullWithMessageFails():void {
			var o:Object = new Object();
			var failed:Boolean = false;
			var message:String = "Assert null fail";
			try {
				Assert.assertNull( message, o )
				// if we get an error with the right message we pass
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( message + " - object was not null: [object Object]", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert null didn't fail" );
			}
		}

		[Test(description="Ensure that the failNull function works correctly when a non-null value is provided")]
		public function testFailNull():void {
			var o:Object = new Object();
			Assert.failNull( "Fail null fail", o );
		}

		[Test(description="Ensure that the failNull function fails when a null value is provided",
			expects="flexunit.framework.AssertionFailedError")]
		public function testFailNullFails():void {
			Assert.failNull( "Fail null fail", null );
		}

		[Test(description="Ensure the the assertNotNull function correctly works when a non-null value is provided")]
		public function testAssertNotNull():void {
			var o:Object = new Object();
			Assert.assertNotNull( o );
		}

		[Test(description="Ensure that the assertNotNull function correctly works when a non-null value and a message are provided")]
		public function testAssertNotNullWithMessage():void {
			var o:Object = new Object();
			Assert.assertNotNull( "Assert not null fail", o );
		}

		[Test(description="Ensure that the assertNotNull function fails when a null value is provided")]
		public function testAssertNotNullFails():void {
			var failed:Boolean = false;
			try {
				Assert.assertNotNull( null )
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( "object was null: null", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert not null didn't fail" );
			}
		}

		[Test(description="Ensure that the assertNotNull function fails when a null value is provided and the proper message is displayed")]
		public function testAssertNotNullWithMessageFails():void {
			var failed:Boolean = false;
			var message:String = "Assert not null fail";
			try {
				Assert.assertNotNull( message, null )
				// if we get an error with the right message we pass
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( message + " - object was null: null", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert not null didn't fail" );
			}
		}

		[Test(description="Ensure that the failNotNull function works correctly when a null value is provided")]
		public function testFailNotNull():void {
			Assert.failNotNull( "Fail not null fail", null );
		}

		[Test(description="Ensure that the failNotNull function fails when a non-null value is provided")]
		public function testFailNotNullFails():void {
			var o:Object = new Object();
			var failed:Boolean = false;
			var message:String = "Fail not null fail";

			try {
				Assert.failNotNull( "Fail not null fail", o );
			} catch(error:AssertionFailedError) {
				failed = true;
				Assert.assertEquals( message + " - object was not null: [object Object]", error.message );
			}
			if(!failed) {
				Assert.fail("The failNotNull function has failed");
			}
		}

		[Test(description="Ensure that the testFail function correctly throws an AssertionFailedError and sends the proper message")]
		public function testFail():void {
			var message:String = "Fail test";
			var failed:Boolean = false;

			try {
				Assert.fail(message);
			} catch(error:AssertionFailedError) {
				failed = true;
				Assert.assertEquals( message, error.message );
			}
			if(!failed) {
				Assert.fail("The fail function has failed");
			}
		}

		protected function test( obj:Object ):void {
			asserterCalled++;
		}
	}
}

package org.flexunit.cases
{
	import flexunit.framework.AssertionFailedError;

	import org.flexunit.Assert;

	public class AssertCase
	{
		protected var asserterCalled:int = 0;

		[Test(description="Ensure that the assertWithApply function correctly runs the function with the parameter array")]
		public function testAssertWithApply():void {
			asserterCalled = 0;
			Assert.assertWithApply( test, [new Object()] );
			Assert.assertEquals( 1, asserterCalled );
		}

		[Test(description="Ensure that the assertWith function correct runs the function with the list of paramters")]
		public function testAssertWith():void {
			asserterCalled = 0;
			Assert.assertWith( test, new Object() );
			Assert.assertEquals( 1, asserterCalled );
		}

		[Test(description="Ensure that the assertionsMade property returns the correct assertCount")]
		public function testAssertionsMade():void {
			//Reset the fields to ensure the the count is accurate
			Assert.resetAssertionsFields();
			Assert.assertEquals( 0, 0 );
			Assert.assertEquals( Assert.assertionsMade, 1 );
		}

		[Test(description="Ensure that the resetAssertionsFields function correctly resets the assertCount")]
		public function testResetAssertionsFields():void {
			Assert.assertEquals( 0, 0 );
			//Ensure that the number of assertions are greater than zero
			Assert.assertTrue( Assert.assertionsMade > 0 );
			//Reset the assertions
			Assert.resetAssertionsFields();
			Assert.assertEquals( Assert.assertionsMade, 0 );
		}

		[Test(description="Ensure that the assertEquals function correctly determines if two non-strictly equal items are equal")]
		public function testAssertEquals():void {
			var o:Object = new Object();

			Assert.assertEquals( null, null );
			Assert.assertEquals( o, o );
			Assert.assertEquals( 5, 5 );
			Assert.assertEquals( "5", "5" );
			Assert.assertEquals( 5, "5" );
		}

		[Test(description="Ensure that the assertEquals function correctly determines if two non-strictly equal items are equal when a message is provided")]
		public function testAssertEqualsWithMessage():void {
			Assert.assertEquals( "Assert equals fail", "5", 5 );
		}

		[Test(description="Ensure that the assertEquals function fails when two items are not equal")]
		public function testAssertEqualsFails():void {
			var failed:Boolean = false;

			try {
				Assert.assertEquals( 2, 4 );
			} catch (error:AssertionFailedError) {
				failed = true;
				Assert.assertEquals( "expected:<2> but was:<4>", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert equals didn't fail" );
			}
		}

		[Test(description="Ensure that the assertEquals function fails when two items are not equal and the proper passed message is displayed")]
		public function testAssertEqualsWithMessageFails():void {
			var message:String = "Assert equals fail";
			var failed:Boolean = false;

			try {
				Assert.assertEquals( message, 2, 4 );
			// if we get an error with the right message we pass
			} catch (error:AssertionFailedError) {
				failed = true;
				Assert.assertEquals( message + " - expected:<2> but was:<4>", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert equals didn't fail" );
			}
		}

		[Test(description="Ensure that the failNotEquals function correctly determines if two non-strictly equal values are equal")]
		public function testFailNotEquals():void {
			Assert.failNotEquals( "Failure", "5", 5 );
		}

		[Test(description="Ensure that the failNotEqula function fails when two values are not equal",
			expects="flexunit.framework.AssertionFailedError")]
		public function testFailNotEqualsFails():void {
			Assert.failNotEquals( "Failure", 2, 4 );
		}

		[Test(description="Ensure that the assertStrictlyEquals function correctly determines if two values are strictly equal")]
		public function testAssertStrictlyEquals():void {
			var o:Object = new Object();
			Assert.assertStrictlyEquals( o, o );
		}

		[Test(description="Ensure that the assertStrictlyEquals function correctly determines if two values are strictly equal when a message is provided")]
		public function testAssertStrictlyEqualsWithMessage():void {
			var o:Object = new Object();
			Assert.assertStrictlyEquals( "Assert strictly equals fail", o, o );
		}

		[Test(description="Ensure that the assertStrictlyEquals function fails when two items are not strictly equal")]
		public function testAssertStrictlyEqualsFails():void {
			var failed:Boolean = false;

			try {
				Assert.assertStrictlyEquals( 5, "5" );
			} catch (error:AssertionFailedError) {
				failed = true;
				Assert.assertEquals( "expected:<5> but was:<5>", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert strictly equals didn't fail" );
			}
		}

		[Test(description="Ensure that the assertStrictlyEquals function fails when two items are not strictly euqal and the proper passed message is displayed")]
		public function testAssertStrictlyEqualsWithMessageFails():void {
			var message:String = "Assert strictly equals fail";
			var failed:Boolean = false;

			try {
				Assert.assertStrictlyEquals( message, 5, "5" );
				// if we get an error with the right message we pass
			} catch (error:AssertionFailedError) {
				failed = true;
				Assert.assertEquals( message + " - expected:<5> but was:<5>", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert strictly equals didn't fail" );
			}
		}

		[Test(description="Ensure that the failNotStrictlyEquals function correctly works when two strictly equal values are provided")]
		public function testFailNotStrictlyEquals():void {
			var o:Object = new Object();
			Assert.failNotStrictlyEquals( "Assert strictly equals fail", o, o );
		}

		[Test(description="Ensure that the failNotStrictlyEquals function fails when two non-strictly equal values are provided")]
		public function testFailNotStrictlyEqualsFails():void {
			var failed:Boolean = false;
			try {
				Assert.failNotStrictlyEquals( "Assert strictly equals fail", 5, "5" );
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( "Assert strictly equals fail - expected:<5> but was:<5>", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert strictly equals didn't fail" );
			}
		}

		[Test(description="Ensure that the assertTrue fucntion correctly works when a true value is provided")]
		public function testAssertTrue():void {
			Assert.assertTrue( true );
		}

		[Test(description="Ensure that the assertTrue function correctly works when a true value and a message are provided")]
		public function testAssertTrueWithMessage():void {
			Assert.assertTrue( "Assert true fail", true );
		}

		[Test(description="Ensure that the assertTrue function fails when a false value is provided")]
		public function testAssertTrueFails():void {
			var failed:Boolean = false;

			try {
				Assert.assertTrue( false )
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( "expected true but was false", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert true didn't fail" );
			}
		}

		[Test(description="Ensure that the assertTrue functions fails when a false value is provided and the proper passed message is displayed")]
		public function testAssertTrueWithMessageFails():void {
			var message:String = "Assert true fail";
			var failed:Boolean = false;

			try {
				Assert.assertTrue( message, false )
				// if we get an error with the right message we pass
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( message + " - expected true but was false", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert true didn't fail" );
			}
		}

		[Test(description="Ensure that the failNotTrue function correctly works when a value of true is provided")]
		public function testFailNotTrue():void {
			Assert.failNotTrue( "Fail not true fail", true );
		}

		[Test(description="Ensure that the failNotTrue function fails when a value of false is provided",
			expects="flexunit.framework.AssertionFailedError")]
		public function testFailNotTrueFails():void {
			Assert.failNotTrue( "Fail not true fail", false );
		}

		[Test(description="Ensure that the assertFalse function correctly works when a value of false is provided")]
		public function testAssertFalse():void {
			Assert.assertFalse( false );
		}

		[Test(description="Ensure that the assertFalse function correctly works when a value of false and a message are provided")]
		public function testAssertFalseWithMessage():void {
			Assert.assertFalse( "Assert false fail", false );
		}

		[Test(description="Ensure that the assertFalse function fails when a value of true is provided")]
		public function testAssertFalseFails():void {
			var failed:Boolean = false;

			try {
				Assert.assertFalse( true )
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( "expected false but was true", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert false didn't fail" );
			}
		}

		[Test(description="Ensure that the assertFalse function fails when a value of true is provided and the proper message is displayed")]
		public function testAssertFalseWithMessageFails():void {
			var message:String = "Assert false fail";
			var failed:Boolean = false;

			try {
				Assert.assertFalse( message, true )
				// if we get an error with the right message we pass
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( message + " - expected false but was true", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert false didn't fail" );
			}
		}

		[Test(description="Ensure that the failTrue function correctly works when a value of false is provided")]
		public function testFailTrue():void {
			Assert.failTrue( "Fail true fail", false );
		}

		[Test(description="Ensure that the failTrue function fails when a value of true is provided",
			expects="flexunit.framework.AssertionFailedError")]
		public function testFailTrueFails():void {
			Assert.failTrue( "Fail true fail", true );
		}

		[Test(description="Ensure that the assertNull function correctly works when a value of null is provided")]
		public function testAssertNull():void {
			Assert.assertNull( null );
		}

		[Test(description="Ensure that the assertNull function correctly works when a value of null and a message are provided")]
		public function testAssertNullWithMessage():void {
			Assert.assertNull( "Assert null fail", null );
		}

		[Test(description="Ensure that the assertNull function fails when a non-null value is provided")]
		public function testAssertNullFails():void {
			var o:Object = new Object();
			var failed:Boolean = false;

			try {
				Assert.assertNull( o )
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( "object was not null: [object Object]", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert null didn't fail" );
			}
		}

		[Test(description="Ensure that the assertNull functions fails when a non-null value is provided an the proper message is displayed")]
		public function testAssertNullWithMessageFails():void {
			var o:Object = new Object();
			var failed:Boolean = false;
			var message:String = "Assert null fail";
			try {
				Assert.assertNull( message, o )
				// if we get an error with the right message we pass
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( message + " - object was not null: [object Object]", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert null didn't fail" );
			}
		}

		[Test(description="Ensure that the failNull function works correctly when a non-null value is provided")]
		public function testFailNull():void {
			var o:Object = new Object();
			Assert.failNull( "Fail null fail", o );
		}

		[Test(description="Ensure that the failNull function fails when a null value is provided",
			expects="flexunit.framework.AssertionFailedError")]
		public function testFailNullFails():void {
			Assert.failNull( "Fail null fail", null );
		}

		[Test(description="Ensure the the assertNotNull function correctly works when a non-null value is provided")]
		public function testAssertNotNull():void {
			var o:Object = new Object();
			Assert.assertNotNull( o );
		}

		[Test(description="Ensure that the assertNotNull function correctly works when a non-null value and a message are provided")]
		public function testAssertNotNullWithMessage():void {
			var o:Object = new Object();
			Assert.assertNotNull( "Assert not null fail", o );
		}

		[Test(description="Ensure that the assertNotNull function fails when a null value is provided")]
		public function testAssertNotNullFails():void {
			var failed:Boolean = false;
			try {
				Assert.assertNotNull( null )
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( "object was null: null", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert not null didn't fail" );
			}
		}

		[Test(description="Ensure that the assertNotNull function fails when a null value is provided and the proper message is displayed")]
		public function testAssertNotNullWithMessageFails():void {
			var failed:Boolean = false;
			var message:String = "Assert not null fail";
			try {
				Assert.assertNotNull( message, null )
				// if we get an error with the right message we pass
			} catch ( error:AssertionFailedError ) {
				failed = true;
				Assert.assertEquals( message + " - object was null: null", error.message );
			}
			if ( !failed ) {
				Assert.fail( "Assert not null didn't fail" );
			}
		}

		[Test(description="Ensure that the failNotNull function works correctly when a null value is provided")]
		public function testFailNotNull():void {
			Assert.failNotNull( "Fail not null fail", null );
		}

		[Test(description="Ensure that the failNotNull function fails when a non-null value is provided")]
		public function testFailNotNullFails():void {
			var o:Object = new Object();
			var failed:Boolean = false;
			var message:String = "Fail not null fail";

			try {
				Assert.failNotNull( "Fail not null fail", o );
			} catch(error:AssertionFailedError) {
				failed = true;
				Assert.assertEquals( message + " - object was not null: [object Object]", error.message );
			}
			if(!failed) {
				Assert.fail("The failNotNull function has failed");
			}
		}

		[Test(description="Ensure that the testFail function correctly throws an AssertionFailedError and sends the proper message")]
		public function testFail():void {
			var message:String = "Fail test";
			var failed:Boolean = false;

			try {
				Assert.fail(message);
			} catch(error:AssertionFailedError) {
				failed = true;
				Assert.assertEquals( message, error.message );
			}
			if(!failed) {
				Assert.fail("The fail function has failed");
			}
		}

		protected function test( obj:Object ):void {
			asserterCalled++;
		}
	}
}

Update to complete the testFailNotStrictlyEqualsFails test.


/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 package org.mangui.flowplayer {
    import org.mangui.hls.event.HLSEvent;
    import org.mangui.hls.utils.Params2Settings;

    import flash.display.DisplayObject;
    import flash.net.NetConnection;
    import flash.net.NetStream;
    import flash.utils.Dictionary;
    import flash.media.Video;

    import org.mangui.hls.HLS;
    import org.mangui.hls.constant.HLSPlayStates;

    import org.flowplayer.model.Plugin;
    import org.flowplayer.model.PluginModel;
    import org.flowplayer.view.Flowplayer;
    import org.flowplayer.controller.StreamProvider;
    import org.flowplayer.controller.TimeProvider;
    import org.flowplayer.controller.VolumeController;
    import org.flowplayer.model.Clip;
    import org.flowplayer.model.ClipType;
    import org.flowplayer.model.ClipEvent;
    import org.flowplayer.model.ClipEventType;
    import org.flowplayer.model.Playlist;
    import org.flowplayer.view.StageVideoWrapper;

    CONFIG::LOGGING {
    import org.mangui.hls.utils.Log;
    }

    public class HLSStreamProvider  implements StreamProvider,Plugin {
        private var _volumecontroller : VolumeController;
        private var _playlist : Playlist;
        private var _timeProvider : TimeProvider;
        private var _model : PluginModel;
        private var _player : Flowplayer;
        private var _clip : Clip;
        private var _video : Video;
        /** reference to the framework. **/
        private var _hls : HLS;
        // event values
        private var _position : Number = 0;
        private var _duration : Number = 0;
        private var _bufferedTime : Number = 0;
        private var _videoWidth : int = -1;
        private var _videoHeight : int = -1;
        private var _isManifestLoaded : Boolean = false;
        private var _pauseAfterStart : Boolean;
        private var _seekable : Boolean = false;

        public function getDefaultConfig() : Object {
            return null;
        }

        public function onConfig(model : PluginModel) : void {
            CONFIG::LOGGING {
            Log.info("onConfig()");
            }
            _model = model;
        }

        public function onLoad(player : Flowplayer) : void {
            CONFIG::LOGGING {
            Log.info("onLoad()");
            }
            _player = player;
            _hls = new HLS();
            _hls.stage = player.screen.getDisplayObject().stage;
            _hls.addEventListener(HLSEvent.PLAYBACK_COMPLETE, _completeHandler);
            _hls.addEventListener(HLSEvent.ERROR, _errorHandler);
            _hls.addEventListener(HLSEvent.MANIFEST_LOADED, _manifestHandler);
            _hls.addEventListener(HLSEvent.MEDIA_TIME, _mediaTimeHandler);
            _hls.addEventListener(HLSEvent.PLAYBACK_STATE, _stateHandler);
            _hls.addEventListener(HLSEvent.ID3_UPDATED, _ID3Handler);

            var cfg : Object = _model.config;
            for (var object : String in cfg) {
                var subidx : int = object.indexOf("hls_");
                if (subidx != -1) {
                    Params2Settings.set(object.substr(4), cfg[object]);
                }
            }

            _model.dispatchOnLoad();
        }

        private function _completeHandler(event : HLSEvent) : void {
            // dispatch a before event because the finish has default behavior that can be prevented by listeners
            _clip.dispatchBeforeEvent(new ClipEvent(ClipEventType.FINISH));
        };

        private function _errorHandler(event : HLSEvent) : void {
        };

        private function _ID3Handler(event : HLSEvent) : void {
            _clip.dispatch(ClipEventType.NETSTREAM_EVENT, "onID3", event.ID3Data);
        };

        private function _manifestHandler(event : HLSEvent) : void {
            _duration = event.levels[_hls.startlevel].duration;
            _isManifestLoaded = true;
            _clip.duration = _duration;
            _clip.stopLiveOnPause = false;
            _clip.dispatch(ClipEventType.METADATA);
            _seekable = true;
            // if (_hls.type == HLSTypes.LIVE) {
            // _seekable = false;
            // } else {
            // _seekable = true;
            // }
            _hls.stream.play();
            _clip.dispatch(ClipEventType.SEEK);
            if (_pauseAfterStart) {
                pause(new ClipEvent(ClipEventType.PAUSE));
            }
        };

        private function _mediaTimeHandler(event : HLSEvent) : void {
            _position = Math.max(0, event.mediatime.position);
            _duration = event.mediatime.duration;
            _clip.duration = _duration;
            _bufferedTime = event.mediatime.buffer + event.mediatime.position;
            var videoWidth : int = _video.videoWidth;
            var videoHeight : int = _video.videoHeight;
            if (videoWidth && videoHeight) {
                var changed : Boolean = _videoWidth != videoWidth || _videoHeight != videoHeight;
                if (changed) {
                    CONFIG::LOGGING {
                    Log.info("video size changed to " + videoWidth + "/" + videoHeight);
                    }
                    _videoWidth = videoWidth;
                    _videoHeight = videoHeight;
                    _clip.originalWidth = videoWidth;
                    _clip.originalHeight = videoHeight;
                    _clip.dispatch(ClipEventType.START);
                    _clip.dispatch(ClipEventType.METADATA_CHANGED);
                }
            }
        };

        private function _stateHandler(event : HLSEvent) : void {
            // CONFIG::LOGGING {
            // Log.txt("state:"+ event.state);
            // }
            switch(event.state) {
                case HLSPlayStates.IDLE:
                case HLSPlayStates.PLAYING:
                case HLSPlayStates.PAUSED:
                    _clip.dispatch(ClipEventType.BUFFER_FULL);
                    break;
                case HLSPlayStates.PLAYING_BUFFERING:
                case HLSPlayStates.PAUSED_BUFFERING:
                    _clip.dispatch(ClipEventType.BUFFER_EMPTY);
                    break;
                default:
                    break;
            }
        };

        /**
         * Starts loading the specified clip. Once video data is available the provider
         * must set it to the clip using clip.setContent(). Typically the video
         * object passed to the clip is an instance of flash.media.Video.
         *
         * @param event the event that this provider should dispatch once loading has successfully started,
         * once dispatched the player will call getVideo()
         * @param clip the clip to load
         * @param pauseAfterStart if true the playback is paused on first frame and
         * buffering is continued
         * @see Clip#setContent()
         * @see #getVideo()
         */
        public function load(event : ClipEvent, clip : Clip, pauseAfterStart : Boolean = true) : void {
            _clip = clip;
            CONFIG::LOGGING {
            Log.info("load()" + clip.completeUrl);
            }
            _hls.load(clip.completeUrl);
            _pauseAfterStart = pauseAfterStart;
            clip.type = ClipType.VIDEO;
            clip.dispatch(ClipEventType.BEGIN);
            clip.setNetStream(_hls.stream);
            return;
        }

        /**
         * Gets the Video object.
         * A stream will be attached to the returned video object using attachStream().
         * @param clip the clip for which the Video object is queried for
         * @see #attachStream()
         */
        public function getVideo(clip : Clip) : DisplayObject {
            CONFIG::LOGGING {
            Log.debug("getVideo()");
            }
            if (_video == null) {
                if (clip.useStageVideo) {
                    CONFIG::LOGGING {
                    Log.debug("useStageVideo");
                    }
                    _video = new StageVideoWrapper(clip);
                } else {
                    _video = new Video();
                    _video.smoothing = clip.smoothing;
                }
            }
            return _video;
        }

        /**
         * Attaches a stream to the specified display object.
         * @param video the video object that was originally retrieved using getVideo().
         * @see #getVideo()
         */
        public function attachStream(video : DisplayObject) : void {
            CONFIG::LOGGING {
            Log.debug("attachStream()");
            }
            Video(video).attachNetStream(_hls.stream);
            return;
        }

        /**
         * Pauses playback.
         * @param event the event that this provider should dispatch once loading has been successfully paused
         */
        public function pause(event : ClipEvent) : void {
            CONFIG::LOGGING {
            Log.info("pause()");
            }
            _hls.stream.pause();
            if (event) {
                _clip.dispatch(ClipEventType.PAUSE);
            }
            return;
        }

        /**
         * Resumes playback.
         * @param event the event that this provider should dispatch once loading has been successfully resumed
         */
        public function resume(event : ClipEvent) : void {
            CONFIG::LOGGING {
            Log.info("resume()");
            }
            _hls.stream.resume();
            _clip.dispatch(ClipEventType.RESUME);
            return;
        }

        /**
         * Stops and rewinds to the beginning of current clip.
         * @param event the event that this provider should dispatch once loading has been successfully stopped
         */
        public function stop(event : ClipEvent, closeStream : Boolean = false) : void {
            CONFIG::LOGGING {
            Log.info("stop()");
            }
            _hls.stream.close();
            return;
        }

        /**
         * Seeks to the specified point in the timeline.
         * @param event the event that this provider should dispatch once the seek is in target
         * @param seconds the target point in the timeline
         */
        public function seek(event : ClipEvent, seconds : Number) : void {
            CONFIG::LOGGING {
            Log.info("seek()");
            }
            _hls.stream.seek(seconds);
            _position = seconds;
            _bufferedTime = seconds;
            _clip.dispatch(ClipEventType.SEEK, seconds);
            return;
        }

        /**
         * File size in bytes.
         */
        public function get fileSize() : Number {
            return 0;
        }

        /**
         * Current playhead time in seconds.
         */
        public function get time() : Number {
            return _position;
        }

        /**
         * The point in timeline where the buffered data region begins, in seconds.
         */
        public function get bufferStart() : Number {
            return 0;
        }

        /**
         * The point in timeline where the buffered data region ends, in seconds.
         */
        public function get bufferEnd() : Number {
            return _bufferedTime;
        }

        /**
         * Does this provider support random seeking to unbuffered areas in the timeline?
         */
        public function get allowRandomSeek() : Boolean {
            // CONFIG::LOGGING {
            // Log.info("allowRandomSeek()");
            // }
            return _seekable;
        }

        /**
         * Volume controller used to control the video volume.
         */
        public function set volumeController(controller : VolumeController) : void {
            _volumecontroller = controller;
            _volumecontroller.netStream = _hls.stream;
            return;
        }

        /**
         * Is this provider in the process of stopping the stream?
         * When stopped the provider should not dispatch any events resulting from events that
         * might get triggered by the underlying streaming implementation.
         */
        public function get stopping() : Boolean {
            CONFIG::LOGGING {
            Log.info("stopping()");
            }
            return false;
        }

        /**
         * The playlist instance.
         */
        public function set playlist(playlist : Playlist) : void {
            // CONFIG::LOGGING {
            // Log.debug("set playlist()");
            // }
            _playlist = playlist;
            return;
        }

        public function get playlist() : Playlist {
            CONFIG::LOGGING {
            Log.debug("get playlist()");
            }
            return _playlist;
        }

        /**
         * Adds a callback public function to the NetConnection instance. This public function will fire ClipEvents whenever
         * the callback is invoked in the connection.
         * @param name
         * @param listener
         * @return
         * @see ClipEventType#CONNECTION_EVENT
         */
        public function addConnectionCallback(name : String, listener : Function) : void {
            CONFIG::LOGGING {
            Log.debug("addConnectionCallback()");
            }
            return;
        }

        /**
         * Adds a callback public function to the NetStream object. This public function will fire a ClipEvent of type StreamEvent whenever
         * the callback has been invoked on the stream. The invokations typically come from a server-side app running
         * on RTMP server.
         * @param name
         * @param listener
         * @return
         * @see ClipEventType.NETSTREAM_EVENT
         */
        public function addStreamCallback(name : String, listener : Function) : void {
            CONFIG::LOGGING {
            Log.debug("addStreamCallback()");
            }
            return;
        }

        /**
         * Get the current stream callbacks.
         * @return a dictionary of callbacks, keyed using callback names and values being the callback functions
         */
        public function get streamCallbacks() : Dictionary {
            CONFIG::LOGGING {
            Log.debug("get streamCallbacks()");
            }
            return null;
        }

        /**
         * Gets the underlying NetStream object.
         * @return the netStream currently in use, or null if this provider has not started streaming yet
         */
        public function get netStream() : NetStream {
            CONFIG::LOGGING {
            Log.debug("get netStream()");
            }
            return _hls.stream;
        }

        /**
         * Gets the underlying netConnection object.
         * @return the netConnection currently in use, or null if this provider has not started streaming yet
         */
        public function get netConnection() : NetConnection {
            CONFIG::LOGGING {
            Log.debug("get netConnection()");
            }
            return null;
        }

        /**
         * Sets a time provider to be used by this StreamProvider. Normally the playhead time is queried from
         * the NetStream.time property.
         *
         * @param timeProvider
         */
        public function set timeProvider(timeProvider : TimeProvider) : void {
            CONFIG::LOGGING {
            Log.debug("set timeProvider()");
            }
            _timeProvider = timeProvider;
            return;
        }

        /**
         * Gets the type of StreamProvider either http, rtmp, psuedo.
         */
        public function get type() : String {
            return "httpstreaming";
        }

        /**
         * Switch the stream in realtime with / without dynamic stream switching support
         *
         * @param event ClipEvent the clip event
         * @param clip Clip the clip to switch to
         * @param netStreamPlayOptions Object the NetStreamPlayOptions object to enable dynamic stream switching
         */
        public function switchStream(event : ClipEvent, clip : Clip, netStreamPlayOptions : Object = null) : void {
            CONFIG::LOGGING {
            Log.info("switchStream()");
            }
            return;
        }
    }
}

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 package org.mangui.flowplayer {
    import org.mangui.hls.event.HLSEvent;
    import org.mangui.hls.utils.Params2Settings;

    import flash.display.DisplayObject;
    import flash.net.NetConnection;
    import flash.net.NetStream;
    import flash.utils.Dictionary;
    import flash.media.Video;

    import org.mangui.hls.HLS;
    import org.mangui.hls.constant.HLSPlayStates;

    import org.flowplayer.model.Plugin;
    import org.flowplayer.model.PluginModel;
    import org.flowplayer.view.Flowplayer;
    import org.flowplayer.controller.StreamProvider;
    import org.flowplayer.controller.TimeProvider;
    import org.flowplayer.controller.VolumeController;
    import org.flowplayer.model.Clip;
    import org.flowplayer.model.ClipType;
    import org.flowplayer.model.ClipEvent;
    import org.flowplayer.model.ClipEventType;
    import org.flowplayer.model.Playlist;
    import org.flowplayer.view.StageVideoWrapper;

    CONFIG::LOGGING {
    import org.mangui.hls.utils.Log;
    }

    public class HLSStreamProvider  implements StreamProvider,Plugin {
        private var _volumecontroller : VolumeController;
        private var _playlist : Playlist;
        private var _timeProvider : TimeProvider;
        private var _model : PluginModel;
        private var _player : Flowplayer;
        private var _clip : Clip;
        private var _video : Video;
        /** reference to the framework. **/
        private var _hls : HLS;
        // event values
        private var _position : Number = 0;
        private var _duration : Number = 0;
        private var _bufferedTime : Number = 0;
        private var _videoWidth : int = -1;
        private var _videoHeight : int = -1;
        private var _isManifestLoaded : Boolean = false;
        private var _pauseAfterStart : Boolean;
        private var _seekable : Boolean = false;

        public function getDefaultConfig() : Object {
            return null;
        }

        public function onConfig(model : PluginModel) : void {
            CONFIG::LOGGING {
            Log.info("onConfig()");
            }
            _model = model;
        }

        public function onLoad(player : Flowplayer) : void {
            CONFIG::LOGGING {
            Log.info("onLoad()");
            }
            _player = player;
            _hls = new HLS();
            _hls.stage = player.screen.getDisplayObject().stage;
            _hls.addEventListener(HLSEvent.PLAYBACK_COMPLETE, _completeHandler);
            _hls.addEventListener(HLSEvent.ERROR, _errorHandler);
            _hls.addEventListener(HLSEvent.MANIFEST_LOADED, _manifestHandler);
            _hls.addEventListener(HLSEvent.MEDIA_TIME, _mediaTimeHandler);
            _hls.addEventListener(HLSEvent.PLAYBACK_STATE, _stateHandler);
            _hls.addEventListener(HLSEvent.ID3_UPDATED, _ID3Handler);

            var cfg : Object = _model.config;
            for (var object : String in cfg) {
                var subidx : int = object.indexOf("hls_");
                if (subidx != -1) {
                    Params2Settings.set(object.substr(4), cfg[object]);
                }
            }

            _model.dispatchOnLoad();
        }

        private function _completeHandler(event : HLSEvent) : void {
            // dispatch a before event because the finish has default behavior that can be prevented by listeners
            _clip.dispatchBeforeEvent(new ClipEvent(ClipEventType.FINISH));
        };

        private function _errorHandler(event : HLSEvent) : void {
        };

        private function _ID3Handler(event : HLSEvent) : void {
            _clip.dispatch(ClipEventType.NETSTREAM_EVENT, "onID3", event.ID3Data);
        };

        private function _manifestHandler(event : HLSEvent) : void {
            _duration = event.levels[_hls.startlevel].duration;
            _isManifestLoaded = true;
            _clip.duration = _duration;
            _clip.stopLiveOnPause = false;
            _clip.dispatch(ClipEventType.METADATA);
            _seekable = true;
            // if (_hls.type == HLSTypes.LIVE) {
            // _seekable = false;
            // } else {
            // _seekable = true;
            // }
            _hls.stream.play();
            _clip.dispatch(ClipEventType.SEEK,0);
            if (_pauseAfterStart) {
                pause(new ClipEvent(ClipEventType.PAUSE));
            }
        };

        private function _mediaTimeHandler(event : HLSEvent) : void {
            _position = Math.max(0, event.mediatime.position);
            _duration = event.mediatime.duration;
            _clip.duration = _duration;
            _bufferedTime = event.mediatime.buffer + event.mediatime.position;
            var videoWidth : int = _video.videoWidth;
            var videoHeight : int = _video.videoHeight;
            if (videoWidth && videoHeight) {
                var changed : Boolean = _videoWidth != videoWidth || _videoHeight != videoHeight;
                if (changed) {
                    CONFIG::LOGGING {
                    Log.info("video size changed to " + videoWidth + "/" + videoHeight);
                    }
                    _videoWidth = videoWidth;
                    _videoHeight = videoHeight;
                    _clip.originalWidth = videoWidth;
                    _clip.originalHeight = videoHeight;
                    _clip.dispatch(ClipEventType.START);
                    _clip.dispatch(ClipEventType.METADATA_CHANGED);
                }
            }
        };

        private function _stateHandler(event : HLSEvent) : void {
            // CONFIG::LOGGING {
            // Log.txt("state:"+ event.state);
            // }
            switch(event.state) {
                case HLSPlayStates.IDLE:
                case HLSPlayStates.PLAYING:
                case HLSPlayStates.PAUSED:
                    _clip.dispatch(ClipEventType.BUFFER_FULL);
                    break;
                case HLSPlayStates.PLAYING_BUFFERING:
                case HLSPlayStates.PAUSED_BUFFERING:
                    _clip.dispatch(ClipEventType.BUFFER_EMPTY);
                    break;
                default:
                    break;
            }
        };

        /**
         * Starts loading the specified clip. Once video data is available the provider
         * must set it to the clip using clip.setContent(). Typically the video
         * object passed to the clip is an instance of flash.media.Video.
         *
         * @param event the event that this provider should dispatch once loading has successfully started,
         * once dispatched the player will call getVideo()
         * @param clip the clip to load
         * @param pauseAfterStart if true the playback is paused on first frame and
         * buffering is continued
         * @see Clip#setContent()
         * @see #getVideo()
         */
        public function load(event : ClipEvent, clip : Clip, pauseAfterStart : Boolean = true) : void {
            _clip = clip;
            CONFIG::LOGGING {
            Log.info("load()" + clip.completeUrl);
            }
            _hls.load(clip.completeUrl);
            _pauseAfterStart = pauseAfterStart;
            clip.type = ClipType.VIDEO;
            clip.dispatch(ClipEventType.BEGIN);
            clip.setNetStream(_hls.stream);
            return;
        }

        /**
         * Gets the Video object.
         * A stream will be attached to the returned video object using attachStream().
         * @param clip the clip for which the Video object is queried for
         * @see #attachStream()
         */
        public function getVideo(clip : Clip) : DisplayObject {
            CONFIG::LOGGING {
            Log.debug("getVideo()");
            }
            if (_video == null) {
                if (clip.useStageVideo) {
                    CONFIG::LOGGING {
                    Log.debug("useStageVideo");
                    }
                    _video = new StageVideoWrapper(clip);
                } else {
                    _video = new Video();
                    _video.smoothing = clip.smoothing;
                }
            }
            return _video;
        }

        /**
         * Attaches a stream to the specified display object.
         * @param video the video object that was originally retrieved using getVideo().
         * @see #getVideo()
         */
        public function attachStream(video : DisplayObject) : void {
            CONFIG::LOGGING {
            Log.debug("attachStream()");
            }
            Video(video).attachNetStream(_hls.stream);
            return;
        }

        /**
         * Pauses playback.
         * @param event the event that this provider should dispatch once loading has been successfully paused
         */
        public function pause(event : ClipEvent) : void {
            CONFIG::LOGGING {
            Log.info("pause()");
            }
            _hls.stream.pause();
            if (event) {
                _clip.dispatch(ClipEventType.PAUSE);
            }
            return;
        }

        /**
         * Resumes playback.
         * @param event the event that this provider should dispatch once loading has been successfully resumed
         */
        public function resume(event : ClipEvent) : void {
            CONFIG::LOGGING {
            Log.info("resume()");
            }
            _hls.stream.resume();
            _clip.dispatch(ClipEventType.RESUME);
            return;
        }

        /**
         * Stops and rewinds to the beginning of current clip.
         * @param event the event that this provider should dispatch once loading has been successfully stopped
         */
        public function stop(event : ClipEvent, closeStream : Boolean = false) : void {
            CONFIG::LOGGING {
            Log.info("stop()");
            }
            _hls.stream.close();
            return;
        }

        /**
         * Seeks to the specified point in the timeline.
         * @param event the event that this provider should dispatch once the seek is in target
         * @param seconds the target point in the timeline
         */
        public function seek(event : ClipEvent, seconds : Number) : void {
            CONFIG::LOGGING {
            Log.info("seek()");
            }
            _hls.stream.seek(seconds);
            _position = seconds;
            _bufferedTime = seconds;
            _clip.dispatch(ClipEventType.SEEK, seconds);
            return;
        }

        /**
         * File size in bytes.
         */
        public function get fileSize() : Number {
            return 0;
        }

        /**
         * Current playhead time in seconds.
         */
        public function get time() : Number {
            return _position;
        }

        /**
         * The point in timeline where the buffered data region begins, in seconds.
         */
        public function get bufferStart() : Number {
            return 0;
        }

        /**
         * The point in timeline where the buffered data region ends, in seconds.
         */
        public function get bufferEnd() : Number {
            return _bufferedTime;
        }

        /**
         * Does this provider support random seeking to unbuffered areas in the timeline?
         */
        public function get allowRandomSeek() : Boolean {
            // CONFIG::LOGGING {
            // Log.info("allowRandomSeek()");
            // }
            return _seekable;
        }

        /**
         * Volume controller used to control the video volume.
         */
        public function set volumeController(controller : VolumeController) : void {
            _volumecontroller = controller;
            _volumecontroller.netStream = _hls.stream;
            return;
        }

        /**
         * Is this provider in the process of stopping the stream?
         * When stopped the provider should not dispatch any events resulting from events that
         * might get triggered by the underlying streaming implementation.
         */
        public function get stopping() : Boolean {
            CONFIG::LOGGING {
            Log.info("stopping()");
            }
            return false;
        }

        /**
         * The playlist instance.
         */
        public function set playlist(playlist : Playlist) : void {
            // CONFIG::LOGGING {
            // Log.debug("set playlist()");
            // }
            _playlist = playlist;
            return;
        }

        public function get playlist() : Playlist {
            CONFIG::LOGGING {
            Log.debug("get playlist()");
            }
            return _playlist;
        }

        /**
         * Adds a callback public function to the NetConnection instance. This public function will fire ClipEvents whenever
         * the callback is invoked in the connection.
         * @param name
         * @param listener
         * @return
         * @see ClipEventType#CONNECTION_EVENT
         */
        public function addConnectionCallback(name : String, listener : Function) : void {
            CONFIG::LOGGING {
            Log.debug("addConnectionCallback()");
            }
            return;
        }

        /**
         * Adds a callback public function to the NetStream object. This public function will fire a ClipEvent of type StreamEvent whenever
         * the callback has been invoked on the stream. The invokations typically come from a server-side app running
         * on RTMP server.
         * @param name
         * @param listener
         * @return
         * @see ClipEventType.NETSTREAM_EVENT
         */
        public function addStreamCallback(name : String, listener : Function) : void {
            CONFIG::LOGGING {
            Log.debug("addStreamCallback()");
            }
            return;
        }

        /**
         * Get the current stream callbacks.
         * @return a dictionary of callbacks, keyed using callback names and values being the callback functions
         */
        public function get streamCallbacks() : Dictionary {
            CONFIG::LOGGING {
            Log.debug("get streamCallbacks()");
            }
            return null;
        }

        /**
         * Gets the underlying NetStream object.
         * @return the netStream currently in use, or null if this provider has not started streaming yet
         */
        public function get netStream() : NetStream {
            CONFIG::LOGGING {
            Log.debug("get netStream()");
            }
            return _hls.stream;
        }

        /**
         * Gets the underlying netConnection object.
         * @return the netConnection currently in use, or null if this provider has not started streaming yet
         */
        public function get netConnection() : NetConnection {
            CONFIG::LOGGING {
            Log.debug("get netConnection()");
            }
            return null;
        }

        /**
         * Sets a time provider to be used by this StreamProvider. Normally the playhead time is queried from
         * the NetStream.time property.
         *
         * @param timeProvider
         */
        public function set timeProvider(timeProvider : TimeProvider) : void {
            CONFIG::LOGGING {
            Log.debug("set timeProvider()");
            }
            _timeProvider = timeProvider;
            return;
        }

        /**
         * Gets the type of StreamProvider either http, rtmp, psuedo.
         */
        public function get type() : String {
            return "httpstreaming";
        }

        /**
         * Switch the stream in realtime with / without dynamic stream switching support
         *
         * @param event ClipEvent the clip event
         * @param clip Clip the clip to switch to
         * @param netStreamPlayOptions Object the NetStreamPlayOptions object to enable dynamic stream switching
         */
        public function switchStream(event : ClipEvent, clip : Clip, netStreamPlayOptions : Object = null) : void {
            CONFIG::LOGGING {
            Log.info("switchStream()");
            }
            return;
        }
    }
}

flashlsFlowPlayer.swf: fix seek bar not being updated when replaying a video


package aerys.minko.type.vertex.format
{
	public class VertexFormat
	{
		public static const XYZ			: VertexFormat 	= new VertexFormat(VertexComponent.XYZ);
		public static const XYZ_RGB		: VertexFormat 	= new VertexFormat(VertexComponent.XYZ,
																		   VertexComponent.RGB);
		public static const XYZ_UV		: VertexFormat 	= new VertexFormat(VertexComponent.XYZ,
																		   VertexComponent.UV);
		public static const XYZ_UV_ST	: VertexFormat	= new VertexFormat(VertexComponent.XYZ,
																		   VertexComponent.UV,
																		   VertexComponent.ST);

		protected var _components : Object;

		private var _dwordsPerVertex	: int		= 0;
		private var _componentOffsets	: Object	= new Object();
		private var _fieldOffsets		: Object	= new Object();

		public function get components() 		: Object 	{ return _components; }
		public function get dwordsPerVertex()	: int		{ return _dwordsPerVertex; }

		public function VertexFormat(...components)
		{
			_components = new Object();

			if (components)
				initialize(components);
		}

		private function initialize(components : Array) : void
		{
			for each (var component : VertexComponent in components)
				addComponent(component);
		}

		private function addComponent(component : VertexComponent) : void
		{
			_components[component.implodedFields] = component;
			_componentOffsets[component.implodedFields] = _dwordsPerVertex;

			for (var fieldName : String in component.offsets)
				_fieldOffsets[fieldName] = _dwordsPerVertex + component.offsets[fieldName];

			_dwordsPerVertex += component.dwords;
		}

		/**
		 * Determine if this Vertex3DFormat has the specified component
		 */
		public function hasComponent(component : VertexComponent) : Boolean
		{
			return _components.hasOwnProperty(component.implodedFields);
		}

		/**
		 * Determine if this Vertex3DFormat is a subset of the Vertex3DFormat passed in attribute
		 */
		public function isSubsetOf(otherVertexFormat : VertexFormat) : Boolean
		{
			for (var implodedFields : String in _components)
				if (!otherVertexFormat._components.hasOwnProperty(implodedFields))
					return false;

			return true;
		}

		/**
		 * Add the components from the vertex format passed in attribute that we don't have in this one.
		 */
		public function unionWith(otherVertexFormat : VertexFormat) : void
		{
			for each (var component : VertexComponent in otherVertexFormat._components)
				addComponent(component);
		}

		public function getOffsetForComponent(component : VertexComponent) : int
		{
			return _componentOffsets[component.implodedFields];
		}

		public function getOffsetForField(fieldName:String) : int
		{
			return _fieldOffsets[fieldName];
		}
	}
}

package aerys.minko.type.vertex.format
{
	public class VertexFormat
	{
		public static const XYZ			: VertexFormat 	= new VertexFormat(VertexComponent.XYZ);
		public static const XYZ_RGB		: VertexFormat 	= new VertexFormat(VertexComponent.XYZ,
																		   VertexComponent.RGB);
		public static const XYZ_UV		: VertexFormat 	= new VertexFormat(VertexComponent.XYZ,
																		   VertexComponent.UV);
		public static const XYZ_UV_ST	: VertexFormat	= new VertexFormat(VertexComponent.XYZ,
																		   VertexComponent.UV,
																		   VertexComponent.ST);

		protected var _components : Object;

		private var _dwordsPerVertex	: int		= 0;
		private var _componentOffsets	: Object	= new Object();
		private var _fieldOffsets		: Object	= new Object();

		public function get components() 		: Object 	{ return _components; }
		public function get dwordsPerVertex()	: int		{ return _dwordsPerVertex; }

		public function VertexFormat(...components)
		{
			_components = new Object();

			if (components)
				initialize(components);
		}

		private function initialize(components : Array) : void
		{
			for each (var component : VertexComponent in components)
				addComponent(component);
		}

		public function addComponent(component : VertexComponent) : void
		{
			_components[component.implodedFields] = component;
			_componentOffsets[component.implodedFields] = _dwordsPerVertex;

			for (var fieldName : String in component.offsets)
				_fieldOffsets[fieldName] = _dwordsPerVertex + component.offsets[fieldName];

			_dwordsPerVertex += component.dwords;
		}

		/**
		 * Determine if this Vertex3DFormat has the specified component
		 */
		public function hasComponent(component : VertexComponent) : Boolean
		{
			return _components.hasOwnProperty(component.implodedFields);
		}

		/**
		 * Determine if this Vertex3DFormat is a subset of the Vertex3DFormat passed in attribute
		 */
		public function isSubsetOf(otherVertexFormat : VertexFormat) : Boolean
		{
			for (var implodedFields : String in _components)
				if (!otherVertexFormat._components.hasOwnProperty(implodedFields))
					return false;

			return true;
		}

		/**
		 * Add the components from the vertex format passed in attribute that we don't have in this one.
		 */
		public function unionWith(otherVertexFormat : VertexFormat) : void
		{
			for each (var component : VertexComponent in otherVertexFormat._components)
				addComponent(component);
		}

		public function getOffsetForComponent(component : VertexComponent) : int
		{
			return _componentOffsets[component.implodedFields];
		}

		public function getOffsetForField(fieldName : String) : int
		{
			return _fieldOffsets[fieldName];
		}
	}
}

Change the visibility of the "addComponent" method in VertexFormat


package common.mvc.model.base
{
	import hu.vizoli.common.mvc.actor.BaseActor;

	/**
	 * Base Model.
	 *
	 * @author vizoli
	 */
	public class BaseModel extends BaseActor
	{

		public function BaseModel()
		{

		}

	}

}

package common.mvc.model.base
{
    import common.mvc.actor.BaseActor;

	/**
	 * Base Model.
	 *
	 * @author vizoli
	 */
	public class BaseModel extends BaseActor
	{

		public function BaseModel()
		{

		}

	}

}

Fix import

Fix import


//
// $Id: $

package flash.utils {

import flash.events.EventDispatcher;
import flash.events.TimerEvent;

import de.polygonal.ds.Heap;

public class Timer extends EventDispatcher
{
    public function Timer (delay :Number, repeatCount :int = 0)
    {
        if (_heap == null) {
            _heap = new Heap(10000, compareTimers);
            Thane.requestHeartbeat(heartbeat);
        }

        _delay = delay;
        _repeatCount = repeatCount;
        reset();
    }

    public function get currentCount () :int
    {
        return _currentCount;
    }

    public function get delay () :Number
    {
        return _delay;
    }

    public function set delay (value :Number) :void
    {
        _delay = value;
        if (running) {
            stop();
            start();
        }
    }

    public function get repeatCount () :int
    {
        return _repeatCount;
    }

    public function get running () :Boolean
    {
        return _buddy != null;
    }

    public function start () :void
    {
        if (_buddy != null) {
            return;
        }

        scheduleBuddy(new Buddy(this));
    }

    public function stop () :void
    {
        // cut any current enqueued buddy adrift
        if (_buddy != null) {
            _buddy.budette = null;
            _buddy = null;
        }
    }

    public function reset () :void
    {
        stop();
        _currentCount = 0;
    }

    protected function expire (buddy :Buddy) :void
    {
        if (buddy !== _buddy) {
            // the timer was stopped since this buddy was enqueued
            return;
        }
        _currentCount ++;
        dispatchEvent(new TimerEvent(TimerEvent.TIMER));
        if (_buddy == null) {
            // the timer was stopped in the TIMER event itself - do not requeue!
            return;
        }

        if (repeatCount == 0 || _currentCount < _repeatCount) {
            scheduleBuddy(_buddy);

        } else {
            dispatchEvent(new TimerEvent(TimerEvent.TIMER_COMPLETE));
            _buddy = null;
        }
    }

    private function scheduleBuddy (buddy :Buddy) :void
    {
        _buddy = buddy;
        _buddy.expiration = getTimer() + Math.max(_delay, 5);
        if (_heap.enqueue(_buddy)) {
            return;
        }

        // TODO: formalize this as a quota rather than an implementation deficiency?
        throw new Error("Too many simultaneous running flash.utils.Timer objects");
    }

    private static function compareTimers (a :Buddy, b :Buddy) :int
    {
        // b-a rather than a-b so as to order low values before high
        return b.expiration - a.expiration;
    }

    protected static function heartbeat () :void
    {
        var now :int = getTimer();

        // see if we should pop one timer off the queue and expire it; we could pop all the
        // outstanding ones, but this solution puts the onus on developers to make their event
        // handlers light-weight, and protects the socket code from starvation
        if (_heap.size > 0 && _heap.front.expiration <= now) {
            var buddy :Buddy = _heap.dequeue();
            if (buddy.budette != null) {
                buddy.budette.expire(buddy);
            }
        }
    }

    static function createTimer (closure :Function, delay :Number,
                                 timeout :Boolean, args :Array) :uint
    {
        var timer :Timer = new Timer(delay, timeout ? 1 : 0);
        var thisIx = _timerIx;
        var fun :Function = function (event :TimerEvent) :void {
            if (timeout) {
                destroyTimer(thisIx);
            }
            closure.apply(null, args);
        };
        timer.addEventListener(TimerEvent.TIMER, fun);
        _timers[_timerIx] = [ timer, fun ];
        timer.start();
        return _timerIx ++;
    }

    static function destroyTimer (id :uint) :void
    {
        var bits :Array = _timers[id];
        if (bits) {
            bits[0].removeEventListener(TimerEvent.TIMER, bits[1]);
            bits[0].stop();
            delete _timers[id];
        }
    }

    private var _currentCount :int;
    private var _delay :Number;
    private var _repeatCount :int;
    private var _buddy :Buddy;

    private static var _heap :Heap;
    private static var _timers :Dictionary = new Dictionary();
    private static var _timerIx :uint = 1;
}
}

import flash.utils.Timer;
import flash.utils.getTimer;

class Buddy {
    public var budette :Timer;
    public var expiration :int;

    public function Buddy (timer :Timer)
    {
        this.budette = timer;
    }
}

//
// $Id: $

package flash.utils {

import flash.events.EventDispatcher;
import flash.events.TimerEvent;

import de.polygonal.ds.Heap;

public class Timer extends EventDispatcher
{
    public function Timer (delay :Number, repeatCount :int = 0)
    {
        if (_heap == null) {
            _heap = new Heap(10000, compareTimers);
            Thane.requestHeartbeat(heartbeat);
        }

        _delay = delay;
        _repeatCount = repeatCount;
        reset();
    }

    /** The total number of times the timer has fired since it started at zero. */
    public function get currentCount () :int
    {
        return _currentCount;
    }

    /** The delay, in milliseconds, between timer events. */
    public function get delay () :Number
    {
        return _delay;
    }

    /** The delay, in milliseconds, between timer events. */
    public function set delay (value :Number) :void
    {
        _delay = value;
        if (running) {
            stop();
            start();
        }
    }

    /** The total number of times the timer is set to run. */
    public function get repeatCount () :int
    {
        return _repeatCount;
    }

    /** The total number of times the timer is set to run. */
    public function set repeatCount (count :int) :void
    {
        _repeatCount = count;
        if (_repeatCount > 0 && _repeatCount < _currentCount) {
            stop();
        }
    }

    /** The timer's current state; true if the timer is running, otherwise false. */
    public function get running () :Boolean
    {
        return _buddy != null;
    }

    /**
     * Starts the timer, if it is not already running.
     */
    public function start () :void
    {
        if (_buddy != null) {
            return;
        }

        scheduleBuddy(new Buddy(this));
    }

    /**
     * Stops the timer.
     */
    public function stop () :void
    {
        // cut any current enqueued buddy adrift
        if (_buddy != null) {
            _buddy.budette = null;
            _buddy = null;
        }
    }

    /**
     * Stops the timer, if it is running, and sets the currentCount property back to 0,
     * like the reset button of a stopwatch.
     */
    public function reset () :void
    {
        stop();
        _currentCount = 0;
    }

    protected function expire (buddy :Buddy) :void
    {
        if (buddy !== _buddy) {
            // the timer was stopped since this buddy was enqueued
            return;
        }

        _currentCount ++;
        dispatchEvent(new TimerEvent(TimerEvent.TIMER));

        // if the timer was stop()'ed in the TIMER event itself, do not requeue!
        if (_buddy == null) {
            return;
        }

        // if we're repeating forever, or still got a ways to go, reschedule, else finish
        if (repeatCount == 0 || _currentCount < _repeatCount) {
            scheduleBuddy(_buddy);

        } else {
            dispatchEvent(new TimerEvent(TimerEvent.TIMER_COMPLETE));
            _buddy = null;
        }
    }

    private function scheduleBuddy (buddy :Buddy) :void
    {
        _buddy = buddy;
        _buddy.expiration = getTimer() + Math.max(_delay, 5);
        if (_heap.enqueue(_buddy)) {
            return;
        }

        // TODO: formalize this as a quota rather than an implementation deficiency?
        throw new Error("Too many simultaneous running flash.utils.Timer objects");
    }

    private static function compareTimers (a :Buddy, b :Buddy) :int
    {
        // b-a rather than a-b so as to order low values before high
        return b.expiration - a.expiration;
    }

    protected static function heartbeat () :void
    {
        var now :int = getTimer();

        // see if we should pop one timer off the queue and expire it; we could pop all the
        // outstanding ones, but this solution puts the onus on developers to make their event
        // handlers light-weight, and protects the socket code from starvation
        if (_heap.size > 0 && _heap.front.expiration <= now) {
            var buddy :Buddy = _heap.dequeue();
            if (buddy.budette != null) {
                buddy.budette.expire(buddy);
            }
        }
    }

    static function createTimer (closure :Function, delay :Number,
                                 timeout :Boolean, args :Array) :uint
    {
        var timer :Timer = new Timer(delay, timeout ? 1 : 0);
        var thisIx = _timerIx;
        var fun :Function = function (event :TimerEvent) :void {
            if (timeout) {
                destroyTimer(thisIx);
            }
            closure.apply(null, args);
        };
        timer.addEventListener(TimerEvent.TIMER, fun);
        _timers[_timerIx] = [ timer, fun ];
        timer.start();
        return _timerIx ++;
    }

    static function destroyTimer (id :uint) :void
    {
        var bits :Array = _timers[id];
        if (bits) {
            bits[0].removeEventListener(TimerEvent.TIMER, bits[1]);
            bits[0].stop();
            delete _timers[id];
        }
    }

    private var _currentCount :int;
    private var _delay :Number;
    private var _repeatCount :int;
    private var _buddy :Buddy;

    private static var _heap :Heap;
    private static var _timers :Dictionary = new Dictionary();
    private static var _timerIx :uint = 1;
}
}

import flash.utils.Timer;
import flash.utils.getTimer;

class Buddy {
    public var budette :Timer;
    public var expiration :int;

    public function Buddy (timer :Timer)
    {
        this.budette = timer;
    }
}

Make Timer.repeatCount writeable (and mimic Flash Player's behaviour when you set it to a value higher than the currentCount).