/* 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.hls {
    import org.mangui.hls.constant.HLSSeekMode;
    import org.mangui.hls.constant.HLSMaxLevelCappingMode;

    public final class HLSSettings extends Object {
        /**
         * capLevelToStage
         *
         * Limit levels usable in auto-quality by the stage dimensions (width and height).
         *      true - level width and height (defined in m3u8 playlist) will be compared with the player width and height (stage.stageWidth and stage.stageHeight).
         *             Max level will be set depending on the maxLevelCappingMode option.
         *      false - levels will not be limited. All available levels could be used in auto-quality mode taking only bandwidth into consideration.
         *
         * Note: this setting is ignored in manual mode so all the levels could be selected manually.
         *
         * Default is false
         */
        public static var capLevelToStage : Boolean = false;

        /**
         * maxLevelCappingMode
         *
         * Defines the max level capping mode to the one available in HLSMaxLevelCappingMode
         *      HLSMaxLevelCappingMode.DOWNSCALE - max capped level should be the one with the dimensions equal or greater than the stage dimensions (so the video will be downscaled)
         *      HLSMaxLevelCappingMode.UPSCALE - max capped level should be the one with the dimensions equal or lower than the stage dimensions (so the video will be upscaled)
         *
         * Default is HLSMaxLevelCappingMode.DOWNSCALE
         */
        public static var maxLevelCappingMode : String = HLSMaxLevelCappingMode.DOWNSCALE;

        // // // // // // /////////////////////////////////
        //
        // org.mangui.hls.stream.HLSNetStream
        //
        // // // // // // /////////////////////////////////
        /**
         * minBufferLength
         *
         * Defines minimum buffer length in seconds before playback can start, after seeking or buffer stalling.
         *
         * Default is -1 = auto
         */
        public static var minBufferLength : Number = -1;

        /**
         * maxBufferLength
         *
         * Defines maximum buffer length in seconds.
         * (0 means infinite buffering)
         *
         * Default is 120
         */
        public static var maxBufferLength : Number = 120;

        /**
         * maxBackBufferLength
         *
         * Defines maximum back buffer length in seconds.
         * (0 means infinite back buffering)
         *
         * Default is 30
         */
        public static var maxBackBufferLength : Number = 30;

        /**
         * lowBufferLength
         *
         * Defines low buffer length in seconds.
         * When crossing down this threshold, HLS will switch to buffering state.
         *
         * Default is 3
         */
        public static var lowBufferLength : Number = 3;

        /**
         * fpsDroppedMonitoringPeriod
         *
         * dropped FPS Monitor Period in ms
         * period at which nb dropped FPS will be checked
         * Default is 5000 ms
         */
        public static var fpsDroppedMonitoringPeriod : int = 5000;

        /**
         * fpsDroppedMonitoringThreshold
         *
         * dropped FPS Threshold
         * every fpsDroppedMonitoringPeriod, dropped FPS will be compared to displayed FPS.
         * if during that period, ratio of (dropped FPS/displayed FPS) is greater or equal
         * than fpsDroppedMonitoringThreshold, HLSEvent.FPS_DROP event will be fired
         * Default is 0.2 (20%)
         */
        public static var fpsDroppedMonitoringThreshold : Number = 0.2;

        /**
         * capLevelonFPSDrop
         *
         * Limit levels usable in auto-quality when FPS drop is detected
         * i.e. if frame drop is detected on level 5, auto level will be capped to level 4 a
         *      true -  enabled
         *      false - disabled
         *
         * Note: this setting is ignored in manual mode so all the levels could be selected manually.
         *
         * Default is true
         */
        public static var capLevelonFPSDrop : Boolean = true;

        /**
         * smoothAutoSwitchonFPSDrop
         *
         * force a smooth level switch Limit when FPS drop is detected in auto-quality
         * i.e. if frame drop is detected on level 5, it will trigger an auto quality level switch
         * to level 4 for next fragment
         *      true -  enabled
         *      false - disabled
         *
         * Note: this setting is active only if capLevelonFPSDrop==true
         *
         * Default is true
         */
        public static var smoothAutoSwitchonFPSDrop : Boolean = true;

        /**
         * seekMode
         *
         * Defines seek mode to one form available in HLSSeekMode class:
         *      HLSSeekMode.ACCURATE_SEEK - accurate seeking to exact requested position
         *      HLSSeekMode.KEYFRAME_SEEK - key-frame based seeking (seek to nearest key frame before requested seek position)
         *
         * Default is HLSSeekMode.KEYFRAME_SEEK
         */
        public static var seekMode : String = HLSSeekMode.KEYFRAME_SEEK;

        /**
         * keyLoadMaxRetry
         *
         * Max nb of retries for Key Loading in case I/O errors are met,
         *      0, means no retry, error will be triggered automatically
         *     -1 means infinite retry
         *
         * Default is 3
         */
        public static var keyLoadMaxRetry : int = 3;

        /**
         * keyLoadMaxRetryTimeout
         *
         * Maximum key retry timeout (in milliseconds) in case I/O errors are met.
         * Every fail on key request, player will exponentially increase the timeout to try again.
         * It starts waiting 1 second (1000ms), than 2, 4, 8, 16, until keyLoadMaxRetryTimeout is reached.
         *
         * Default is 64000.
         */
        public static var keyLoadMaxRetryTimeout : Number = 64000;

        /**
         * fragmentLoadMaxRetry
         *
         * Max number of retries for Fragment Loading in case I/O errors are met,
         *      0, means no retry, error will be triggered automatically
         *     -1 means infinite retry
         *
         * Default is 3
         */
        public static var fragmentLoadMaxRetry : int = 3;

        /**
         * fragmentLoadMaxRetryTimeout
         *
         * Maximum Fragment retry timeout (in milliseconds) in case I/O errors are met.
         * Every fail on fragment request, player will exponentially increase the timeout to try again.
         * It starts waiting 1 second (1000ms), than 2, 4, 8, 16, until fragmentLoadMaxRetryTimeout is reached.
         *
         * Default is 4000
         */
        public static var fragmentLoadMaxRetryTimeout : Number = 4000

        /**
         * fragmentLoadSkipAfterMaxRetry
         *
         * control behaviour in case fragment load still fails after max retry timeout
         * if set to true, fragment will be skipped and next one will be loaded.
         * If set to false, an I/O Error will be raised.
         *
         * Default is true.
         */
        public static var fragmentLoadSkipAfterMaxRetry : Boolean = true;

        /**
         * flushLiveURLCache
         *
         * If set to true, live playlist will be flushed from URL cache before reloading
         * (this is to workaround some cache issues with some combination of Flash Player / IE version)
         *
         * Default is false
         */
        public static var flushLiveURLCache : Boolean = false;

        /**
         * manifestLoadMaxRetry
         *
         * max nb of retries for Manifest Loading in case I/O errors are met,
         *      0, means no retry, error will be triggered automatically
         *     -1 means infinite retry
         */
        public static var manifestLoadMaxRetry : int = 3;

        /**
         * manifestLoadMaxRetryTimeout
         *
         * Maximum Manifest retry timeout (in milliseconds) in case I/O errors are met.
         * Every fail on fragment request, player will exponentially increase the timeout to try again.
         * It starts waiting 1 second (1000ms), than 2, 4, 8, 16, until manifestLoadMaxRetryTimeout is reached.
         *
         * Default is 64000
         */
        public static var manifestLoadMaxRetryTimeout : Number = 64000;

        /**
         * startFromBitrate
         *
         * If greater than 0, specifies the preferred bitrate.
         * If -1, and startFromLevel is not specified, automatic start level selection will be used.
         * This parameter, if set, will take priority over startFromLevel.
         *
         * Default is -1
         */
        public static var startFromBitrate : Number = -1;

        /**
         * startFromLevel
         *
         * start level :
         *  from 0 to 1 : indicates the "normalized" preferred level. As such, if it is 0.5, the closest to the middle bitrate will be selected and used first.
         * -1 : automatic start level selection, playback will start from level matching download bandwidth (determined from download of first segment)
         * -2 : playback will start from the first level appearing in Manifest (not sorted by bitrate)
         *
         * Default is -1
         */
        public static var startFromLevel : Number = -1;

        /**
         * seekFromLevel
         *
         * Seek level:
         *  from 0 to 1: indicates the "normalized" preferred bitrate. As such, if it is 0.5, the closest to the middle bitrate will be selected and used first.
         * -1 : automatic start level selection, keep previous level matching previous download bandwidth
         *
         * Default is -1
         */
        public static var seekFromLevel : Number = -1;

        /**
         * useHardwareVideoDecoder
         *
         * Use hardware video decoder:
         *  it will set NetStream.useHardwareDecoder
         *  refer to http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#useHardwareDecoder
         *
         * Default is true
         */
        public static var useHardwareVideoDecoder : Boolean = true;

        /**
         * logInfo
         *
         * Defines whether INFO level log messages will will appear in the console
         *
         * Default is true
         */
        public static var logInfo : Boolean = true;

        /**
         * logDebug
         *
         * Defines whether DEBUG level log messages will will appear in the console
         *
         * Default is false
         */
        public static var logDebug : Boolean = false;

        /**
         * logDebug2
         *
         * Defines whether DEBUG2 level log messages will will appear in the console
         *
         * Default is false
         */
        public static var logDebug2 : Boolean = false;

        /**
         * logWarn
         *
         * Defines whether WARN level log messages will will appear in the console
         *
         * Default is true
         */
        public static var logWarn : Boolean = true;

        /**
         * logError
         *
         * Defines whether ERROR level log messages will will appear in the console
         *
         * Default is true
         */
        public static var logError : Boolean = true;
    }
}

/* 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.hls {
    import org.mangui.hls.constant.HLSSeekMode;
    import org.mangui.hls.constant.HLSMaxLevelCappingMode;

    public final class HLSSettings extends Object {
        /**
         * capLevelToStage
         *
         * Limit levels usable in auto-quality by the stage dimensions (width and height).
         *      true - level width and height (defined in m3u8 playlist) will be compared with the player width and height (stage.stageWidth and stage.stageHeight).
         *             Max level will be set depending on the maxLevelCappingMode option.
         *      false - levels will not be limited. All available levels could be used in auto-quality mode taking only bandwidth into consideration.
         *
         * Note: this setting is ignored in manual mode so all the levels could be selected manually.
         *
         * Default is false
         */
        public static var capLevelToStage : Boolean = false;

        /**
         * maxLevelCappingMode
         *
         * Defines the max level capping mode to the one available in HLSMaxLevelCappingMode
         *      HLSMaxLevelCappingMode.DOWNSCALE - max capped level should be the one with the dimensions equal or greater than the stage dimensions (so the video will be downscaled)
         *      HLSMaxLevelCappingMode.UPSCALE - max capped level should be the one with the dimensions equal or lower than the stage dimensions (so the video will be upscaled)
         *
         * Default is HLSMaxLevelCappingMode.DOWNSCALE
         */
        public static var maxLevelCappingMode : String = HLSMaxLevelCappingMode.DOWNSCALE;

        // // // // // // /////////////////////////////////
        //
        // org.mangui.hls.stream.HLSNetStream
        //
        // // // // // // /////////////////////////////////
        /**
         * minBufferLength
         *
         * Defines minimum buffer length in seconds before playback can start, after seeking or buffer stalling.
         *
         * Default is -1 = auto
         */
        public static var minBufferLength : Number = -1;

        /**
         * maxBufferLength
         *
         * Defines maximum buffer length in seconds.
         * (0 means infinite buffering)
         *
         * Default is 120
         */
        public static var maxBufferLength : Number = 120;

        /**
         * maxBackBufferLength
         *
         * Defines maximum back buffer length in seconds.
         * (0 means infinite back buffering)
         *
         * Default is 30
         */
        public static var maxBackBufferLength : Number = 30;

        /**
         * lowBufferLength
         *
         * Defines low buffer length in seconds.
         * When crossing down this threshold, HLS will switch to buffering state.
         *
         * Default is 3
         */
        public static var lowBufferLength : Number = 3;

        /**
         * fpsDroppedMonitoringPeriod
         *
         * dropped FPS Monitor Period in ms
         * period at which nb dropped FPS will be checked
         * Default is 5000 ms
         */
        public static var fpsDroppedMonitoringPeriod : int = 5000;

        /**
         * fpsDroppedMonitoringThreshold
         *
         * dropped FPS Threshold
         * every fpsDroppedMonitoringPeriod, dropped FPS will be compared to displayed FPS.
         * if during that period, ratio of (dropped FPS/displayed FPS) is greater or equal
         * than fpsDroppedMonitoringThreshold, HLSEvent.FPS_DROP event will be fired
         * Default is 0.2 (20%)
         */
        public static var fpsDroppedMonitoringThreshold : Number = 0.2;

        /**
         * capLevelonFPSDrop
         *
         * Limit levels usable in auto-quality when FPS drop is detected
         * i.e. if frame drop is detected on level 5, auto level will be capped to level 4 a
         *      true -  enabled
         *      false - disabled
         *
         * Note: this setting is ignored in manual mode so all the levels could be selected manually.
         *
         * Default is true
         */
        public static var capLevelonFPSDrop : Boolean = true;

        /**
         * smoothAutoSwitchonFPSDrop
         *
         * force a smooth level switch Limit when FPS drop is detected in auto-quality
         * i.e. if frame drop is detected on level 5, it will trigger an auto quality level switch
         * to level 4 for next fragment
         *      true -  enabled
         *      false - disabled
         *
         * Note: this setting is active only if capLevelonFPSDrop==true
         *
         * Default is true
         */
        public static var smoothAutoSwitchonFPSDrop : Boolean = true;

        /**
         * seekMode
         *
         * Defines seek mode to one form available in HLSSeekMode class:
         *      HLSSeekMode.ACCURATE_SEEK - accurate seeking to exact requested position
         *      HLSSeekMode.KEYFRAME_SEEK - key-frame based seeking (seek to nearest key frame before requested seek position)
         *
         * Default is HLSSeekMode.KEYFRAME_SEEK
         */
        public static var seekMode : String = HLSSeekMode.KEYFRAME_SEEK;

        /**
         * keyLoadMaxRetry
         *
         * Max nb of retries for Key Loading in case I/O errors are met,
         *      0, means no retry, error will be triggered automatically
         *     -1 means infinite retry
         *
         * Default is 3
         */
        public static var keyLoadMaxRetry : int = 3;

        /**
         * keyLoadMaxRetryTimeout
         *
         * Maximum key retry timeout (in milliseconds) in case I/O errors are met.
         * Every fail on key request, player will exponentially increase the timeout to try again.
         * It starts waiting 1 second (1000ms), than 2, 4, 8, 16, until keyLoadMaxRetryTimeout is reached.
         *
         * Default is 64000.
         */
        public static var keyLoadMaxRetryTimeout : Number = 64000;

        /**
         * fragmentLoadMaxRetry
         *
         * Max number of retries for Fragment Loading in case I/O errors are met,
         *      0, means no retry, error will be triggered automatically
         *     -1 means infinite retry
         *
         * Default is 3
         */
        public static var fragmentLoadMaxRetry : int = 3;

        /**
         * fragmentLoadMaxRetryTimeout
         *
         * Maximum Fragment retry timeout (in milliseconds) in case I/O errors are met.
         * Every fail on fragment request, player will exponentially increase the timeout to try again.
         * It starts waiting 1 second (1000ms), than 2, 4, 8, 16, until fragmentLoadMaxRetryTimeout is reached.
         *
         * Default is 4000
         */
        public static var fragmentLoadMaxRetryTimeout : Number = 4000

        /**
         * fragmentLoadSkipAfterMaxRetry
         *
         * control behaviour in case fragment load still fails after max retry timeout
         * if set to true, fragment will be skipped and next one will be loaded.
         * If set to false, an I/O Error will be raised.
         *
         * Default is true.
         */
        public static var fragmentLoadSkipAfterMaxRetry : Boolean = true;

        /**
         * flushLiveURLCache
         *
         * If set to true, live playlist will be flushed from URL cache before reloading
         * (this is to workaround some cache issues with some combination of Flash Player / IE version)
         *
         * Default is false
         */
        public static var flushLiveURLCache : Boolean = false;

        /**
         * manifestLoadMaxRetry
         *
         * max nb of retries for Manifest Loading in case I/O errors are met,
         *      0, means no retry, error will be triggered automatically
         *     -1 means infinite retry
         */
        public static var manifestLoadMaxRetry : int = 3;

        /**
         * manifestLoadMaxRetryTimeout
         *
         * Maximum Manifest retry timeout (in milliseconds) in case I/O errors are met.
         * Every fail on fragment request, player will exponentially increase the timeout to try again.
         * It starts waiting 1 second (1000ms), than 2, 4, 8, 16, until manifestLoadMaxRetryTimeout is reached.
         *
         * Default is 64000
         */
        public static var manifestLoadMaxRetryTimeout : Number = 64000;

        /**
         * startFromBitrate
         *
         * If greater than 0, specifies the preferred bitrate.
         * If -1, and startFromLevel is not specified, automatic start level selection will be used.
         * This parameter, if set, will take priority over startFromLevel.
         *
         * Default is -1
         */
        public static var startFromBitrate : Number = -1;

        /**
         * startFromLevel
         *
         * start level :
         *  from 0 to 1 : indicates the "normalized" preferred level. As such, if it is 0.5, the closest to the middle bitrate will be selected and used first.
         * -1 : automatic start level selection, playback will start from level matching download bandwidth (determined from download of first segment)
         * -2 : playback will start from the first level appearing in Manifest (not sorted by bitrate)
         *
         * Default is -1
         */
        public static var startFromLevel : Number = -1;

        /**
         * seekFromLevel
         *
         * Seek level:
         *  from 0 to 1: indicates the "normalized" preferred bitrate. As such, if it is 0.5, the closest to the middle bitrate will be selected and used first.
         * -1 : automatic start level selection, keep previous level matching previous download bandwidth
         *
         * Default is -1
         */
        public static var seekFromLevel : Number = -1;

        /**
         * useHardwareVideoDecoder
         *
         * Use hardware video decoder:
         *  it will set NetStream.useHardwareDecoder
         *  refer to http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#useHardwareDecoder
         *
         * Default is true
         */
        public static var useHardwareVideoDecoder : Boolean = true;

        /**
         * logInfo
         *
         * Defines whether INFO level log messages will will appear in the console
         *
         * Default is true
         */
        public static var logInfo : Boolean = true;

        /**
         * logDebug
         *
         * Defines whether DEBUG level log messages will will appear in the console
         *
         * Default is false
         */
        public static var logDebug : Boolean = false;

        /**
         * logDebug2
         *
         * Defines whether DEBUG2 level log messages will will appear in the console
         *
         * Default is false
         */
        public static var logDebug2 : Boolean = false;

        /**
         * logWarn
         *
         * Defines whether WARN level log messages will will appear in the console
         *
         * Default is true
         */
        public static var logWarn : Boolean = true;

        /**
         * logError
         *
         * Defines whether ERROR level log messages will will appear in the console
         *
         * Default is true
         */
        public static var logError : Boolean = true;

        /**
         * recoverFromNonIDRStartFragment
         *
         * Load same sequence Fragment from previous Level and splice with
         * current Fragment when that Fragment does not start with necessary
         * AVC header.
         *
         * Default is true
         */
        public static var recoverFromNonIDRStartFragment : Boolean = true;
    }
}

[HLSSettings] Add HLSSettings.recoverFromNonIDRStartFragment


package battlecode.client.viewer.render {
    import battlecode.common.ResearchType;

    import flash.utils.getTimer;

    import mx.containers.Canvas;
    import mx.controls.Image;

    public class DrawHUDResearch extends Canvas {
        private var image:Image;
        private var type:String;
        private var progress:Number;

        public function DrawHUDResearch(type:String) {
            width = 50;
            height = 50;

            horizontalScrollPolicy = "off";
            verticalScrollPolicy = "off";

            image = new Image();
            image.source = ResearchType.getImageAsset(type);
            image.width = 50;
            image.height = 50;
            image.x = 0;
            image.y = 0;

            progress = 0;
            this.type = type;

            addChild(image);
        }

        public function resize(size:Number):void {
            width = Math.max(size, 50);
            image.x = size - 50;
        }

        public function setProgress(val:Number):void {
            progress = val;
            draw();
        }

        public function getProgress():Number {
            return progress;
        }

        public function draw():void {
            if (progress == 0) {
                visible = false;
                return;
            }

            visible = true;
            this.graphics.clear();

            var color:uint = progress < 1.0 ? 0x00FFFF : 0x00FF00;
            if (progress < 1.0 && progress > 0.5
                    && type == ResearchType.NUKE && Math.floor(getTimer() / 400) % 2 == 0) {
                color = 0xFFFF66;
            }

            // draw progress bar
            var progressBarWidth:Number = width - image.width;
            this.graphics.lineStyle();
            this.graphics.beginFill(color, 0.8);
            this.graphics.drawRect(0, (height / 2) - 2.5, progress * progressBarWidth, 5);
            this.graphics.endFill();
            this.graphics.beginFill(0x000000, 0.8);
            this.graphics.drawRect(progress * progressBarWidth, (height / 2) - 2.5, (1 - progress) * progressBarWidth, 5);
            this.graphics.endFill();
        }

    }

}

package battlecode.client.viewer.render {
    import battlecode.common.ResearchType;

    import flash.utils.getTimer;

    import mx.containers.Canvas;
    import mx.controls.Image;

    public class DrawHUDResearch extends Canvas {
        private var image:Image;
        private var type:String;
        private var progress:Number;

        public function DrawHUDResearch(type:String) {
            width = 50;
            height = 50;

            horizontalScrollPolicy = "off";
            verticalScrollPolicy = "off";

            toolTip = type;

            image = new Image();
            image.source = ResearchType.getImageAsset(type);
            image.width = 50;
            image.height = 50;
            image.x = 0;
            image.y = 0;

            progress = 0;
            this.type = type;

            addChild(image);
        }

        public function resize(size:Number):void {
            width = Math.max(size, 50);
            image.x = size - 50;
        }

        public function setProgress(val:Number):void {
            progress = val;
            draw();
        }

        public function getProgress():Number {
            return progress;
        }

        public function draw():void {
            if (progress == 0) {
                visible = false;
                return;
            }

            visible = true;
            this.graphics.clear();

            var color:uint = progress < 1.0 ? 0x00FFFF : 0x00FF00;
            if (progress < 1.0 && progress > 0.5
                    && type == ResearchType.NUKE && Math.floor(getTimer() / 400) % 2 == 0) {
                color = 0xFFFF66;
            }

            // draw progress bar
            var progressBarWidth:Number = width - image.width;
            this.graphics.lineStyle();
            this.graphics.beginFill(color, 0.8);
            this.graphics.drawRect(0, (height / 2) - 2.5, progress * progressBarWidth, 5);
            this.graphics.endFill();
            this.graphics.beginFill(0x000000, 0.8);
            this.graphics.drawRect(progress * progressBarWidth, (height / 2) - 2.5, (1 - progress) * progressBarWidth, 5);
            this.graphics.endFill();
        }

    }

}

add tooltips for research progress indicators


package com.kaltura.kdpfl.plugin
{
	import com.akamai.playeranalytics.AnalyticsPluginLoader;
	import com.kaltura.kdpfl.model.ConfigProxy;
	import com.kaltura.kdpfl.model.MediaProxy;
	import com.kaltura.kdpfl.model.type.NotificationType;
	import com.kaltura.kdpfl.model.type.StreamerType;
	import com.kaltura.types.KalturaMediaType;
	import com.kaltura.vo.KalturaBaseEntry;
	import com.kaltura.vo.KalturaFlavorAsset;
	import com.kaltura.vo.KalturaMediaEntry;

	import flash.system.Capabilities;

	import org.puremvc.as3.interfaces.INotification;
	import org.puremvc.as3.patterns.mediator.Mediator;

	public class akamaiMediaAnalyticsMediator extends Mediator
	{
		public static const NAME:String = "akamaiMediaAnalyticsMediator";
		private var _mediaProxy:MediaProxy;

		public function akamaiMediaAnalyticsMediator(viewComponent:Object=null)
		{
			super(NAME, viewComponent);
		}

		override public function onRegister():void
		{
			_mediaProxy = facade.retrieveProxy(MediaProxy.NAME) as MediaProxy;
			super.onRegister();
		}

		override public function listNotificationInterests():Array
		{
			return [NotificationType.MEDIA_READY, NotificationType.MEDIA_ELEMENT_READY, NotificationType.SWITCHING_CHANGE_COMPLETE];
		}

		override public function handleNotification(notification:INotification):void
		{
			switch (notification.getName())
			{
				case NotificationType.MEDIA_READY:
					//populate analytics metadata
					var configProxy:ConfigProxy = facade.retrieveProxy(ConfigProxy.NAME) as ConfigProxy;
					var entry:KalturaBaseEntry = _mediaProxy.vo.entry;

					AnalyticsPluginLoader.setData("title", entry.id);

					AnalyticsPluginLoader.setData("category", entry.categories);

					//since we don't have a partnerID field, we will send it as "subCategory"
					AnalyticsPluginLoader.setData("subCategory", configProxy.vo.flashvars.partnerId);

					//find content type
					if (entry is KalturaMediaEntry)
					{
						var mediaEntry:KalturaMediaEntry = entry as KalturaMediaEntry;

						AnalyticsPluginLoader.setData("contentLength", mediaEntry.duration);
						var contentType:String;
						switch (mediaEntry.mediaType)
						{
							case KalturaMediaType.VIDEO:
								contentType = "video";
								break;
							case KalturaMediaType.AUDIO:
								contentType = "audio";
								break;
							case KalturaMediaType.IMAGE:
								contentType = "image";
								break;
							default:
								contentType = "live";
						}
						AnalyticsPluginLoader.setData("contentType", contentType);
					}

					AnalyticsPluginLoader.setData("device", Capabilities.os );
					AnalyticsPluginLoader.setData("playerId", configProxy.vo.flashvars.uiConfId);

					break;

				case NotificationType.SWITCHING_CHANGE_COMPLETE:
					AnalyticsPluginLoader.setData("show", getFlavorIdByIndex(notification.getBody().newIndex));
					break;

				case NotificationType.MEDIA_ELEMENT_READY:
					//find starting flavor ID
					var flavorId:String;
					if (_mediaProxy.vo.deliveryType == StreamerType.HTTP)
					{
						flavorId = _mediaProxy.vo.selectedFlavorId;
					}
					else if (_mediaProxy.vo.deliveryType == StreamerType.RTMP)
					{
						flavorId = getFlavorIdByIndex(_mediaProxy.startingIndex);
					}

					//since we don't have "flavor" field, we will send it as "show"
					if (flavorId)
						AnalyticsPluginLoader.setData("show", flavorId);

					break;
			}
		}

		/**
		 * returns the id of the flavor asset in the given index. null if index is invalid.
		 * @param index
		 * @return
		 *
		 */
		private function getFlavorIdByIndex(index:int):String
		{
			var flavorId:String;

			if (index >= 0 &&
				_mediaProxy.vo.kalturaMediaFlavorArray &&
				index < _mediaProxy.vo.kalturaMediaFlavorArray.length)	{

				flavorId = (_mediaProxy.vo.kalturaMediaFlavorArray[index] as KalturaFlavorAsset).id;
			}

			return flavorId;
		}
	}
}

package com.kaltura.kdpfl.plugin
{
	import com.akamai.playeranalytics.AnalyticsPluginLoader;
	import com.kaltura.kdpfl.model.ConfigProxy;
	import com.kaltura.kdpfl.model.MediaProxy;
	import com.kaltura.kdpfl.model.type.NotificationType;
	import com.kaltura.kdpfl.model.type.StreamerType;
	import com.kaltura.types.KalturaMediaType;
	import com.kaltura.vo.KalturaBaseEntry;
	import com.kaltura.vo.KalturaFlavorAsset;
	import com.kaltura.vo.KalturaMediaEntry;

	import flash.system.Capabilities;

	import org.puremvc.as3.interfaces.INotification;
	import org.puremvc.as3.patterns.mediator.Mediator;

	public class akamaiMediaAnalyticsMediator extends Mediator
	{
		public static const NAME:String = "akamaiMediaAnalyticsMediator";
		private var _mediaProxy:MediaProxy;

		public function akamaiMediaAnalyticsMediator(viewComponent:Object=null)
		{
			super(NAME, viewComponent);
		}

		override public function onRegister():void
		{
			_mediaProxy = facade.retrieveProxy(MediaProxy.NAME) as MediaProxy;
			super.onRegister();
		}

		override public function listNotificationInterests():Array
		{
			return [NotificationType.MEDIA_READY, NotificationType.MEDIA_ELEMENT_READY, NotificationType.SWITCHING_CHANGE_COMPLETE];
		}

		override public function handleNotification(notification:INotification):void
		{
			switch (notification.getName())
			{
				case NotificationType.MEDIA_READY:
					//populate analytics metadata
					var configProxy:ConfigProxy = facade.retrieveProxy(ConfigProxy.NAME) as ConfigProxy;
					var entry:KalturaBaseEntry = _mediaProxy.vo.entry;

					AnalyticsPluginLoader.setData("title", entry.name);
					AnalyticsPluginLoader.setData("entryId", entry.id);
					AnalyticsPluginLoader.setData("category", entry.categories);
					AnalyticsPluginLoader.setData("partnerId", configProxy.vo.flashvars.partnerId);

					//find content type
					if (entry is KalturaMediaEntry)
					{
						var mediaEntry:KalturaMediaEntry = entry as KalturaMediaEntry;

						AnalyticsPluginLoader.setData("contentLength", mediaEntry.duration);
						var contentType:String;
						switch (mediaEntry.mediaType)
						{
							case KalturaMediaType.VIDEO:
								contentType = "video";
								break;
							case KalturaMediaType.AUDIO:
								contentType = "audio";
								break;
							case KalturaMediaType.IMAGE:
								contentType = "image";
								break;
							default:
								contentType = "live";
						}
						AnalyticsPluginLoader.setData("contentType", contentType);
					}

					AnalyticsPluginLoader.setData("device", Capabilities.os );
					AnalyticsPluginLoader.setData("playerId", configProxy.vo.flashvars.uiConfId);

					break;

				case NotificationType.SWITCHING_CHANGE_COMPLETE:
					AnalyticsPluginLoader.setData("flavorId", getFlavorIdByIndex(notification.getBody().newIndex));
					break;

				case NotificationType.MEDIA_ELEMENT_READY:
					//find starting flavor ID
					var flavorId:String;
					if (_mediaProxy.vo.deliveryType == StreamerType.HTTP)
					{
						flavorId = _mediaProxy.vo.selectedFlavorId;
					}
					else if (_mediaProxy.vo.deliveryType == StreamerType.RTMP)
					{
						flavorId = getFlavorIdByIndex(_mediaProxy.startingIndex);
					}

					if (flavorId)
						AnalyticsPluginLoader.setData("flavorId", flavorId);

					break;
			}
		}

		/**
		 * returns the id of the flavor asset in the given index. null if index is invalid.
		 * @param index
		 * @return
		 *
		 */
		private function getFlavorIdByIndex(index:int):String
		{
			var flavorId:String;

			if (index >= 0 &&
				_mediaProxy.vo.kalturaMediaFlavorArray &&
				index < _mediaProxy.vo.kalturaMediaFlavorArray.length)	{

				flavorId = (_mediaProxy.vo.kalturaMediaFlavorArray[index] as KalturaFlavorAsset).id;
			}

			return flavorId;
		}
	}
}

fix names

qnd: fix names

git-svn-id: 3f608e5a9a704dd448217c0a64c508e7f145cfa1@87235 6b8eccd3-e8c5-4e7d-8186-e12b5326b719


package flexlib.styles
{
	import flash.utils.getQualifiedClassName;

	import mx.core.FlexVersion;

	public class StyleDeclarationHelper
	{

		/**
		 * Gets the style selector for the specified class.
		 * @see getStyleSelectorForClassName
		 *
		 * @param c The component class to get the style selector for
		 * @return style selector string for given class
		 *
		 */
		public static function getStyleSelectorForClass(c:Class):String
		{
			return getStyleSelectorForClassName(flash.utils.getQualifiedClassName(c));
		}

		/**
		 * Gets the style selector for the specified class name.
		 *
		 * Starting in Flex 4, component selectors passed to StyleManager.getStyleDeclaration and StyleManager.setStyleDeclaration
		 * must be fully qualified class names. In versions of Flex < 4, the class name itself was used.
		 *
		 * @see http://flexdevtips.blogspot.com/2009/03/setting-default-styles-for-custom.html
		 *
		 * @param fullyQualifiedName The fully qualified name of the class to get the selector for
		 * @return style selector string
		 *
		 */
		public static function getStyleSelectorForClassName(fullyQualifiedName:String):String
		{
			if (FlexVersion.compatibilityVersion >= FlexVersion.VERSION_4_0)
				return fullyQualifiedName.replace("::", ".");

			var classNameStart:int = fullyQualifiedName.lastIndexOf(":");
			if(classNameStart != -1)
				return fullyQualifiedName.substr(classNameStart + 1);
			return fullyQualifiedName;
		}
	}
}

Fix asdoc generation broken

Fix asdoc generation broken


package aerys.minko.render.shader.compiler.graph
{
	import aerys.minko.Minko;
	import aerys.minko.render.geometry.stream.format.VertexComponent;
	import aerys.minko.render.resource.Program3DResource;
	import aerys.minko.render.resource.texture.ITextureResource;
	import aerys.minko.render.shader.Signature;
	import aerys.minko.render.shader.compiler.graph.nodes.AbstractNode;
	import aerys.minko.render.shader.compiler.graph.visitors.*;
	import aerys.minko.render.shader.compiler.register.Components;
	import aerys.minko.render.shader.compiler.sequence.AgalInstruction;
	import aerys.minko.type.log.DebugLevel;

	import flash.utils.ByteArray;
	import flash.utils.Endian;

	/**
	 * @private
	 * @author Romain Gilliotte
	 *
	 */
	public class ShaderGraph
	{
		private static const SPLITTER				: SplitterVisitor						= new SplitterVisitor();
		private static const REMOVE_EXTRACT			: RemoveExtractsVisitor					= new RemoveExtractsVisitor();
		private static const MERGER					: MergeVisitor							= new MergeVisitor();
		private static const OVERWRITER_CLEANER		: OverwriterCleanerVisitor				= new OverwriterCleanerVisitor();
		private static const RESOLVE_CONSTANT		: ResolveConstantComputationVisitor		= new ResolveConstantComputationVisitor();
		private static const CONSTANT_PACKER		: ConstantPackerVisitor					= new ConstantPackerVisitor();
		private static const CONSTANT_GROUPER		: ConstantGrouperVisitor				= new ConstantGrouperVisitor();
		private static const RESOLVE_PARAMETRIZED	: ResolveParametrizedComputationVisitor	= new ResolveParametrizedComputationVisitor();
		private static const REMOVE_USELESS			: RemoveUselessComputation				= new RemoveUselessComputation();
		private static const COPY_INSERTER			: CopyInserterVisitor					= new CopyInserterVisitor();
		private static const ALLOCATOR				: AllocationVisitor						= new AllocationVisitor();
		private static const INTERPOLATE_FINDER		: InterpolateFinder						= new InterpolateFinder();
		private static const WRITE_DOT				: WriteDot								= new WriteDot();
		private static const MATRIX_TRANSFORMATION	: MatrixTransformationGrouper			= new MatrixTransformationGrouper();

		private var _position				: AbstractNode;
		private var _positionComponents		: uint;
		private var _interpolates			: Vector.<AbstractNode>;
		private var _color					: AbstractNode;
		private var _colorComponents		: uint;
		private var _kills					: Vector.<AbstractNode>;
		private var _killComponents			: Vector.<uint>;
		private var _computableConstants	: Object;

		private var _isCompiled				: Boolean;

		private var _vertexSequence			: Vector.<AgalInstruction>;
		private var _fragmentSequence		: Vector.<AgalInstruction>;
		private var _bindings				: Object;

		private var _vertexComponents		: Vector.<VertexComponent>;
		private var _vertexIndices			: Vector.<uint>;
		private var _vsConstants			: Vector.<Number>;
		private var _fsConstants			: Vector.<Number>;
		private var _textures				: Vector.<ITextureResource>;

		public function get position() : AbstractNode
		{
			return _position;
		}
		public function set position(v : AbstractNode)	: void
		{
			_position = v;
		}

		public function get interpolates() : Vector.<AbstractNode>
		{
			return _interpolates;
		}

		public function get color() : AbstractNode
		{
			return _color;
		}
		public function set color(v : AbstractNode)	: void
		{
			_color = v;
		}

		public function get kills() : Vector.<AbstractNode>
		{
			return _kills;
		}

		public function get positionComponents() : uint
		{
			return _positionComponents;
		}
		public function set positionComponents(v : uint) : void
		{
			_positionComponents = v;
		}

		public function get colorComponents() : uint
		{
			return _colorComponents;
		}
		public function set colorComponents(v : uint) : void
		{
			_colorComponents = v;
		}

		public function get killComponents() : Vector.<uint>
		{
			return _killComponents;
		}

		public function get computableConstants() : Object
		{
			return _computableConstants;
		}

		public function ShaderGraph(position	: AbstractNode,
									color		: AbstractNode,
									kills		: Vector.<AbstractNode>)
		{
			_isCompiled				= false;

			_position				= position;
			_positionComponents		= Components.createContinuous(0, 0, 4, position.size);
			_interpolates			= new Vector.<AbstractNode>();
			_color					= color;
			_colorComponents		= Components.createContinuous(0, 0, 4, color.size);
			_kills					= kills;
			_killComponents			= new Vector.<uint>();
			_computableConstants	= new Object();

			var numKills : uint = kills.length;
			for (var killId : uint = 0; killId < numKills; ++killId)
				_killComponents[killId] = Components.createContinuous(0, 0, 1, 1);
		}

		public function generateProgram(name : String, signature : Signature) : Program3DResource
		{
			if (!_isCompiled)
				compile();

			if (Minko.debugLevel & DebugLevel.SHADER_AGAL)
				Minko.log(DebugLevel.SHADER_AGAL, generateAGAL(name));

			var vsProgram	: ByteArray = computeBinaryProgram(_vertexSequence, true);
			var fsProgram	: ByteArray = computeBinaryProgram(_fragmentSequence, false);

			var program : Program3DResource = new Program3DResource(
				name,
				signature,
				vsProgram,
				fsProgram,
				_vertexComponents,
				_vertexIndices,
				_vsConstants,
				_fsConstants,
				_textures,
				_bindings
			);

			return program;
		}

		public function generateAGAL(name : String) : String
		{
			var instruction	: AgalInstruction;
			var shader		: String = name + "\n";

			if (!_isCompiled)
				compile();

			shader += "- vertex shader\n";
			for each (instruction in _vertexSequence)
				shader += instruction.getAgal(true);

			shader += "- fragment shader\n";
			for each (instruction in _fragmentSequence)
				shader += instruction.getAgal(false);

			return shader;
		}

		private function compile() : void
		{
			// execute consecutive visitors to optimize the shader graph.
			// Warning: the order matters, do not swap lines.
			MERGER					.process(this);	// merge duplicate nodes
			REMOVE_EXTRACT			.process(this);	// remove all extract nodes
			OVERWRITER_CLEANER		.process(this);	// remove nested overwriters
			RESOLVE_CONSTANT		.process(this);	// resolve constant computation
			CONSTANT_PACKER			.process(this);	// pack constants [0,0,0,1] => [0,1].xxxy
			REMOVE_USELESS			.process(this);	// remove some useless operations (add 0, mul 0, mul 1...)
//			RESOLVE_PARAMETRIZED	.process(this);	// replace computations that depend on parameters by evalexp parameters
//			MATRIX_TRANSFORMATION	.process(this);	// replace ((vector * matrix1) * matrix2) by vector * (matrix1 * matrix2) to save registers on GPU
			COPY_INSERTER			.process(this);	// ensure there are no operations between constants
			SPLITTER				.process(this);	// clone nodes that are shared between vertex and fragment shader
			CONSTANT_GROUPER		.process(this);	// group constants [0,1] & [0,2] => [0, 1, 2]

			if (Minko.debugLevel & DebugLevel.SHADER_DOTTY)
			{
				WRITE_DOT.process(this);
				Minko.log(DebugLevel.SHADER_DOTTY, WRITE_DOT.result);
				WRITE_DOT.clear();
			}

			// generate final program
			INTERPOLATE_FINDER		.process(this);	// find interpolate nodes. We may skip that in the future.
			ALLOCATOR				.process(this);	// allocate memory and generate final code.

			// retrieve program
			_vertexSequence		= ALLOCATOR.vertexSequence;
			_fragmentSequence	= ALLOCATOR.fragmentSequence;
			_bindings			= ALLOCATOR.parameterBindings;
			_vertexComponents	= ALLOCATOR.vertexComponents;
			_vertexIndices		= ALLOCATOR.vertexIndices;
			_vsConstants		= ALLOCATOR.vertexConstants;
			_fsConstants		= ALLOCATOR.fragmentConstants;
			_textures			= ALLOCATOR.textures;

			ALLOCATOR.clear();

			_isCompiled = true;
		}

		private function computeBinaryProgram(sequence			: Vector.<AgalInstruction>,
											  isVertexShader	: Boolean) : ByteArray
		{
			var program : ByteArray = new ByteArray();

			program.endian = Endian.LITTLE_ENDIAN;
			program.writeByte(0xa0);					// tag version
			program.writeUnsignedInt(1);				// AGAL version, big endian, bit pattern will be 0x01000000
			program.writeByte(0xa1);					// tag program id
			program.writeByte(isVertexShader ? 0 : 1);	// vertex or fragment

			for each (var instruction : AgalInstruction in sequence)
				instruction.getBytecode(program);

			return program;
		}
	}
}

package aerys.minko.render.shader.compiler.graph
{
	import aerys.minko.Minko;
	import aerys.minko.render.geometry.stream.format.VertexComponent;
	import aerys.minko.render.resource.Program3DResource;
	import aerys.minko.render.resource.texture.ITextureResource;
	import aerys.minko.render.shader.Signature;
	import aerys.minko.render.shader.compiler.graph.nodes.AbstractNode;
	import aerys.minko.render.shader.compiler.graph.visitors.*;
	import aerys.minko.render.shader.compiler.register.Components;
	import aerys.minko.render.shader.compiler.sequence.AgalInstruction;
	import aerys.minko.type.log.DebugLevel;

	import flash.utils.ByteArray;
	import flash.utils.Endian;

	/**
	 * @private
	 * @author Romain Gilliotte
	 *
	 */
	public class ShaderGraph
	{
		private static const SPLITTER				: SplitterVisitor						= new SplitterVisitor();
		private static const REMOVE_EXTRACT			: RemoveExtractsVisitor					= new RemoveExtractsVisitor();
		private static const MERGER					: MergeVisitor							= new MergeVisitor();
		private static const OVERWRITER_CLEANER		: OverwriterCleanerVisitor				= new OverwriterCleanerVisitor();
		private static const RESOLVE_CONSTANT		: ResolveConstantComputationVisitor		= new ResolveConstantComputationVisitor();
		private static const CONSTANT_PACKER		: ConstantPackerVisitor					= new ConstantPackerVisitor();
		private static const CONSTANT_GROUPER		: ConstantGrouperVisitor				= new ConstantGrouperVisitor();
		private static const RESOLVE_PARAMETRIZED	: ResolveParametrizedComputationVisitor	= new ResolveParametrizedComputationVisitor();
		private static const REMOVE_USELESS			: RemoveUselessComputation				= new RemoveUselessComputation();
		private static const COPY_INSERTER			: CopyInserterVisitor					= new CopyInserterVisitor();
		private static const ALLOCATOR				: AllocationVisitor						= new AllocationVisitor();
		private static const INTERPOLATE_FINDER		: InterpolateFinder						= new InterpolateFinder();
		private static const WRITE_DOT				: WriteDot								= new WriteDot();
		private static const MATRIX_TRANSFORMATION	: MatrixTransformationGrouper			= new MatrixTransformationGrouper();

		private var _position				: AbstractNode;
		private var _positionComponents		: uint;
		private var _interpolates			: Vector.<AbstractNode>;
		private var _color					: AbstractNode;
		private var _colorComponents		: uint;
		private var _kills					: Vector.<AbstractNode>;
		private var _killComponents			: Vector.<uint>;
		private var _computableConstants	: Object;

		private var _isCompiled				: Boolean;

		private var _vertexSequence			: Vector.<AgalInstruction>;
		private var _fragmentSequence		: Vector.<AgalInstruction>;
		private var _bindings				: Object;

		private var _vertexComponents		: Vector.<VertexComponent>;
		private var _vertexIndices			: Vector.<uint>;
		private var _vsConstants			: Vector.<Number>;
		private var _fsConstants			: Vector.<Number>;
		private var _textures				: Vector.<ITextureResource>;

		public function get position() : AbstractNode
		{
			return _position;
		}
		public function set position(v : AbstractNode)	: void
		{
			_position = v;
		}

		public function get interpolates() : Vector.<AbstractNode>
		{
			return _interpolates;
		}

		public function get color() : AbstractNode
		{
			return _color;
		}
		public function set color(v : AbstractNode)	: void
		{
			_color = v;
		}

		public function get kills() : Vector.<AbstractNode>
		{
			return _kills;
		}

		public function get positionComponents() : uint
		{
			return _positionComponents;
		}
		public function set positionComponents(v : uint) : void
		{
			_positionComponents = v;
		}

		public function get colorComponents() : uint
		{
			return _colorComponents;
		}
		public function set colorComponents(v : uint) : void
		{
			_colorComponents = v;
		}

		public function get killComponents() : Vector.<uint>
		{
			return _killComponents;
		}

		public function get computableConstants() : Object
		{
			return _computableConstants;
		}

		public function ShaderGraph(position	: AbstractNode,
									color		: AbstractNode,
									kills		: Vector.<AbstractNode>)
		{
			_isCompiled				= false;

			_position				= position;
			_positionComponents		= Components.createContinuous(0, 0, 4, position.size);
			_interpolates			= new Vector.<AbstractNode>();
			_color					= color;
			_colorComponents		= Components.createContinuous(0, 0, 4, color.size);
			_kills					= kills;
			_killComponents			= new Vector.<uint>();
			_computableConstants	= new Object();

			var numKills : uint = kills.length;
			for (var killId : uint = 0; killId < numKills; ++killId)
				_killComponents[killId] = Components.createContinuous(0, 0, 1, 1);
		}

		public function generateProgram(name : String, signature : Signature) : Program3DResource
		{
			if (!_isCompiled)
				compile();

			if (Minko.debugLevel & DebugLevel.SHADER_AGAL)
				Minko.log(DebugLevel.SHADER_AGAL, generateAGAL(name));

			var vsProgram	: ByteArray = computeBinaryProgram(_vertexSequence, true);
			var fsProgram	: ByteArray = computeBinaryProgram(_fragmentSequence, false);

			var program : Program3DResource = new Program3DResource(
				name,
				signature,
				vsProgram,
				fsProgram,
				_vertexComponents,
				_vertexIndices,
				_vsConstants,
				_fsConstants,
				_textures,
				_bindings
			);

			return program;
		}

		public function generateAGAL(name : String) : String
		{
			var instruction	: AgalInstruction;
			var shader		: String = name + "\n";

			if (!_isCompiled)
				compile();

			shader += "- vertex shader\n";
			for each (instruction in _vertexSequence)
				shader += instruction.getAgal(true);

			shader += "- fragment shader\n";
			for each (instruction in _fragmentSequence)
				shader += instruction.getAgal(false);

			return shader;
		}

		private function compile() : void
		{
			// execute consecutive visitors to optimize the shader graph.
			// Warning: the order matters, do not swap lines.
			MERGER					.process(this);	// merge duplicate nodes
			REMOVE_EXTRACT			.process(this);	// remove all extract nodes
			OVERWRITER_CLEANER		.process(this);	// remove nested overwriters
			RESOLVE_CONSTANT		.process(this);	// resolve constant computation
			CONSTANT_PACKER			.process(this);	// pack constants [0,0,0,1] => [0,1].xxxy
//			REMOVE_USELESS			.process(this);	// remove some useless operations (add 0, mul 0, mul 1...)
//			RESOLVE_PARAMETRIZED	.process(this);	// replace computations that depend on parameters by evalexp parameters
//			MATRIX_TRANSFORMATION	.process(this);	// replace ((vector * matrix1) * matrix2) by vector * (matrix1 * matrix2) to save registers on GPU
			COPY_INSERTER			.process(this);	// ensure there are no operations between constants
			SPLITTER				.process(this);	// clone nodes that are shared between vertex and fragment shader
			CONSTANT_GROUPER		.process(this);	// group constants [0,1] & [0,2] => [0, 1, 2]

			if (Minko.debugLevel & DebugLevel.SHADER_DOTTY)
			{
				WRITE_DOT.process(this);
				Minko.log(DebugLevel.SHADER_DOTTY, WRITE_DOT.result);
				WRITE_DOT.clear();
			}

			// generate final program
			INTERPOLATE_FINDER		.process(this);	// find interpolate nodes. We may skip that in the future.
			ALLOCATOR				.process(this);	// allocate memory and generate final code.

			// retrieve program
			_vertexSequence		= ALLOCATOR.vertexSequence;
			_fragmentSequence	= ALLOCATOR.fragmentSequence;
			_bindings			= ALLOCATOR.parameterBindings;
			_vertexComponents	= ALLOCATOR.vertexComponents;
			_vertexIndices		= ALLOCATOR.vertexIndices;
			_vsConstants		= ALLOCATOR.vertexConstants;
			_fsConstants		= ALLOCATOR.fragmentConstants;
			_textures			= ALLOCATOR.textures;

			ALLOCATOR.clear();

			_isCompiled = true;
		}

		private function computeBinaryProgram(sequence			: Vector.<AgalInstruction>,
											  isVertexShader	: Boolean) : ByteArray
		{
			var program : ByteArray = new ByteArray();

			program.endian = Endian.LITTLE_ENDIAN;
			program.writeByte(0xa0);					// tag version
			program.writeUnsignedInt(1);				// AGAL version, big endian, bit pattern will be 0x01000000
			program.writeByte(0xa1);					// tag program id
			program.writeByte(isVertexShader ? 0 : 1);	// vertex or fragment

			for each (var instruction : AgalInstruction in sequence)
				instruction.getBytecode(program);

			return program;
		}
	}
}

disable RemoveUselessComputation shader graph visitor to fix multiple minor issues


package org.jivesoftware.xiff.core
{
	import flash.events.ErrorEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import flash.xml.XMLDocument;
	import flash.xml.XMLNode;

	import mx.messaging.messages.HTTPRequestMessage;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.http.HTTPService;

	import org.jivesoftware.xiff.auth.Anonymous;
	import org.jivesoftware.xiff.auth.External;
	import org.jivesoftware.xiff.auth.Plain;
	import org.jivesoftware.xiff.auth.SASLAuth;
	import org.jivesoftware.xiff.data.IQ;
	import org.jivesoftware.xiff.data.bind.BindExtension;
	import org.jivesoftware.xiff.data.session.SessionExtension;
	import org.jivesoftware.xiff.events.ConnectionSuccessEvent;
	import org.jivesoftware.xiff.events.IncomingDataEvent;
	import org.jivesoftware.xiff.events.LoginEvent;
	import org.jivesoftware.xiff.util.Callback;

	public class XMPPBOSHConnection extends XMPPConnection
	{
		private static var saslMechanisms:Object = {
			"PLAIN":Plain,
			"ANONYMOUS":Anonymous,
            "EXTERNAL":External
		};

		private var maxConcurrentRequests:uint = 2;
		private var boshVersion:Number = 1.6;
		private var headers:Object = {
			"post": [],
			"get": ['Cache-Control', 'no-store', 'Cache-Control', 'no-cache', 'Pragma', 'no-cache']
		};
		private var requestCount:int = 0;
		private var failedRequests:Array = [];
		private var requestQueue:Array = [];
		private var responseQueue:Array = [];
		private const responseTimer:Timer = new Timer(0.0, 1);
		private var isDisconnecting:Boolean = false;
		private var boshPollingInterval:Number = 10000;
		private var sid:String;
		private var rid:Number;
		private var wait:int;
		private var inactivity:int;
		private var pollTimer:Timer = new Timer(1, 1);
		private var pollTimeoutTimer:Timer = new Timer(1, 1);

		private var auth:SASLAuth;
		private var authHandler:Function;
		private var https:Boolean = false;
		private var _port:Number = -1;

		private var callbacks:Object = {};

		public static var logger:Object = null;
		private var lastPollTime:Date = null;

		public override function connect(streamType:String=null):Boolean
		{
			if(logger)
				logger.log("CONNECT()", "INFO");
			BindExtension.enable();
			active = false;
			loggedIn = false;
			var attrs:Object = {
	            xmlns: "http://jabber.org/protocol/httpbind",
	            hold: maxConcurrentRequests,
	            rid: nextRID,
	            secure: https,
	            wait: 10,
	            ver: boshVersion
	        }

	        var result:XMLNode = new XMLNode(1, "body");
	        result.attributes = attrs;
	        sendRequests(result);

	        return true;
		}

		public static function registerSASLMechanism(name:String, authClass:Class):void
		{
			saslMechanisms[name] = authClass;
		}

		public static function disableSASLMechanism(name:String):void
		{
			saslMechanisms[name] = null;
		}

		public function set secure(flag:Boolean):void
		{
			https = flag;
		}

		public override function set port(portnum:Number):void
		{
			_port = portnum;
		}

		public override function get port():Number
		{
			if(_port == -1)
				return https ? 8483 : 8080;
			return _port;
		}

		public function get httpServer():String
		{
			return (https ? "https" : "http") + "://" + server + ":" + port + "/http-bind/";
		}

		public override function disconnect():void
		{
			super.disconnect();
			pollTimer.stop();
			pollTimer = null;
			pollTimeoutTimer.stop();
			pollTimeoutTimer = null;
		}

		public function processConnectionResponse(responseBody:XMLNode):void
		{
			var attributes:Object = responseBody.attributes;
			sid = attributes.sid;
	        boshPollingInterval = attributes.polling * 1000;

	        wait = attributes.wait;
	        inactivity = attributes.inactivity * 1000;
	        if(inactivity - 2000 >= boshPollingInterval || (boshPollingInterval <= 1000 && boshPollingInterval > 0))
	        {
	        	boshPollingInterval += 1000;
	        }

	        inactivity -= 1000;

	        var serverRequests:int = attributes.requests;
	        if (serverRequests)
	            maxConcurrentRequests = Math.min(serverRequests, maxConcurrentRequests);
	        active = true;
	        configureConnection(responseBody);
	        responseTimer.addEventListener(TimerEvent.TIMER_COMPLETE, processResponse);
	        trace(boshPollingInterval);
	        pollTimer.delay = boshPollingInterval;
	        pollTimer.addEventListener(TimerEvent.TIMER_COMPLETE, pollServer);
	        pollTimer.start();

	        pollTimeoutTimer.delay = inactivity;
	        pollTimeoutTimer.addEventListener(TimerEvent.TIMER_COMPLETE, function(evt:TimerEvent):void {
				trace("Poll timed out, resuming");
				pollServer(evt, true);
			});
		}

		private function processResponse(event:TimerEvent=null):void
		{
			// Read the data and send it to the appropriate parser
			var currentNode:XMLNode = responseQueue.shift();
			var nodeName:String = currentNode.nodeName.toLowerCase();

			switch( nodeName )
			{
				case "stream:features":
					//we already handled this in httpResponse()
					break;

				case "stream:error":
					handleStreamError( currentNode );
					break;

				case "iq":
					handleIQ( currentNode );
					break;

				case "message":
					handleMessage( currentNode );
					break;

				case "presence":
					handlePresence( currentNode );
					break;

				case "success":
					handleAuthentication( currentNode );
					break;

				case "failure":
					handleAuthentication( currentNode );
					break;
				default:
					dispatchError( "undefined-condition", "Unknown Error", "modify", 500 );
					break;
			}

			resetResponseProcessor();
		}

		private function resetResponseProcessor():void
		{
			if(responseQueue.length > 0)
			{
				responseTimer.reset();
				responseTimer.start();
			}
		}

		private function httpResponse(req:XMLNode, isPollResponse:Boolean, evt:ResultEvent):void
		{
			requestCount--;
			var rawXML:String = evt.result as String;

			if(logger)
	       		logger.log(rawXML, "INCOMING");

			var xmlData:XMLDocument = new XMLDocument();
			xmlData.ignoreWhite = this.ignoreWhite;
			xmlData.parseXML( rawXML );
			var bodyNode:XMLNode = xmlData.firstChild;

			var event:IncomingDataEvent = new IncomingDataEvent();
			event.data = xmlData;
			dispatchEvent( event );

			if(bodyNode.attributes["type"] == "terminal")
			{
				dispatchError( "BOSH Error", bodyNode.attributes["condition"], "", -1 );
				active = false;
			}

			for each(var childNode:XMLNode in bodyNode.childNodes)
			{
				if(childNode.nodeName == "stream:features")
				{
					_expireTagSearch = false;
					processConnectionResponse( bodyNode );
				}
				else
					responseQueue.push(childNode);
			}

			resetResponseProcessor();

			//if we have no outstanding requests, then we're free to send a poll at the next opportunity
			if(requestCount == 0 && !sendQueuedRequests())
				resetPollTimer();
		}

		private function httpError(req:XMLNode, isPollResponse:Boolean, evt:FaultEvent):void
		{
			disconnect();
			dispatchError("Unknown HTTP Error", evt.fault.rootCause.text, "", -1);
		}

		protected override function sendXML(body:*):void
		{
			sendQueuedRequests(body);
		}

		private function sendQueuedRequests(body:*=null):Boolean
		{
			if(body)
				requestQueue.push(body);
			else if(requestQueue.length == 0)
				return false;

			return sendRequests();
		}

		//returns true if any requests were sent
		private function sendRequests(data:XMLNode = null, isPoll:Boolean = false):Boolean
		{
			if(requestCount >= maxConcurrentRequests)
				return false;

			requestCount++;

			if(!data)
			{
				if(isPoll)
				{
					data = createRequest();
				}
				else
				{
					var temp:Array = [];
					for(var i:uint = 0; i < 10 && requestQueue.length > 0; i++)
					{
						temp.push(requestQueue.shift());
					}
					data = createRequest(temp);
				}
			}

			//build the http request
	        var request:HTTPService = new HTTPService();
	        request.method = "post";
	        request.headers = headers[request.method];
	        request.url = httpServer;
	        request.resultFormat = HTTPService.RESULT_FORMAT_TEXT;
	        request.contentType = "text/xml";

	        var responseCallback:Callback = new Callback(this, httpResponse, data, isPoll);
	        var errorCallback:Callback = new Callback(this, httpError, data, isPoll);

	        request.addEventListener(ResultEvent.RESULT, responseCallback.call, false);
	        request.addEventListener(FaultEvent.FAULT, errorCallback.call, false);

	       	if(logger)
	       		logger.log(data, "OUTGOING");

			request.send(data);

			if(isPoll) {
				lastPollTime = new Date();
				pollTimeoutTimer.reset();
				pollTimeoutTimer.start();
				trace("Polling at: " + lastPollTime.getMinutes() + ":" + lastPollTime.getSeconds());
			}

			pollTimer.stop();

			return true;
		}

    	private function resetPollTimer():void
    	{
    		if(!pollTimer)
    			return;

    		pollTimeoutTimer.stop();

    		pollTimer.reset();
    		var timeSinceLastPoll:Number = 0;
    		if(lastPollTime)
    			 timeSinceLastPoll = new Date().time - lastPollTime.time;

    		if(timeSinceLastPoll >= boshPollingInterval)
    			timeSinceLastPoll = 0;

    		pollTimer.delay = boshPollingInterval - timeSinceLastPoll;
    		pollTimer.start();
    	}

    	private function pollServer(evt:TimerEvent, force:Boolean=false):void
    	{
    		if(force)
    			trace("Forcing poll!");
    		//We shouldn't poll if the connection is dead, if we had requests to send instead, or if there's already one in progress
    		if(!isActive() || ((sendQueuedRequests() || requestCount > 0) && !force))
    			return;

    		//this should be safe since sendRequests checks to be sure it's not over the concurrent requests limit, and we just ensured that the queue is empty by calling sendQueuedRequests()
    		sendRequests(null, true);
    	}

    	private function get nextRID():Number {
    		if(!rid)
    			rid = Math.floor(Math.random() * 1000000);
    		return ++rid;
    	}

    	private function createRequest(bodyContent:Array=null):XMLNode {
    		var attrs:Object = {
    			xmlns: "http://jabber.org/protocol/httpbind",
				rid: nextRID,
				sid: sid
    		}
    		var req:XMLNode = new XMLNode(1, "body");
    		if(bodyContent)
    			for each(var content:XMLNode in bodyContent)
    					req.appendChild(content);

    		req.attributes = attrs;

    		return req;
    	}

	    private function handleAuthentication(responseBody:XMLNode):void
	    {
	    //    if(!response || response.length == 0) {
	     //       return;
	     //   }
	        var status:Object = auth.handleResponse(0, responseBody);
	        if (status.authComplete) {
	            if (status.authSuccess) {
	                bindConnection();
	            }
	            else {
					dispatchError("Authentication Error", "", "", 401);
	                disconnect();
	            }
	        }
	    }

	    private function configureConnection(responseBody:XMLNode):void
	    {
	    	var features:XMLNode = responseBody.firstChild;

	        var authentication:Object = {};
	        for each(var feature:XMLNode in features.childNodes)
			{
	            if (feature.nodeName == "mechanisms")
	                authentication.auth = configureAuthMechanisms(feature);
	            else if (feature.nodeName == "bind")
	                authentication.bind = true;
	            else if (feature.nodeName == "session")
	                authentication.session = true;
	        }

	        auth = authentication.auth;
	        dispatchEvent(new ConnectionSuccessEvent());
	        authHandler = handleAuthentication;
	        sendXML(auth.request);
	    }

	    private function configureAuthMechanisms(mechanisms:XMLNode):SASLAuth
	    {
	        var authMechanism:SASLAuth;
	        var authClass:Class;
	        for each(var mechanism:XMLNode in mechanisms.childNodes)
	        {
	        	authClass = saslMechanisms[mechanism.firstChild.nodeValue];
	   			if(authClass)
	   				break;
	        }

	        if (!authClass) {
	        	dispatchError("SASL missing", "The server is not configured to support any available SASL mechanisms", "SASL", -1);
	        	return null;
	        }

	   		return new authClass(this);
	    }

	    public function handleBindResponse(packet:IQ):void
	    {
	    	var bind:BindExtension = packet.getExtension("bind") as BindExtension;

            var jid:UnescapedJID = bind.jid.unescaped;

            myResource = jid.resource;
            myUsername = jid.node;
            domain = jid.domain;

            establishSession();
	    }

	    private function bindConnection():void
	    {
	    	var bindIQ:IQ = new IQ(null, "set");

			var bindExt:BindExtension = new BindExtension();
			if(resource)
	        	bindExt.resource = resource;

	        bindIQ.addExtension(bindExt);

			//this is laaaaaame, it should be a function
			bindIQ.callbackName = "handleBindResponse";
			bindIQ.callbackScope = this;

	        send(bindIQ);
	    }

	    public function handleSessionResponse(packet:IQ):void
	    {
	    	dispatchEvent(new LoginEvent());
	    }

	    private function establishSession():void
	    {
	        var sessionIQ:IQ = new IQ(null, "set");

	        sessionIQ.addExtension(new SessionExtension());

	        sessionIQ.callbackName = "handleSessionResponse";
	        sessionIQ.callbackScope = this;

	        send(sessionIQ);
	    }

		//do nothing, we use polling instead
		public override function sendKeepAlive():void {}
	}
}

package org.jivesoftware.xiff.core
{
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import flash.xml.XMLDocument;
	import flash.xml.XMLNode;

	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.http.HTTPService;

	import org.jivesoftware.xiff.auth.Anonymous;
	import org.jivesoftware.xiff.auth.External;
	import org.jivesoftware.xiff.auth.Plain;
	import org.jivesoftware.xiff.auth.SASLAuth;
	import org.jivesoftware.xiff.data.IQ;
	import org.jivesoftware.xiff.data.bind.BindExtension;
	import org.jivesoftware.xiff.data.session.SessionExtension;
	import org.jivesoftware.xiff.events.ConnectionSuccessEvent;
	import org.jivesoftware.xiff.events.IncomingDataEvent;
	import org.jivesoftware.xiff.events.LoginEvent;
	import org.jivesoftware.xiff.util.Callback;

	public class XMPPBOSHConnection extends XMPPConnection
	{
		private static var saslMechanisms:Object = {
			"PLAIN":Plain,
			"ANONYMOUS":Anonymous,
            "EXTERNAL":External
		};

		private var maxConcurrentRequests:uint = 2;
		private var boshVersion:Number = 1.6;
		private var headers:Object = {
			"post": [],
			"get": ['Cache-Control', 'no-store', 'Cache-Control', 'no-cache', 'Pragma', 'no-cache']
		};
		private var requestCount:int = 0;
		private var failedRequests:Array = [];
		private var requestQueue:Array = [];
		private var responseQueue:Array = [];
		private const responseTimer:Timer = new Timer(0.0, 1);
		private var isDisconnecting:Boolean = false;
		private var boshPollingInterval:Number = 10000;
		private var sid:String;
		private var rid:Number;
		private var wait:int;
		private var inactivity:int;
		private var pollTimer:Timer = new Timer(1, 1);
		private var pollTimeoutTimer:Timer = new Timer(1, 1);

		private var auth:SASLAuth;
		private var authHandler:Function;
		private var https:Boolean = false;
		private var _port:Number = -1;

		private var callbacks:Object = {};

		public static var logger:Object = null;
		private var lastPollTime:Date = null;

		public override function connect(streamType:String=null):Boolean
		{
			if(logger)
				logger.log("CONNECT()", "INFO");
			BindExtension.enable();
			active = false;
			loggedIn = false;
			var attrs:Object = {
	            xmlns: "http://jabber.org/protocol/httpbind",
	            hold: maxConcurrentRequests,
	            rid: nextRID,
	            secure: https,
	            wait: 10,
	            ver: boshVersion
	        }

	        var result:XMLNode = new XMLNode(1, "body");
	        result.attributes = attrs;
	        sendRequests(result);

	        return true;
		}

		public static function registerSASLMechanism(name:String, authClass:Class):void
		{
			saslMechanisms[name] = authClass;
		}

		public static function disableSASLMechanism(name:String):void
		{
			saslMechanisms[name] = null;
		}

		public function set secure(flag:Boolean):void
		{
			https = flag;
		}

		public function get secure():Boolean
		{
			return https;
		}

		public override function set port(portnum:Number):void
		{
			_port = portnum;
		}

		public override function get port():Number
		{
			if(_port == -1)
				return https ? 8483 : 8080;
			return _port;
		}

		public function get httpServer():String
		{
			return (https ? "https" : "http") + "://" + server + ":" + port + "/http-bind/";
		}

		public override function disconnect():void
		{
			super.disconnect();
			pollTimer.stop();
			pollTimer = null;
			pollTimeoutTimer.stop();
			pollTimeoutTimer = null;
		}

		public function processConnectionResponse(responseBody:XMLNode):void
		{
			var attributes:Object = responseBody.attributes;
			sid = attributes.sid;
	        boshPollingInterval = attributes.polling * 1000;

	        wait = attributes.wait;
	        inactivity = attributes.inactivity * 1000;
	        if(inactivity - 2000 >= boshPollingInterval || (boshPollingInterval <= 1000 && boshPollingInterval > 0))
	        {
	        	boshPollingInterval += 1000;
	        }

	        inactivity -= 1000;

	        var serverRequests:int = attributes.requests;
	        if (serverRequests)
	            maxConcurrentRequests = Math.min(serverRequests, maxConcurrentRequests);
	        active = true;
	        configureConnection(responseBody);
	        responseTimer.addEventListener(TimerEvent.TIMER_COMPLETE, processResponse);
	        trace(boshPollingInterval);
	        pollTimer.delay = boshPollingInterval;
	        pollTimer.addEventListener(TimerEvent.TIMER_COMPLETE, pollServer);
	        pollTimer.start();

	        pollTimeoutTimer.delay = inactivity;
	        pollTimeoutTimer.addEventListener(TimerEvent.TIMER_COMPLETE, function(evt:TimerEvent):void {
				trace("Poll timed out, resuming");
				pollServer(evt, true);
			});
		}

		private function processResponse(event:TimerEvent=null):void
		{
			// Read the data and send it to the appropriate parser
			var currentNode:XMLNode = responseQueue.shift();
			var nodeName:String = currentNode.nodeName.toLowerCase();

			switch( nodeName )
			{
				case "stream:features":
					//we already handled this in httpResponse()
					break;

				case "stream:error":
					handleStreamError( currentNode );
					break;

				case "iq":
					handleIQ( currentNode );
					break;

				case "message":
					handleMessage( currentNode );
					break;

				case "presence":
					handlePresence( currentNode );
					break;

				case "success":
					handleAuthentication( currentNode );
					break;

				case "failure":
					handleAuthentication( currentNode );
					break;
				default:
					dispatchError( "undefined-condition", "Unknown Error", "modify", 500 );
					break;
			}

			resetResponseProcessor();
		}

		private function resetResponseProcessor():void
		{
			if(responseQueue.length > 0)
			{
				responseTimer.reset();
				responseTimer.start();
			}
		}

		private function httpResponse(req:XMLNode, isPollResponse:Boolean, evt:ResultEvent):void
		{
			requestCount--;
			var rawXML:String = evt.result as String;

			if(logger)
	       		logger.log(rawXML, "INCOMING");

			var xmlData:XMLDocument = new XMLDocument();
			xmlData.ignoreWhite = this.ignoreWhite;
			xmlData.parseXML( rawXML );
			var bodyNode:XMLNode = xmlData.firstChild;

			var event:IncomingDataEvent = new IncomingDataEvent();
			event.data = xmlData;
			dispatchEvent( event );

			if(bodyNode.attributes["type"] == "terminal")
			{
				dispatchError( "BOSH Error", bodyNode.attributes["condition"], "", -1 );
				active = false;
			}

			for each(var childNode:XMLNode in bodyNode.childNodes)
			{
				if(childNode.nodeName == "stream:features")
				{
					_expireTagSearch = false;
					processConnectionResponse( bodyNode );
				}
				else
					responseQueue.push(childNode);
			}

			resetResponseProcessor();

			//if we have no outstanding requests, then we're free to send a poll at the next opportunity
			if(requestCount == 0 && !sendQueuedRequests())
				resetPollTimer();
		}

		private function httpError(req:XMLNode, isPollResponse:Boolean, evt:FaultEvent):void
		{
			disconnect();
			dispatchError("Unknown HTTP Error", evt.fault.rootCause.text, "", -1);
		}

		protected override function sendXML(body:*):void
		{
			sendQueuedRequests(body);
		}

		private function sendQueuedRequests(body:*=null):Boolean
		{
			if(body)
				requestQueue.push(body);
			else if(requestQueue.length == 0)
				return false;

			return sendRequests();
		}

		//returns true if any requests were sent
		private function sendRequests(data:XMLNode = null, isPoll:Boolean = false):Boolean
		{
			if(requestCount >= maxConcurrentRequests)
				return false;

			requestCount++;

			if(!data)
			{
				if(isPoll)
				{
					data = createRequest();
				}
				else
				{
					var temp:Array = [];
					for(var i:uint = 0; i < 10 && requestQueue.length > 0; i++)
					{
						temp.push(requestQueue.shift());
					}
					data = createRequest(temp);
				}
			}

			//build the http request
	        var request:HTTPService = new HTTPService();
	        request.method = "post";
	        request.headers = headers[request.method];
	        request.url = httpServer;
	        request.resultFormat = HTTPService.RESULT_FORMAT_TEXT;
	        request.contentType = "text/xml";

	        var responseCallback:Callback = new Callback(this, httpResponse, data, isPoll);
	        var errorCallback:Callback = new Callback(this, httpError, data, isPoll);

	        request.addEventListener(ResultEvent.RESULT, responseCallback.call, false);
	        request.addEventListener(FaultEvent.FAULT, errorCallback.call, false);

	       	if(logger)
	       		logger.log(data, "OUTGOING");

			request.send(data);

			if(isPoll) {
				lastPollTime = new Date();
				pollTimeoutTimer.reset();
				pollTimeoutTimer.start();
				trace("Polling at: " + lastPollTime.getMinutes() + ":" + lastPollTime.getSeconds());
			}

			pollTimer.stop();

			return true;
		}

    	private function resetPollTimer():void
    	{
    		if(!pollTimer)
    			return;

    		pollTimeoutTimer.stop();

    		pollTimer.reset();
    		var timeSinceLastPoll:Number = 0;
    		if(lastPollTime)
    			 timeSinceLastPoll = new Date().time - lastPollTime.time;

    		if(timeSinceLastPoll >= boshPollingInterval)
    			timeSinceLastPoll = 0;

    		pollTimer.delay = boshPollingInterval - timeSinceLastPoll;
    		pollTimer.start();
    	}

    	private function pollServer(evt:TimerEvent, force:Boolean=false):void
    	{
    		if(force)
    			trace("Forcing poll!");
    		//We shouldn't poll if the connection is dead, if we had requests to send instead, or if there's already one in progress
    		if(!isActive() || ((sendQueuedRequests() || requestCount > 0) && !force))
    			return;

    		//this should be safe since sendRequests checks to be sure it's not over the concurrent requests limit, and we just ensured that the queue is empty by calling sendQueuedRequests()
    		sendRequests(null, true);
    	}

    	private function get nextRID():Number {
    		if(!rid)
    			rid = Math.floor(Math.random() * 1000000);
    		return ++rid;
    	}

    	private function createRequest(bodyContent:Array=null):XMLNode {
    		var attrs:Object = {
    			xmlns: "http://jabber.org/protocol/httpbind",
				rid: nextRID,
				sid: sid
    		}
    		var req:XMLNode = new XMLNode(1, "body");
    		if(bodyContent)
    			for each(var content:XMLNode in bodyContent)
    					req.appendChild(content);

    		req.attributes = attrs;

    		return req;
    	}

	    private function handleAuthentication(responseBody:XMLNode):void
	    {
	    //    if(!response || response.length == 0) {
	     //       return;
	     //   }
	        var status:Object = auth.handleResponse(0, responseBody);
	        if (status.authComplete) {
	            if (status.authSuccess) {
	                bindConnection();
	            }
	            else {
					dispatchError("Authentication Error", "", "", 401);
	                disconnect();
	            }
	        }
	    }

	    private function configureConnection(responseBody:XMLNode):void
	    {
	    	var features:XMLNode = responseBody.firstChild;

	        var authentication:Object = {};
	        for each(var feature:XMLNode in features.childNodes)
			{
	            if (feature.nodeName == "mechanisms")
	                authentication.auth = configureAuthMechanisms(feature);
	            else if (feature.nodeName == "bind")
	                authentication.bind = true;
	            else if (feature.nodeName == "session")
	                authentication.session = true;
	        }

	        auth = authentication.auth;
	        dispatchEvent(new ConnectionSuccessEvent());
	        authHandler = handleAuthentication;
	        sendXML(auth.request);
	    }

	    private function configureAuthMechanisms(mechanisms:XMLNode):SASLAuth
	    {
	        var authMechanism:SASLAuth;
	        var authClass:Class;
	        for each(var mechanism:XMLNode in mechanisms.childNodes)
	        {
	        	authClass = saslMechanisms[mechanism.firstChild.nodeValue];
	   			if(authClass)
	   				break;
	        }

	        if (!authClass) {
	        	dispatchError("SASL missing", "The server is not configured to support any available SASL mechanisms", "SASL", -1);
	        	return null;
	        }

	   		return new authClass(this);
	    }

	    public function handleBindResponse(packet:IQ):void
	    {
	    	var bind:BindExtension = packet.getExtension("bind") as BindExtension;

            var jid:UnescapedJID = bind.jid.unescaped;

            myResource = jid.resource;
            myUsername = jid.node;
            domain = jid.domain;

            establishSession();
	    }

	    private function bindConnection():void
	    {
	    	var bindIQ:IQ = new IQ(null, "set");

			var bindExt:BindExtension = new BindExtension();
			if(resource)
	        	bindExt.resource = resource;

	        bindIQ.addExtension(bindExt);

			//this is laaaaaame, it should be a function
			bindIQ.callbackName = "handleBindResponse";
			bindIQ.callbackScope = this;

	        send(bindIQ);
	    }

	    public function handleSessionResponse(packet:IQ):void
	    {
	    	dispatchEvent(new LoginEvent());
	    }

	    private function establishSession():void
	    {
	        var sessionIQ:IQ = new IQ(null, "set");

	        sessionIQ.addExtension(new SessionExtension());

	        sessionIQ.callbackName = "handleSessionResponse";
	        sessionIQ.callbackScope = this;

	        send(sessionIQ);
	    }

		//do nothing, we use polling instead
		public override function sendKeepAlive():void {}
	}
}

Add an accessor for whether or not we are using https. r=Armando


//////////////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2012 Freshplanet (http://freshplanet.com | opensource@freshplanet.com)
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
//////////////////////////////////////////////////////////////////////////////////////

package com.freshplanet.ane.AirAACPlayer
{
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.StatusEvent;
    import flash.external.ExtensionContext;
    import flash.system.Capabilities;

    public class AirAACPlayer extends EventDispatcher
    {
        // --------------------------------------------------------------------------------------//
        //                                                                                //
        //                                     PUBLIC API                                        //
        //                                                                                //
        // --------------------------------------------------------------------------------------//

        public static const AAC_PLAYER_PREPARED:String = "AAC_PLAYER_PREPARED";

        /** AirAACPlayer is supported on Android devices. */
        public static function get isSupported():Boolean
        {
            var isAndroid:Boolean = (Capabilities.manufacturer.indexOf("Android") != -1)
            return isAndroid;
        }

        public function AirAACPlayer()
        {
            if (!_instance)
            {
                _context = ExtensionContext.createExtensionContext(EXTENSION_ID, null);
                if (!_context)
                {
                    log("ERROR - Extension context is null. Please check if extension.xml is setup correctly.");
                    return;
                }
                _context.addEventListener(StatusEvent.STATUS, onStatus);

                _instance = this;
            }
            else
            {
                throw Error("This is a singleton, use getInstance(), do not call the constructor directly.");
            }
        }

        public static function getInstance():AirAACPlayer
        {
            return _instance ? _instance:new AirAACPlayer();
        }

        public var logEnabled:Boolean = true;

        /**
        * Load a music stream url
        * @param url:String
        */
        public function loadUrl(url:String):void
        {
            _context.call("loadUrl", url);
        }

        /**
        * Start playing the stream.
        * If the playback has been paused before, it will continue from this point.
        * @param startTime:int the start time in milliseconds
        */
        public function play(startTime:int=0):void
        {
            _context.call("play", startTime);
        }

        /**
        * Pause the playback
        */
        public function pause():void
        {
            _context.call("pause");
        }

        /**
        * Stop the playback
        */
        public function stop():void
        {
            _context.call("stop");
        }

        /**
        * Close the stream and release.
        * Note that loadUrl() has to be called again before replaying if close has been called.
        */
        public function close():void
        {
            _context.call("close");
        }

        /**
        * Length in milliseconds
        */
        public function get length():int
        {
            return _context.call("getLength") as int;
        }

        /**
        * Progress in milliseconds
        */
        public function get progress():int
        {
            return _context.call("getProgress") as int;
        }

        // --------------------------------------------------------------------------------------//
        //                                                                                //
        //                                      PRIVATE API                                      //
        //                                                                                //
        // --------------------------------------------------------------------------------------//

        private static const EXTENSION_ID:String = "com.freshplanet.AirAACPlayer";

        private static var _instance:AirAACPlayer;

        private var _context:ExtensionContext;

        private function onStatus( event:StatusEvent ):void
        {
            if (event.code == "LOGGING") // Simple log message
            {
                log(event.level);
            }
            else if (event.code == AAC_PLAYER_PREPARED)
            {
                dispatchEvent(new Event(event.code));
            }
        }

        private function log( message:String ):void
        {
            if (logEnabled) trace("[AirAACPlayer] " + message);
        }
    }
}

//////////////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2012 Freshplanet (http://freshplanet.com | opensource@freshplanet.com)
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
//////////////////////////////////////////////////////////////////////////////////////

package com.freshplanet.ane.AirAACPlayer
{
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.StatusEvent;
    import flash.external.ExtensionContext;
    import flash.system.Capabilities;

    public class AirAACPlayer extends EventDispatcher
    {
        // --------------------------------------------------------------------------------------//
        //                                                                                //
        //                                     PUBLIC API                                        //
        //                                                                                //
        // --------------------------------------------------------------------------------------//

        public static const AAC_PLAYER_PREPARED:String = "AAC_PLAYER_PREPARED";

        /** AirAACPlayer is supported on Android devices. */
        public static function get isSupported():Boolean
        {
            var isAndroid:Boolean = (Capabilities.manufacturer.indexOf("Android") != -1)
            return isAndroid;
        }

        public function AirAACPlayer()
        {
            _context = ExtensionContext.createExtensionContext(EXTENSION_ID, null);
            if (!_context)
            {
                log("ERROR - Extension context is null. Please check if extension.xml is setup correctly.");
                return;
            }
            _context.addEventListener(StatusEvent.STATUS, onStatus);
        }

        public var logEnabled:Boolean = true;

        /**
        * Load a music stream url
        * @param url:String
        */
        public function loadUrl(url:String):void
        {
            _context.call("loadUrl", url);
        }

        /**
        * Start playing the stream.
        * If the playback has been paused before, it will continue from this point.
        * @param startTime:int the start time in milliseconds
        */
        public function play(startTime:int=0):void
        {
            _context.call("play", startTime);
        }

        /**
        * Pause the playback
        */
        public function pause():void
        {
            _context.call("pause");
        }

        /**
        * Stop the playback
        */
        public function stop():void
        {
            _context.call("stop");
        }

        /**
        * Close the stream and release.
        * Note that loadUrl() has to be called again before replaying if close has been called.
        */
        public function close():void
        {
            _context.call("close");
        }

        /**
        * Length in milliseconds
        */
        public function get length():int
        {
            return _context.call("getLength") as int;
        }

        /**
        * Progress in milliseconds
        */
        public function get progress():int
        {
            return _context.call("getProgress") as int;
        }

        // --------------------------------------------------------------------------------------//
        //                                                                                //
        //                                      PRIVATE API                                      //
        //                                                                                //
        // --------------------------------------------------------------------------------------//

        private static const EXTENSION_ID:String = "com.freshplanet.AirAACPlayer";

        private static var _instance:AirAACPlayer;

        private var _context:ExtensionContext;

        private function onStatus( event:StatusEvent ):void
        {
            if (event.code == "LOGGING") // Simple log message
            {
                log(event.level);
            }
            else if (event.code == AAC_PLAYER_PREPARED)
            {
                dispatchEvent(new Event(event.code));
            }
        }

        private function log( message:String ):void
        {
            if (logEnabled) trace("[AirAACPlayer] " + message);
        }
    }
}

Convert ACC ane to instantiable from singleton


m4_pattern_allow([^URBI_(PATH|SERVER)$])         -*- shell-script -*-

AS_INIT()dnl
URBI_PREPARE()

set -e

case $VERBOSE in
  x) set -x;;
esac

# Avoid zombies and preserve debugging information.
cleanup ()
{
  exit_status=$?

  # In case we were caught by set -e, kill the children.
  children_kill
  children_harvest
  children_report

  children_sta=$(children_status remote)
  # Don't clean before calling children_status...
  test x$VERBOSE != x || children_clean

  case $exit_status:$children_sta in
    0:0) ;;
    0:*) # Maybe a children exited for SKIP etc.
	 exit $children_sta;;
    *:*) # If liburbi-check failed, there is a big problem.
	 error SOFTWARE "liburbi-check itself failed with $exit_status";;
  esac
  # rst_expect sets exit=false if it saw a failure.
  $exit
}
for signal in 1 2 13 15; do
  trap 'error $((128 + $signal)) \
	      "received signal $signal ($(kill -l $signal))"' $signal
done
trap cleanup 0

# Overriden to include the test name.
stderr ()
{
  echo >&2 "$(basename $0): $me: $@"
  echo >&2
}

# Sleep some time, but taking into account the fact that
# instrumentation slows down a lot.
my_sleep ()
{
  if $INSTRUMENT; then
    sleep $(($1 * 5))
  else
    sleep $1
  fi
}

## -------------- ##
## Main program.  ##
## -------------- ##

exec 3>&2

: ${abs_builddir='@abs_builddir@'}
check_dir abs_builddir liburbi-check
: ${abs_top_builddir='@abs_top_builddir@'}
check_dir abs_top_builddir config.status
: ${abs_top_srcdir='@abs_top_srcdir@'}
check_dir abs_top_srcdir configure.ac

# Make it absolute.
chk=$(absolute "$1")
if test ! -f "$chk.cc"; then
  fatal "no such file: $chk.cc"
fi

period=32
# ./../../../tests/2.x/andexp-pipeexp.chk -> 2.x
medir=$(basename $(dirname "$chk"))
# ./../../../tests/2.x/andexp-pipeexp.chk -> 2.x/andexp-pipeexp
me=$medir/$(basename "$chk" ".cc")
# ./../../../tests/2.x/andexp-pipeexp.chk -> andexp-pipeexp
meraw=$(basename $me)    # MERAW!

srcdir=$(absolute $srcdir)
export srcdir
# Move to a private dir.
rm -rf $me.dir
mkdir -p $me.dir
cd $me.dir

# Help debugging
set | rst_pre "$me variables"

# $URBI_SERVER.
#
# If this SDK-Remote is part of the Kernel package, then we should not
# use an installed urbi-console, but rather the one which is part of
# this package.
if test -x $abs_top_builddir/../src/urbi-console; then
  URBI_SERVER=$abs_top_builddir/../src/urbi-console
  export URBI_PATH=$abs_top_srcdir/../share
else
  # Leaves trailing files, so run it in subdir.
  find_urbi_server
fi

# compute expected output
sed -n -e 's@//= @@p' $chk.cc >output.exp
touch error.exp
echo 0 >status.exp

#start it
valgrind=$(instrument "server.val")
cmd="$valgrind $URBI_SERVER --port 0 -w server.port --period $period"
echo "$cmd" >server.cmd
$cmd >server.out 2>server.err &
children_register server

my_sleep 2

#start the test
valgrind=$(instrument "remote.val")
cmd="$valgrind ../../tests localhost $(cat server.port) $meraw"
echo "$cmd" >remote.cmd
$cmd >remote.out.raw 2>remote.err &
children_register remote

# Let some time to run the tests.
children_wait 10

# Ignore the "client errors".
sed -e '/^E client error/d' remote.out.raw >remote.out.eff
# Compare expected output with actual output.
rst_expect output remote.out
rst_pre "Error output" remote.err

# Display Valgrind report.
rst_pre "Valgrind" remote.val

# Exit with success: liburbi-check made its job.  But now clean (on
# trap 0) will check $exit to see if there is a failure in the tests
# and adjust the exit status accordingly.
exit 0

m4_pattern_allow([^URBI_(PATH|SERVER)$])         -*- shell-script -*-

AS_INIT()dnl
URBI_PREPARE()

set -e

case $VERBOSE in
  x) set -x;;
esac

# Avoid zombies and preserve debugging information.
cleanup ()
{
  exit_status=$?

  # In case we were caught by set -e, kill the children.
  children_kill
  children_harvest
  children_report

  children_sta=$(children_status remote)
  # Don't clean before calling children_status...
  test x$VERBOSE != x || children_clean

  case $exit_status:$children_sta in
    0:0) ;;
    0:*) # Maybe a children exited for SKIP etc.
	 exit $children_sta;;
    *:*) # If liburbi-check failed, there is a big problem.
	 error SOFTWARE "liburbi-check itself failed with $exit_status";;
  esac
  # rst_expect sets exit=false if it saw a failure.
  $exit
}
for signal in 1 2 13 15; do
  trap 'error $((128 + $signal)) \
	      "received signal $signal ($(kill -l $signal))"' $signal
done
trap cleanup 0

# Overriden to include the test name.
stderr ()
{
  echo >&2 "$(basename $0): $me: $@"
  echo >&2
}

# Sleep some time, but taking into account the fact that
# instrumentation slows down a lot.
my_sleep ()
{
  if $INSTRUMENT; then
    sleep $(($1 * 5))
  else
    sleep $1
  fi
}

## -------------- ##
## Main program.  ##
## -------------- ##

exec 3>&2

: ${abs_builddir='@abs_builddir@'}
check_dir abs_builddir liburbi-check
: ${abs_top_builddir='@abs_top_builddir@'}
check_dir abs_top_builddir config.status
: ${abs_top_srcdir='@abs_top_srcdir@'}
check_dir abs_top_srcdir configure.ac

# Make it absolute.
chk=$(absolute "$1")
if test ! -f "$chk.cc"; then
  fatal "no such file: $chk.cc"
fi

period=32
# ./../../../tests/2.x/andexp-pipeexp.chk -> 2.x
medir=$(basename $(dirname "$chk"))
# ./../../../tests/2.x/andexp-pipeexp.chk -> 2.x/andexp-pipeexp
me=$medir/$(basename "$chk" ".cc")
# ./../../../tests/2.x/andexp-pipeexp.chk -> andexp-pipeexp
meraw=$(basename $me)    # MERAW!

srcdir=$(absolute $srcdir)
export srcdir
# Move to a private dir.
rm -rf $me.dir
mkdir -p $me.dir
cd $me.dir

# Help debugging
set | rst_pre "$me variables"

# $URBI_SERVER.
#
# If this SDK-Remote is part of the Kernel package, then we should not
# use an installed urbi-console, but rather the one which is part of
# this package.
if test -d $abs_top_srcdir/../../src/kernel; then
  stderr "This SDK-Remote is part of a kernel package."
  URBI_SERVER=$abs_top_builddir/../src/urbi-console
  export URBI_PATH=$abs_top_srcdir/../share
else
  stderr "This SDK-Remote is standalone."
fi
# Leaves trailing files, so run it in subdir.
find_urbi_server

# Compute expected output.
sed -n -e 's@//= @@p' $chk.cc >output.exp
touch error.exp
echo 0 >status.exp

# Start it.
valgrind=$(instrument "server.val")
cmd="$valgrind $URBI_SERVER --port 0 -w server.port --period $period"
echo "$cmd" >server.cmd
$cmd >server.out 2>server.err &
children_register server

my_sleep 2

# Start the test.
valgrind=$(instrument "remote.val")
cmd="$valgrind ../../tests localhost $(cat server.port) $meraw"
echo "$cmd" >remote.cmd
$cmd >remote.out.raw 2>remote.err &
children_register remote

# Let some time to run the tests.
children_wait 10

# Ignore the "client errors".
sed -e '/^E client error/d' remote.out.raw >remote.out.eff
# Compare expected output with actual output.
rst_expect output remote.out
rst_pre "Error output" remote.err

# Display Valgrind report.
rst_pre "Valgrind" remote.val

# Exit with success: liburbi-check made its job.  But now clean (on
# trap 0) will check $exit to see if there is a failure in the tests
# and adjust the exit status accordingly.
exit 0

Fix embed SDK-Remote test suite.

Fix embed SDK-Remote test suite.

	* src/tests/liburbi-check.as: Also define URBI_PATH.
	Be sure to issue messages when embedded urbi-console is not found.