////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You 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 org.apache.flex.html.beads
{
    COMPILE::AS3
    {
        import flash.display.Bitmap;
        import flash.display.Loader;
        import flash.display.LoaderInfo;
        import flash.events.IOErrorEvent;
        import flash.net.URLRequest;
    }
    COMPILE::JS
    {
        import goog.events;
    }

	import org.apache.flex.core.BeadViewBase;
	import org.apache.flex.core.IBeadView;
	import org.apache.flex.core.IImageModel;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.core.IUIBase;
	import org.apache.flex.core.UIBase;
	import org.apache.flex.events.Event;
	import org.apache.flex.events.IEventDispatcher;

	/**
	 *  The ImageView class creates the visual elements of the org.apache.flex.html.Image component.
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	public class ImageView extends BeadViewBase implements IBeadView
	{
		/**
		 *  constructor.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function ImageView()
		{
		}

        COMPILE::AS3
		private var bitmap:Bitmap;
        COMPILE::AS3
		private var loader:Loader;

		private var _model:IImageModel;

		/**
		 *  @copy org.apache.flex.core.IBead#strand
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		override public function set strand(value:IStrand):void
		{
			super.strand = value;

            COMPILE::AS3
            {
                IEventDispatcher(_strand).addEventListener("widthChanged",handleSizeChange);
                IEventDispatcher(_strand).addEventListener("heightChanged",handleSizeChange);
            }

			_model = value.getBeadByType(IImageModel) as IImageModel;
			_model.addEventListener("urlChanged",handleUrlChange);

//			handleUrlChange(null);
		}

		/**
		 * @private
		 */
		private function handleUrlChange(event:Event):void
		{
            COMPILE::AS3
            {
                if (_model.source) {
                    loader = new Loader();
                    loader.contentLoaderInfo.addEventListener("complete",onComplete);
                    loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
                        trace(e);
                        e.preventDefault();
                    });
                    loader.load(new URLRequest(_model.source));
                }
            }
            COMPILE::JS
            {
				if (_model.source) {
	                var host:IUIBase = _strand as IUIBase;
	                host.element.addEventListener('load',
	                    loadHandler, false);
	                host.addEventListener('sizeChanged',
	                    sizeChangedHandler);
	                (host.element as HTMLImageElement).src = _model.source;
				}
            }
		}

		/**
		 * @private
		 */
        COMPILE::AS3
		private function onComplete(event:Object):void
		{
            var host:UIBase = UIBase(_strand);
			if (bitmap) {
				host.removeChild(bitmap);
			}

			bitmap = Bitmap(LoaderInfo(event.target).content);

			host.addChild(bitmap);

            if (host.isWidthSizedToContent())
            {
                host.dispatchEvent(new Event("widthChanged"));
                if (host.parent)
                    host.parent.dispatchEvent(new Event("layoutNeeded"));
            }
            else
                bitmap.width = UIBase(_strand).width;

            if (host.isHeightSizedToContent())
            {
                host.dispatchEvent(new Event("heightChanged"));
                if (host.parent)
                    host.parent.dispatchEvent(new Event("layoutNeeded"));
            }
            else
                bitmap.height = UIBase(_strand).height;

		}

		/**
		 * @private
		 */
        COMPILE::AS3
		private function handleSizeChange(event:Object):void
		{
            var host:UIBase = UIBase(_strand);
            if (bitmap) {
                if (!isNaN(host.explicitWidth) || !isNaN(host.percentWidth))
	    			bitmap.width = UIBase(_strand).width;
                if (!isNaN(host.explicitHeight) || !isNaN(host.percentHeight))
    				bitmap.height = UIBase(_strand).height;
			}
		}

        COMPILE::JS
        private function loadHandler(event:Object):void
        {
            var host:UIBase = UIBase(_strand);
            host.parent.dispatchEvent(new Event("layoutNeeded"));
        }

        /**
         * @flexjsignorecoercion HTMLElement
         */
        COMPILE::JS
        private function sizeChangedHandler(event:Object):void
        {
            var host:UIBase = _strand as UIBase;
            var s:Object = host.positioner.style;
            var l:Number = NaN;
            var ls:String = s.left;
            if (typeof(ls) === 'string' && ls.length > 0)
                l = parseFloat(ls.substring(0, ls.length - 2));
            var r:Number = NaN;
            var rs:String = s.right;
            if (typeof(rs) === 'string' && rs.length > 0)
                r = parseFloat(rs.substring(0, rs.length - 2));
            if (!isNaN(l) &&
                !isNaN(r)) {
                // if just using size constraints and image will not shrink or grow
                var computedWidth:Number = (host.positioner.offsetParent as HTMLElement).offsetWidth -
                    l - r;
                s.width = computedWidth.toString() + 'px';
            }
            var t:Number = NaN;
            var ts:String = s.top;
            if (typeof(ts) === 'string' && ts.length > 0)
                t = parseFloat(ts.substring(0, ts.length - 2));
            var b:Number = NaN;
            var bs:String = s.right;
            if (typeof(bs) === 'string' && bs.length > 0)
                b = parseFloat(bs.substring(0, bs.length - 2));
            if (!isNaN(t) &&
                !isNaN(b)) {
                // if just using size constraints and image will not shrink or grow
                var computedHeight:Number = (host.positioner.offsetParent as HTMLElement).offsetHeight -
                    t - b;
                s.height = computedHeight.toString() + 'px';
            }
        }
	}
}

////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You 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 org.apache.flex.html.beads
{
    COMPILE::AS3
    {
        import flash.display.Bitmap;
        import flash.display.Loader;
        import flash.display.LoaderInfo;
        import flash.events.IOErrorEvent;
        import flash.net.URLRequest;
    }
    COMPILE::JS
    {
        import goog.events;
    }

	import org.apache.flex.core.BeadViewBase;
	import org.apache.flex.core.IBeadView;
	import org.apache.flex.core.IImageModel;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.core.IUIBase;
	import org.apache.flex.core.UIBase;
	import org.apache.flex.events.Event;
	import org.apache.flex.events.IEventDispatcher;

	/**
	 *  The ImageView class creates the visual elements of the org.apache.flex.html.Image component.
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	public class ImageView extends BeadViewBase implements IBeadView
	{
		/**
		 *  constructor.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function ImageView()
		{
		}

        COMPILE::AS3
		private var bitmap:Bitmap;
        COMPILE::AS3
		private var loader:Loader;

		private var _model:IImageModel;

		/**
		 *  @copy org.apache.flex.core.IBead#strand
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		override public function set strand(value:IStrand):void
		{
			super.strand = value;

            COMPILE::AS3
            {
                IEventDispatcher(_strand).addEventListener("widthChanged",handleSizeChange);
                IEventDispatcher(_strand).addEventListener("heightChanged",handleSizeChange);
            }

			_model = value.getBeadByType(IImageModel) as IImageModel;
			_model.addEventListener("urlChanged",handleUrlChange);

			handleUrlChange(null);
		}

		/**
		 * @private
		 */
		private function handleUrlChange(event:Event):void
		{
            COMPILE::AS3
            {
                if (_model.source) {
                    loader = new Loader();
                    loader.contentLoaderInfo.addEventListener("complete",onComplete);
                    loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
                        trace(e);
                        e.preventDefault();
                    });
                    loader.load(new URLRequest(_model.source));
                }
            }
            COMPILE::JS
            {
				if (_model.source) {
	                var host:IUIBase = _strand as IUIBase;
	                host.element.addEventListener('load',
	                    loadHandler, false);
	                host.addEventListener('sizeChanged',
	                    sizeChangedHandler);
	                (host.element as HTMLImageElement).src = _model.source;
				}
            }
		}

		/**
		 * @private
		 */
        COMPILE::AS3
		private function onComplete(event:Object):void
		{
            var host:UIBase = UIBase(_strand);
			if (bitmap) {
				host.removeChild(bitmap);
			}

			bitmap = Bitmap(LoaderInfo(event.target).content);

			host.addChild(bitmap);

            if (host.isWidthSizedToContent())
            {
                host.dispatchEvent(new Event("widthChanged"));
                if (host.parent)
                    host.parent.dispatchEvent(new Event("layoutNeeded"));
            }
            else
                bitmap.width = UIBase(_strand).width;

            if (host.isHeightSizedToContent())
            {
                host.dispatchEvent(new Event("heightChanged"));
                if (host.parent)
                    host.parent.dispatchEvent(new Event("layoutNeeded"));
            }
            else
                bitmap.height = UIBase(_strand).height;

		}

		/**
		 * @private
		 */
        COMPILE::AS3
		private function handleSizeChange(event:Object):void
		{
            var host:UIBase = UIBase(_strand);
            if (bitmap) {
                if (!isNaN(host.explicitWidth) || !isNaN(host.percentWidth))
	    			bitmap.width = UIBase(_strand).width;
                if (!isNaN(host.explicitHeight) || !isNaN(host.percentHeight))
    				bitmap.height = UIBase(_strand).height;
			}
		}

        COMPILE::JS
        private function loadHandler(event:Object):void
        {
            var host:UIBase = UIBase(_strand);
            host.parent.dispatchEvent(new Event("layoutNeeded"));
        }

        /**
         * @flexjsignorecoercion HTMLElement
         */
        COMPILE::JS
        private function sizeChangedHandler(event:Object):void
        {
            var host:UIBase = _strand as UIBase;
            var s:Object = host.positioner.style;
            var l:Number = NaN;
            var ls:String = s.left;
            if (typeof(ls) === 'string' && ls.length > 0)
                l = parseFloat(ls.substring(0, ls.length - 2));
            var r:Number = NaN;
            var rs:String = s.right;
            if (typeof(rs) === 'string' && rs.length > 0)
                r = parseFloat(rs.substring(0, rs.length - 2));
            if (!isNaN(l) &&
                !isNaN(r)) {
                // if just using size constraints and image will not shrink or grow
                var computedWidth:Number = (host.positioner.offsetParent as HTMLElement).offsetWidth -
                    l - r;
                s.width = computedWidth.toString() + 'px';
            }
            var t:Number = NaN;
            var ts:String = s.top;
            if (typeof(ts) === 'string' && ts.length > 0)
                t = parseFloat(ts.substring(0, ts.length - 2));
            var b:Number = NaN;
            var bs:String = s.right;
            if (typeof(bs) === 'string' && bs.length > 0)
                b = parseFloat(bs.substring(0, bs.length - 2));
            if (!isNaN(t) &&
                !isNaN(b)) {
                // if just using size constraints and image will not shrink or grow
                var computedHeight:Number = (host.positioner.offsetParent as HTMLElement).offsetHeight -
                    t - b;
                s.height = computedHeight.toString() + 'px';
            }
        }
	}
}

fix image loading on the SWF side

fix image loading on the SWF side


package org.mangui.osmf.plugins.traits {
    import org.mangui.hls.HLS;
    import org.mangui.hls.event.HLSEvent;
    import org.osmf.traits.DynamicStreamTrait;
    import org.osmf.utils.OSMFStrings;

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

    public class HLSDynamicStreamTrait extends DynamicStreamTrait {
        private var _hls : HLS;

        public function HLSDynamicStreamTrait(hls : HLS) {
            CONFIG::LOGGING {
            Log.debug("HLSDynamicStreamTrait()");
            }
            _hls = hls;
            _hls.addEventListener(HLSEvent.LEVEL_SWITCH, _levelSwitchHandler);
            super(true, _hls.startlevel, hls.levels.length);
        }

        override public function dispose() : void {
            CONFIG::LOGGING {
            Log.debug("HLSDynamicStreamTrait:dispose");
            }
            _hls.removeEventListener(HLSEvent.LEVEL_SWITCH, _levelSwitchHandler);
            super.dispose();
        }

        override public function getBitrateForIndex(index : int) : Number {
            if (index > numDynamicStreams - 1 || index < 0) {
                throw new RangeError(OSMFStrings.getString(OSMFStrings.STREAMSWITCH_INVALID_INDEX));
            }
            var bitrate : Number = _hls.levels[index].bitrate / 1024;
            CONFIG::LOGGING {
            Log.debug("HLSDynamicStreamTrait:getBitrateForIndex(" + index + ")=" + bitrate);
            }
            return bitrate;
        }

        override public function switchTo(index : int) : void {
            CONFIG::LOGGING {
            Log.debug("HLSDynamicStreamTrait:switchTo(" + index + ")/max:" + maxAllowedIndex);
            }
            if (index < 0 || index > maxAllowedIndex) {
                throw new RangeError(OSMFStrings.getString(OSMFStrings.STREAMSWITCH_INVALID_INDEX));
            }
            autoSwitch = false;
            if (!switching) {
                setSwitching(true, index);
            }
        }

        override protected function autoSwitchChangeStart(value : Boolean) : void {
            CONFIG::LOGGING {
            Log.debug("HLSDynamicStreamTrait:autoSwitchChangeStart:" + value);
            }
            if (value == true && _hls.autolevel == false) {
                _hls.level = -1;
                // only seek if position is set
                if (!isNaN(_hls.position)) {
                    _hls.stream.seek(_hls.position);
                }
            }
        }

        override protected function switchingChangeStart(newSwitching : Boolean, index : int) : void {
            CONFIG::LOGGING {
            Log.debug("HLSDynamicStreamTrait:switchingChangeStart(newSwitching/index):" + newSwitching + "/" + index);
            }
            if (newSwitching) {
                _hls.level = index;
            }
        }

        /** Update playback position/duration **/
        private function _levelSwitchHandler(event : HLSEvent) : void {
            var newLevel : int = event.level;
            CONFIG::LOGGING {
            Log.debug("HLSDynamicStreamTrait:_qualitySwitchHandler:" + newLevel);
            }
            setCurrentIndex(newLevel);
            setSwitching(false, newLevel);
        };
    }
}

package org.mangui.osmf.plugins.traits {
    import org.mangui.hls.HLS;
    import org.mangui.hls.event.HLSEvent;
    import org.osmf.traits.DynamicStreamTrait;
    import org.osmf.utils.OSMFStrings;

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

    public class HLSDynamicStreamTrait extends DynamicStreamTrait {
        private var _hls : HLS;

        public function HLSDynamicStreamTrait(hls : HLS) {
            CONFIG::LOGGING {
            Log.debug("HLSDynamicStreamTrait()");
            }
            _hls = hls;
            _hls.addEventListener(HLSEvent.LEVEL_SWITCH, _levelSwitchHandler);
            super(true, _hls.startlevel, hls.levels.length);
        }

        override public function dispose() : void {
            CONFIG::LOGGING {
            Log.debug("HLSDynamicStreamTrait:dispose");
            }
            _hls.removeEventListener(HLSEvent.LEVEL_SWITCH, _levelSwitchHandler);
            super.dispose();
        }

        override public function getBitrateForIndex(index : int) : Number {
            if (index > numDynamicStreams - 1 || index < 0) {
                throw new RangeError(OSMFStrings.getString(OSMFStrings.STREAMSWITCH_INVALID_INDEX));
            }
            var bitrate : Number = _hls.levels[index].bitrate / 1000;
            CONFIG::LOGGING {
            Log.debug("HLSDynamicStreamTrait:getBitrateForIndex(" + index + ")=" + bitrate);
            }
            return bitrate;
        }

        override public function switchTo(index : int) : void {
            CONFIG::LOGGING {
            Log.debug("HLSDynamicStreamTrait:switchTo(" + index + ")/max:" + maxAllowedIndex);
            }
            if (index < 0 || index > maxAllowedIndex) {
                throw new RangeError(OSMFStrings.getString(OSMFStrings.STREAMSWITCH_INVALID_INDEX));
            }
            autoSwitch = false;
            if (!switching) {
                setSwitching(true, index);
            }
        }

        override protected function autoSwitchChangeStart(value : Boolean) : void {
            CONFIG::LOGGING {
            Log.debug("HLSDynamicStreamTrait:autoSwitchChangeStart:" + value);
            }
            if (value == true && _hls.autolevel == false) {
                _hls.level = -1;
                // only seek if position is set
                if (!isNaN(_hls.position)) {
                    _hls.stream.seek(_hls.position);
                }
            }
        }

        override protected function switchingChangeStart(newSwitching : Boolean, index : int) : void {
            CONFIG::LOGGING {
            Log.debug("HLSDynamicStreamTrait:switchingChangeStart(newSwitching/index):" + newSwitching + "/" + index);
            }
            if (newSwitching) {
                _hls.level = index;
            }
        }

        /** Update playback position/duration **/
        private function _levelSwitchHandler(event : HLSEvent) : void {
            var newLevel : int = event.level;
            CONFIG::LOGGING {
            Log.debug("HLSDynamicStreamTrait:_qualitySwitchHandler:" + newLevel);
            }
            setCurrentIndex(newLevel);
            setSwitching(false, newLevel);
        };
    }
}

fix bitrate computation related to #97

flashlsOSMF.swf: fix bitrate computation
related to #97


//
// $Id$
//
// Vilya library - tools for developing networked games
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/vilya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.parlor.client {

import mx.binding.utils.BindingUtils;

import mx.containers.Grid;

import mx.controls.CheckBox;
import mx.controls.HSlider;
import mx.controls.Label;

import com.threerings.flex.GridUtil;

import com.threerings.parlor.data.TableConfig;
import com.threerings.parlor.util.ParlorContext;

import com.threerings.parlor.game.client.FlexGameConfigurator;
import com.threerings.parlor.game.data.GameConfig;

/**
 * Provides a default implementation of a TableConfigurator for
 * a Swing interface.
 */
public class DefaultFlexTableConfigurator extends TableConfigurator
{
    /**
     * Create a TableConfigurator that allows for the specified configuration
     * parameters.
     */
    public function DefaultFlexTableConfigurator (
            desiredPlayers :int, minPlayers :int = -1, maxPlayers :int = -1,
            allowPrivate :Boolean = false)
    {
        if (minPlayers < 0) {
            minPlayers = desiredPlayers;
        }
        if (maxPlayers < 0) {
            maxPlayers = desiredPlayers;
        }

        _config.minimumPlayerCount = minPlayers;

        // create a slider for players, if applicable
        if (minPlayers != maxPlayers) {
            _playerSlider = new HSlider();
            _playerSlider.value = desiredPlayers;
            _playerSlider.minimum = minPlayers;
            _playerSlider.maximum = maxPlayers;
            _playerSlider.liveDragging = true;
            _playerSlider.snapInterval = 1;
            _playerSlider.showDataTip = false;

        } else {
            _config.desiredPlayerCount = desiredPlayers;
        }

        // create up the checkbox for private games, if applicable
        if (allowPrivate) {
            _privateCheck = new CheckBox();
        }
    }

    // documentation inherited
    override protected function createConfigInterface () :void
    {
        super.createConfigInterface();

        var gconf :FlexGameConfigurator =
            (_gameConfigurator as FlexGameConfigurator);

        if (_playerSlider != null) {
            // TODO: proper translation
            var playerLabel :Label = new Label();
            playerLabel.text = "Players:";

            var countLabel :Label = new Label();
            BindingUtils.bindProperty(countLabel, "text",
                _playerSlider, "value");

            var grid :Grid = new Grid();
            GridUtil.addRow(grid, countLabel, _playerSlider);

            gconf.addControl(playerLabel, grid);
        }

        if (_privateCheck != null) {
            // TODO: proper translation
            var privateLabel :Label = new Label();
            privateLabel.text = "Private:";
            gconf.addControl(privateLabel, _privateCheck);
        }
    }

    // documentation inherited
    override public function isEmpty () :Boolean
    {
        return (_playerSlider == null) && (_privateCheck == null);
    }

    // documentation inherited
    override protected function flushTableConfig() :void
    {
        super.flushTableConfig();

        if (_playerSlider != null) {
            _config.desiredPlayerCount = _playerSlider.value;
        }
        if (_privateCheck != null) {
            _config.privateTable = _privateCheck.selected;
        }
    }

    /** A slider for configuring the number of players at the table. */
    protected var _playerSlider :HSlider;

    /** A checkbox to allow the table creator to specify if the table is
     * private. */
    protected var _privateCheck :CheckBox;
}
}

//
// $Id$
//
// Vilya library - tools for developing networked games
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/vilya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.parlor.client {

import mx.containers.Grid;

import mx.controls.CheckBox;
import mx.controls.HSlider;
import mx.controls.Label;

import com.threerings.flex.GridUtil;
import com.threerings.flex.LabeledSlider;

import com.threerings.parlor.data.TableConfig;
import com.threerings.parlor.util.ParlorContext;

import com.threerings.parlor.game.client.FlexGameConfigurator;
import com.threerings.parlor.game.data.GameConfig;

/**
 * Provides a default implementation of a TableConfigurator for
 * a Swing interface.
 */
public class DefaultFlexTableConfigurator extends TableConfigurator
{
    /**
     * Create a TableConfigurator that allows for the specified configuration
     * parameters.
     */
    public function DefaultFlexTableConfigurator (
            desiredPlayers :int, minPlayers :int = -1, maxPlayers :int = -1,
            allowPrivate :Boolean = false)
    {
        if (minPlayers < 0) {
            minPlayers = desiredPlayers;
        }
        if (maxPlayers < 0) {
            maxPlayers = desiredPlayers;
        }

        _config.minimumPlayerCount = minPlayers;

        // create a slider for players, if applicable
        if (minPlayers != maxPlayers) {
            _playerSlider = new HSlider();
            _playerSlider.value = desiredPlayers;
            _playerSlider.minimum = minPlayers;
            _playerSlider.maximum = maxPlayers;
            _playerSlider.liveDragging = true;
            _playerSlider.snapInterval = 1;

        } else {
            _config.desiredPlayerCount = desiredPlayers;
        }

        // create up the checkbox for private games, if applicable
        if (allowPrivate) {
            _privateCheck = new CheckBox();
        }
    }

    // documentation inherited
    override protected function createConfigInterface () :void
    {
        super.createConfigInterface();

        var gconf :FlexGameConfigurator =
            (_gameConfigurator as FlexGameConfigurator);

        if (_playerSlider != null) {
            // TODO: proper translation
            var playerLabel :Label = new Label();
            playerLabel.text = "Players:";

            gconf.addControl(playerLabel, new LabeledSlider(_playerSlider));
        }

        if (_privateCheck != null) {
            // TODO: proper translation
            var privateLabel :Label = new Label();
            privateLabel.text = "Private:";
            gconf.addControl(privateLabel, _privateCheck);
        }
    }

    // documentation inherited
    override public function isEmpty () :Boolean
    {
        return (_playerSlider == null) && (_privateCheck == null);
    }

    // documentation inherited
    override protected function flushTableConfig() :void
    {
        super.flushTableConfig();

        if (_playerSlider != null) {
            _config.desiredPlayerCount = _playerSlider.value;
        }
        if (_privateCheck != null) {
            _config.privateTable = _privateCheck.selected;
        }
    }

    /** A slider for configuring the number of players at the table. */
    protected var _playerSlider :HSlider;

    /** A checkbox to allow the table creator to specify if the table is
     * private. */
    protected var _privateCheck :CheckBox;
}
}

Use the new LabeledSlider instead of rolling our own.

git-svn-id: a3e1eb16dde062992de22c830ed8045c8013209a@241 c613c5cb-e716-0410-b11b-feb51c14d237


package com.thedevstop.asfac
{
	import asunit.framework.TestCase;
	import flash.errors.IllegalOperationError;
	import flash.utils.Dictionary;
	/**
	 * ...
	 * @author
	 */
	public class FluentRegistrationTests extends TestCase
	{
		public function FluentRegistrationTests(testMethod:String = null)
		{
			super(testMethod);
		}

		public function test_should_allow_register_concrete_instance():void
		{
			var factory:FluentAsFactory = new FluentAsFactory();

			var instance:Object = { foo:"bar" };
			factory.register(instance).asType(Object);

			var result:Object = factory.resolve(Object);
			assertSame(instance, result);
		}

		public function test_should_allow_register_type():void
		{
			var factory:FluentAsFactory = new FluentAsFactory();

			factory.register(Dictionary).asType(Dictionary);

			var result:Object = factory.resolve(Dictionary);
			assertTrue(result.constructor == Dictionary);
		}

		public function test_should_allow_register_callback():void
		{
			var factory:FluentAsFactory = new FluentAsFactory();

			var source:Array = [1, 2, 3];
			factory.register(function():Array { return source; }).asType(Array);

			var result:Array = factory.resolve(Array);
			assertSame(source, result);
		}

		public function test_should_error_when_registering_callback_with_arguments():void
		{
			var factory:FluentAsFactory = new FluentAsFactory();

			var registerFunc:Function = function():void
			{
				factory.register(function(name:String):Array { return [1, 2, 3]; }).asType(Array);
			};

			assertThrows(IllegalOperationError, registerFunc);
		}

		public function test_should_allow_register_callback_as_singleton():void
		{
			var factory:FluentAsFactory = new FluentAsFactory();

			factory.register(function():Dictionary { return new Dictionary(); } ).asType(Dictionary).asSingleton();

			var result1:Object = factory.resolve(Dictionary);
			var result2:Object = factory.resolve(Dictionary);
			assertSame(result1, result2);
		}

		public function test_should_allow_register_type_as_singleton():void
		{
			var factory:FluentAsFactory = new FluentAsFactory();

			factory.register(Dictionary).asType(Dictionary).asSingleton();

			var result1:Object = factory.resolve(Dictionary);
			var result2:Object = factory.resolve(Dictionary);
			assertSame(result1, result2);
		}

		public function test_should_error_when_registering_type_is_null():void
		{
			var factory:FluentAsFactory = new FluentAsFactory();

			var registerFunc:Function = function():void
			{
				factory.register(Dictionary).asType(null);
			};

			assertThrows(IllegalOperationError, registerFunc);
		}
	}
}

package com.thedevstop.asfac
{
	import asunit.framework.TestCase;
	import flash.errors.IllegalOperationError;
	import flash.utils.Dictionary;
	/**
	 * ...
	 * @author
	 */
	public class FluentRegistrationTests extends TestCase
	{
		public function FluentRegistrationTests(testMethod:String = null)
		{
			super(testMethod);
		}

		public function test_should_allow_register_concrete_instance():void
		{
			var factory:FluentAsFactory = new FluentAsFactory();

			var instance:Object = { foo:"bar" };
			factory.register(instance).asType(Object);

			var result:Object = factory.resolve(Object);
			assertSame(instance, result);
		}

		public function test_should_allow_register_type():void
		{
			var factory:FluentAsFactory = new FluentAsFactory();

			factory.register(Dictionary).asType(Dictionary);

			var result:Object = factory.resolve(Dictionary);
			assertTrue(result.constructor == Dictionary);
		}

		public function test_should_allow_register_callback():void
		{
			var factory:FluentAsFactory = new FluentAsFactory();

			var source:Array = [1, 2, 3];
			factory.register(function():Array { return source; }).asType(Array);

			var result:Array = factory.resolve(Array);
			assertSame(source, result);
		}

		public function test_should_error_when_registering_callback_with_arguments():void
		{
			var factory:FluentAsFactory = new FluentAsFactory();

			var registerFunc:Function = function():void
			{
				factory.register(function(name:String):Array { return [1, 2, 3]; }).asType(Array);
			};

			assertThrows(IllegalOperationError, registerFunc);
		}

		public function test_should_allow_register_callback_as_singleton():void
		{
			var factory:FluentAsFactory = new FluentAsFactory();

			factory.register(function():Dictionary { return new Dictionary(); } ).asType(Dictionary).asSingleton();

			var result1:Object = factory.resolve(Dictionary);
			var result2:Object = factory.resolve(Dictionary);
			assertSame(result1, result2);
		}

		public function test_should_allow_register_type_as_singleton():void
		{
			var factory:FluentAsFactory = new FluentAsFactory();

			factory.register(Dictionary).asType(Dictionary).asSingleton();

			var result1:Object = factory.resolve(Dictionary);
			var result2:Object = factory.resolve(Dictionary);
			assertSame(result1, result2);
		}

		public function test_should_retun_new_instances_when_not_registered_as_singleton():void
		{
			var factory:FluentAsFactory = new FluentAsFactory();

			factory.register(Dictionary).asType(Dictionary);

			var result1:Object = factory.resolve(Dictionary);
			var result2:Object = factory.resolve(Dictionary);
			assertNotSame(result1, result2);
		}

		public function test_should_error_when_registering_type_is_null():void
		{
			var factory:FluentAsFactory = new FluentAsFactory();

			var registerFunc:Function = function():void
			{
				factory.register(Dictionary).asType(null);
			};

			assertThrows(IllegalOperationError, registerFunc);
		}
	}
}

Add fluent test that new instances are returned when registering not as singleton


package {

    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.DataEvent;
    import flash.events.IOErrorEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.XMLSocket;

    public class Agent extends Sprite {
	    private static const HOST:String = "localhost";
	    private static const PORT:int = 42624;
	    private static const PREFIX:String = "[AGENT]";

	    private var _host:String;
	    private var _port:int;
	    private var _socket:XMLSocket;
	    private var _connected:Boolean;

    	public function Agent() {
    	    trace(PREFIX, "Loaded");

            /*trace(loaderInfo.loaderURL, loaderInfo.url);*/

    	    _host = loaderInfo.parameters["host"] || HOST;
    	    _port = loaderInfo.parameters["port"] || PORT;

	        _socket = new XMLSocket();

            _socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, fail);
            _socket.addEventListener(IOErrorEvent.IO_ERROR, fail);
            _socket.addEventListener(DataEvent.DATA, dataReceived);
            _socket.addEventListener(Event.CONNECT, connected);
            _socket.addEventListener(Event.CLOSE, close);

            connect();
    	}

    	private function dataReceived(e:DataEvent):void {
    	    trace(PREFIX, "Received command", e.data);
    	}

    	private function connect():void {
    	    trace(PREFIX, "Trying to connect to", _host, ":", _port);

    	    try {
    	        _socket.connect(_host, _port);
	        } catch (e:Error) {
	            trace(PREFIX, "Unable to connect ", e);
	        }
    	}

    	private function connected(e:Event):void {
    	   _connected = true;
    	   trace(PREFIX, "Connected");
    	}

    	private function close(e:Event):void {
    	   _connected = false;
    	   trace(PREFIX, "Disconnected, will try to reconnect");

           connect();
    	}

    	private function fail(e:Event):void {
            trace(PREFIX, "Communication failure", e);
    	}
    }
}

package {

    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.DataEvent;
    import flash.events.IOErrorEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.XMLSocket;

    public class Agent extends Sprite {
	    private static const HOST:String = "localhost";
	    private static const PORT:int = 42624;
	    private static const PREFIX:String = "[AGENT]";

	    private var _host:String;
	    private var _port:int;
	    private var _socket:XMLSocket;
	    private var _connected:Boolean;

    	public function Agent() {
    	    trace(PREFIX, "Loaded");

    	    _host = loaderInfo.parameters["host"] || HOST;
    	    _port = loaderInfo.parameters["port"] || PORT;

	        _socket = new XMLSocket();

            _socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, fail);
            _socket.addEventListener(IOErrorEvent.IO_ERROR, fail);
            _socket.addEventListener(DataEvent.DATA, dataReceived);
            _socket.addEventListener(Event.CONNECT, connected);
            _socket.addEventListener(Event.CLOSE, close);

            connect();
    	}

    	private function dataReceived(e:DataEvent):void {
    	    trace(PREFIX, "Received command", e.data);
    	}

    	private function connect():void {
    	    trace(PREFIX, "Trying to connect to", _host, ":", _port);

    	    try {
    	        _socket.connect(_host, _port);
	        } catch (e:Error) {
	            trace(PREFIX, "Unable to connect ", e);
	        }
    	}

    	private function connected(e:Event):void {
    	   _connected = true;
    	   trace(PREFIX, "Connected");
    	}

    	private function close(e:Event):void {
    	   _connected = false;
    	   trace(PREFIX, "Disconnected, will try to reconnect");

           connect();
    	}

    	private function fail(e:Event):void {
            trace(PREFIX, "Communication failure", e);
    	}
    }
}

remove debug line

remove debug line


////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You 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 spark.skins.ios7
{
import spark.components.ButtonBar;
import spark.components.ButtonBarButton;
import spark.components.DataGroup;
import spark.components.supportClasses.ButtonBarHorizontalLayout;
import spark.skins.mobile.supportClasses.ButtonBarButtonClassFactory;
import spark.skins.mobile.supportClasses.MobileSkin;

/**
 *  iOS7+ specific skin class for the Spark ButtonBar component.
 *
 *  @see spark.components.ButtonBar
 *
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
public class ButtonBarSkin extends MobileSkin
{
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     * Constructor.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     *
     */
    public function ButtonBarSkin()
    {
        super();
    }

    //--------------------------------------------------------------------------
    //
    //  Skin parts
    //
    //--------------------------------------------------------------------------

    /**
     *  @copy spark.skins.spark.ApplicationSkin#hostComponent
     */
    public var hostComponent:ButtonBar;

    /**
     *  @copy spark.components.ButtonBar#firstButton
     */
    public var firstButton:ButtonBarButtonClassFactory;

    /**
     *  @copy spark.components.ButtonBar#lastButton
     */
    public var lastButton:ButtonBarButtonClassFactory;

    /**
     *  @copy spark.components.ButtonBar#middleButton
     */
    public var middleButton:ButtonBarButtonClassFactory;

    /**
     *  @copy spark.components.SkinnableDataContainer#dataGroup
     */
    public var dataGroup:DataGroup;

    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override protected function createChildren():void
    {
        // Set up the class factories for the buttons
        if (!firstButton)
        {
            firstButton = new ButtonBarButtonClassFactory(ButtonBarButton);
            firstButton.skinClass = spark.skins.ios7.ButtonBarFirstButtonSkin;
        }

        if (!lastButton)
        {
            lastButton = new ButtonBarButtonClassFactory(ButtonBarButton);
            lastButton.skinClass = spark.skins.ios7.ButtonBarLastButtonSkin;
        }

        if (!middleButton)
        {
            middleButton = new ButtonBarButtonClassFactory(ButtonBarButton);
            middleButton.skinClass = spark.skins.ios7.ButtonBarMiddleButtonSkin;
        }

        // create the data group to house the buttons
        if (!dataGroup)
        {
            dataGroup = new DataGroup();
            var hLayout:ButtonBarHorizontalLayout = new ButtonBarHorizontalLayout();
            hLayout.gap = -1;
            dataGroup.layout = hLayout;
            addChild(dataGroup);
        }
    }

    /**
     *  @private
     */
    override protected function commitCurrentState():void
    {
        alpha = (currentState == "disabled") ? 0.5 : 1;
    }

    /**
     *  @private
     */
    override protected function measure():void
    {
        measuredWidth = dataGroup.measuredWidth;
        measuredHeight = dataGroup.measuredHeight;

        measuredMinWidth = dataGroup.measuredMinWidth;
        measuredMinHeight = dataGroup.measuredMinHeight;
    }

    /**
     *  @private
     */
    override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.layoutContents(unscaledWidth, unscaledHeight);

        setElementPosition(dataGroup, 0, 0);
        setElementSize(dataGroup, unscaledWidth, unscaledHeight);
    }
}
}

////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You 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 spark.skins.ios7
{
import spark.components.ButtonBar;
import spark.components.ButtonBarButton;
import spark.components.DataGroup;
import spark.components.supportClasses.ButtonBarHorizontalLayout;
import spark.skins.mobile.supportClasses.ButtonBarButtonClassFactory;
import spark.skins.mobile.supportClasses.MobileSkin;

/**
 *  iOS7+ specific skin class for the Spark ButtonBar component.
 *
 *  @see spark.components.ButtonBar
 *
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
public class ButtonBarSkin extends MobileSkin
{
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     * Constructor.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     *
     */
    public function ButtonBarSkin()
    {
        super();
    }

    //--------------------------------------------------------------------------
    //
    //  Skin parts
    //
    //--------------------------------------------------------------------------

    /**
     *  @copy spark.skins.spark.ApplicationSkin#hostComponent
     */
    public var hostComponent:ButtonBar;

    /**
     *  @copy spark.components.ButtonBar#firstButton
     */
    public var firstButton:ButtonBarButtonClassFactory;

    /**
     *  @copy spark.components.ButtonBar#lastButton
     */
    public var lastButton:ButtonBarButtonClassFactory;

    /**
     *  @copy spark.components.ButtonBar#middleButton
     */
    public var middleButton:ButtonBarButtonClassFactory;

    /**
     *  @copy spark.components.SkinnableDataContainer#dataGroup
     */
    public var dataGroup:DataGroup;

    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override protected function createChildren():void
    {
        // Set up the class factories for the buttons
        if (!firstButton)
        {
            firstButton = new ButtonBarButtonClassFactory(ButtonBarButton);
            firstButton.skinClass = spark.skins.ios7.ButtonBarFirstButtonSkin;
        }

        if (!lastButton)
        {
            lastButton = new ButtonBarButtonClassFactory(ButtonBarButton);
            lastButton.skinClass = spark.skins.ios7.ButtonBarLastButtonSkin;
        }

        if (!middleButton)
        {
            middleButton = new ButtonBarButtonClassFactory(ButtonBarButton);
            middleButton.skinClass = spark.skins.ios7.ButtonBarMiddleButtonSkin;
        }

        // create the data group to house the buttons
        if (!dataGroup)
        {
            dataGroup = new DataGroup();
            var hLayout:ButtonBarHorizontalLayout = new ButtonBarHorizontalLayout();
			//TODO: Gap should vary depending on current DPI
            hLayout.gap = -1;
            dataGroup.layout = hLayout;
            addChild(dataGroup);
        }
    }

    /**
     *  @private
     */
    override protected function commitCurrentState():void
    {
        alpha = (currentState == "disabled") ? 0.5 : 1;
    }

    /**
     *  @private
     */
    override protected function measure():void
    {
        measuredWidth = dataGroup.measuredWidth;
        measuredHeight = dataGroup.measuredHeight;

        measuredMinWidth = dataGroup.measuredMinWidth;
        measuredMinHeight = dataGroup.measuredMinHeight;
    }

    /**
     *  @private
     */
    override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.layoutContents(unscaledWidth, unscaledHeight);

        setElementPosition(dataGroup, 0, 0);
        setElementSize(dataGroup, unscaledWidth, unscaledHeight);
    }
}
}

Add TODO

Add TODO


package aerys.minko.render.geometry.stream
{
	import aerys.minko.ns.minko_stream;
	import aerys.minko.render.geometry.stream.format.VertexComponent;
	import aerys.minko.render.geometry.stream.format.VertexFormat;
	import aerys.minko.type.Signal;

	public final class VertexStreamList implements IVertexStream
	{
		use namespace minko_stream;

		private var _streams		: Vector.<VertexStream>	= new Vector.<VertexStream>();
		private var _format			: VertexFormat			= new VertexFormat();
		private var _usage			: uint					= 0;

		private var _changed		: Signal				= new Signal('VertexStreamList.changed');
		private var _boundsChanged	: Signal				= new Signal('VertexStream.boundsChanged');

		public function get usage()	: uint
		{
			return _usage;
		}

		public function get format() : VertexFormat
		{
			return _format;
		}

		public function get numStreams() : uint
		{
			return _streams.length;
		}

		public function get numVertices() : uint
		{
			return _streams.length ? _streams[0].numVertices : 0;
		}

		public function get changed() : Signal
		{
			return _changed;
		}

		public function get boundsChanged() : Signal
		{
			return _boundsChanged;
		}

		public function VertexStreamList(...streams)
		{
			initialize(streams);
		}

		private function initialize(streams : Array) : void
		{
			for each (var stream : VertexStream in streams)
				pushVertexStream(stream);
		}

		public function clone() : VertexStreamList
		{
			var vertexStreamList : VertexStreamList = new VertexStreamList();

			vertexStreamList._streams = _streams.concat();
			vertexStreamList._format = _format.clone();

			return vertexStreamList;
		}

		public function pushVertexStream(vertexStream : VertexStream, force : Boolean = false) : void
		{
			if (numVertices && vertexStream.numVertices != numVertices)
				throw new Error('All streams must have the same total number of vertices.');

			_usage |= vertexStream.usage;
			_format.unionWith(vertexStream.format, force);
			_streams.push(vertexStream);

			vertexStream.changed.add(subStreamChangedHandler);
			vertexStream.boundsChanged.add(subStreamBoundsChangedHandler);
		}

		public function getSubStreamById(id : int) : VertexStream
		{
			return _streams[id];
		}

		public function getStreamByComponent(vertexComponent : VertexComponent) : VertexStream
		{
			var streamLength	: int = _streams.length;

			for (var i : int = streamLength - 1; i >= 0; --i)
				if (_streams[i].format.hasComponent(vertexComponent))
					return _streams[i];

			return null;
		}

		public function getVertexStream(id : int = 0) : VertexStream
		{
			return id < _streams.length ? _streams[id] : null;
		}

		public function getVertexProperty(index 		: uint,
										  component 	: VertexComponent 	= null,
										  offset 		: uint 				= 0) : Number
		{
			if (!format.hasComponent(component))
				throw new Error(
					'This stream does not provide the \'' + component + '\' vertex component.'
				);

			return getStreamByComponent(component).getVertexProperty(index, component, offset);
		}

		public function setVertexProperty(index 		: uint,
										  value 		: Number,
										  component 	: VertexComponent 	= null,
										  offset 		: uint 				= 0) : void
		{
			if (!format.hasComponent(component))
				throw new Error(
					'This stream does not provide the \'' + component + '\' vertex component.'
				);

			return getStreamByComponent(component).setVertexProperty(
				index, value, component, offset
			);
		}

		public function deleteVertex(index : uint) : IVertexStream
		{
			for each (var stream : VertexStream in _streams)
				stream.deleteVertex(index);

			return this;
		}

		public function duplicateVertex(index : uint) : IVertexStream
		{
			for each (var stream : VertexStream in _streams)
				stream.duplicateVertex(index);

			return this;
		}

		public function disposeLocalData(waitForUpload : Boolean = true) : void
		{
			for (var i : int = _streams.length - 1; i >= 0; --i)
				_streams[i].disposeLocalData(waitForUpload);
		}

		public function dispose() : void
		{
			for (var i : int = _streams.length - 1; i >= 0; --i)
				_streams[i].dispose();
		}

		private function subStreamChangedHandler(subStream : VertexStream) : void
		{
			_changed.execute(this);
		}

		private function subStreamBoundsChangedHandler(subStream : VertexStream) : void
		{
			_boundsChanged.execute(this);
		}
	}
}

package aerys.minko.render.geometry.stream
{
	import aerys.minko.ns.minko_stream;
	import aerys.minko.render.geometry.stream.format.VertexComponent;
	import aerys.minko.render.geometry.stream.format.VertexFormat;
	import aerys.minko.type.Signal;

	public final class VertexStreamList implements IVertexStream
	{
		use namespace minko_stream;

		private var _streams		: Vector.<VertexStream>	= new Vector.<VertexStream>();
		private var _format			: VertexFormat			= new VertexFormat();
		private var _usage			: uint					= 0;

		private var _changed		: Signal				= new Signal('VertexStreamList.changed');
		private var _boundsChanged	: Signal				= new Signal('VertexStream.boundsChanged');

		public function get usage()	: uint
		{
			return _usage;
		}

		public function get format() : VertexFormat
		{
			return _format;
		}

		public function get numStreams() : uint
		{
			return _streams.length;
		}

		public function get numVertices() : uint
		{
			return _streams.length ? _streams[0].numVertices : 0;
		}

		public function get changed() : Signal
		{
			return _changed;
		}

		public function get boundsChanged() : Signal
		{
			return _boundsChanged;
		}

		public function VertexStreamList(...streams)
		{
			initialize(streams);
		}

		private function initialize(streams : Array) : void
		{
			for each (var stream : VertexStream in streams)
				pushVertexStream(stream);
		}

		public function clone() : VertexStreamList
		{
			var vertexStreamList : VertexStreamList = new VertexStreamList();

			vertexStreamList._streams = _streams.concat();
			vertexStreamList._format = _format.clone();

			return vertexStreamList;
		}

		public function pushVertexStream(vertexStream   : VertexStream,
                                         force          : Boolean = false) : void
		{
			if (numVertices && vertexStream.numVertices != numVertices)
				throw new Error('All streams must have the same total number of vertices.');

			_usage |= vertexStream.usage;
			_format.unionWith(vertexStream.format, force);
			_streams.push(vertexStream);

			vertexStream.changed.add(subStreamChangedHandler);
			vertexStream.boundsChanged.add(subStreamBoundsChangedHandler);

            _changed.execute(this);
		}

		public function getSubStreamById(id : int) : VertexStream
		{
			return _streams[id];
		}

		public function getStreamByComponent(vertexComponent : VertexComponent) : VertexStream
		{
			var streamLength	: int = _streams.length;

			for (var i : int = streamLength - 1; i >= 0; --i)
				if (_streams[i].format.hasComponent(vertexComponent))
					return _streams[i];

			return null;
		}

		public function getVertexStream(id : int = 0) : VertexStream
		{
			return id < _streams.length ? _streams[id] : null;
		}

		public function getVertexProperty(index 		: uint,
										  component 	: VertexComponent 	= null,
										  offset 		: uint 				= 0) : Number
		{
			if (!format.hasComponent(component))
				throw new Error(
					'This stream does not provide the \'' + component + '\' vertex component.'
				);

			return getStreamByComponent(component).getVertexProperty(index, component, offset);
		}

		public function setVertexProperty(index 		: uint,
										  value 		: Number,
										  component 	: VertexComponent 	= null,
										  offset 		: uint 				= 0) : void
		{
			if (!format.hasComponent(component))
				throw new Error(
					'This stream does not provide the \'' + component + '\' vertex component.'
				);

			return getStreamByComponent(component).setVertexProperty(
				index, value, component, offset
			);
		}

		public function deleteVertex(index : uint) : IVertexStream
		{
			for each (var stream : VertexStream in _streams)
				stream.deleteVertex(index);

			return this;
		}

		public function duplicateVertex(index : uint) : IVertexStream
		{
			for each (var stream : VertexStream in _streams)
				stream.duplicateVertex(index);

			return this;
		}

		public function disposeLocalData(waitForUpload : Boolean = true) : void
		{
			for (var i : int = _streams.length - 1; i >= 0; --i)
				_streams[i].disposeLocalData(waitForUpload);
		}

		public function dispose() : void
		{
			for (var i : int = _streams.length - 1; i >= 0; --i)
				_streams[i].dispose();
		}

		private function subStreamChangedHandler(subStream : VertexStream) : void
		{
			_changed.execute(this);
		}

		private function subStreamBoundsChangedHandler(subStream : VertexStream) : void
		{
			_boundsChanged.execute(this);
		}
	}
}

add missing execution of VertexStreamList.changed in VertexStreamList.pushVertexStream()


package aerys.minko.render.material.realistic
{
	import aerys.minko.render.Effect;
	import aerys.minko.render.material.environment.EnvironmentMappingProperties;
	import aerys.minko.render.material.phong.PhongEffect;
	import aerys.minko.render.material.phong.PhongMaterial;
	import aerys.minko.render.resource.texture.ITextureResource;
	import aerys.minko.scene.node.Scene;
	import aerys.minko.type.binding.IDataProvider;

	import flash.utils.Dictionary;

	public class RealisticMaterial extends PhongMaterial
	{
		private static const DEFAULT_NAME		: String		= 'RealisticMaterial';
        private static const DEFAULT_EFFECT     : Effect        = new PhongEffect(
            new RealisticShader()
        );

		public function get environmentMap() : ITextureResource
		{
			return getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP) as ITextureResource;
		}
		public function set environmentMap(value : ITextureResource) : void
		{
			setProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP, value);
		}

        public function get environmentMapFiltering() : uint
        {
            return getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_FILTERING);
        }
        public function set environmentMapFiltering(value : uint) : void
        {
            setProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_FILTERING, value);
        }

        public function get environmentMapMipMapping() : uint
        {
            return getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_MIPMAPPING);
        }
        public function set environmentMapMipMapping(value : uint) : void
        {
            setProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_MIPMAPPING, value);
        }

        public function get environmentMapWrapping() : uint
        {
            return getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_WRAPPING);
        }
        public function set environmentMapWrapping(value : uint) : void
        {
            setProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_WRAPPING, value);
        }

        public function get environmentMapFormat() : uint
        {
            return getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_FORMAT);
        }
        public function set environmentMapFormat(value : uint) : void
        {
            setProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_FORMAT, value);
        }

		public function get reflectivity() : Number
		{
			return getProperty(EnvironmentMappingProperties.REFLECTIVITY) as Number;
		}
		public function set reflectivity(value : Number) : void
		{
			setProperty(EnvironmentMappingProperties.REFLECTIVITY, value);
		}

		public function get environmentMappingType() : uint
		{
			return getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAPPING_TYPE) as uint;
		}
		public function set environmentMappingType(value : uint) : void
		{
			setProperty(EnvironmentMappingProperties.ENVIRONMENT_MAPPING_TYPE, value);
		}

		public function get environmentBlending() : uint
		{
			return getProperty(EnvironmentMappingProperties.ENVIRONMENT_BLENDING) as uint;
		}
		public function set environmentBlending(value : uint) : void
		{
			setProperty(EnvironmentMappingProperties.ENVIRONMENT_BLENDING, value);
		}

		public function RealisticMaterial(properties	: Object	= null,
										  effect		: Effect	= null,
										  name			: String	= DEFAULT_NAME)
		{
			super(properties, effect || DEFAULT_EFFECT, name);
		}

        override public function clone() : IDataProvider
        {
            return new RealisticMaterial(this, effect, name);
        }
	}
}

package aerys.minko.render.material.realistic
{
	import aerys.minko.render.Effect;
	import aerys.minko.render.material.environment.EnvironmentMappingProperties;
	import aerys.minko.render.material.phong.PhongEffect;
	import aerys.minko.render.material.phong.PhongMaterial;
	import aerys.minko.render.resource.texture.ITextureResource;
	import aerys.minko.type.binding.IDataProvider;

	public class RealisticMaterial extends PhongMaterial
	{
		private static const DEFAULT_NAME		: String		= 'RealisticMaterial';
        private static const DEFAULT_EFFECT     : Effect        = new PhongEffect(
            new RealisticShader()
        );

		public function get environmentMap() : ITextureResource
		{
			return getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP) as ITextureResource;
		}
		public function set environmentMap(value : ITextureResource) : void
		{
			setProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP, value);
		}

        public function get environmentMapFiltering() : uint
        {
            return getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_FILTERING);
        }
        public function set environmentMapFiltering(value : uint) : void
        {
            setProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_FILTERING, value);
        }

        public function get environmentMapMipMapping() : uint
        {
            return getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_MIPMAPPING);
        }
        public function set environmentMapMipMapping(value : uint) : void
        {
            setProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_MIPMAPPING, value);
        }

        public function get environmentMapWrapping() : uint
        {
            return getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_WRAPPING);
        }
        public function set environmentMapWrapping(value : uint) : void
        {
            setProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_WRAPPING, value);
        }

        public function get environmentMapFormat() : uint
        {
            return getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_FORMAT);
        }
        public function set environmentMapFormat(value : uint) : void
        {
            setProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_FORMAT, value);
        }

		public function get reflectivity() : Number
		{
			return getProperty(EnvironmentMappingProperties.REFLECTIVITY) as Number;
		}
		public function set reflectivity(value : Number) : void
		{
			setProperty(EnvironmentMappingProperties.REFLECTIVITY, value);
		}

		public function get environmentMappingType() : uint
		{
			return getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAPPING_TYPE) as uint;
		}
		public function set environmentMappingType(value : uint) : void
		{
			setProperty(EnvironmentMappingProperties.ENVIRONMENT_MAPPING_TYPE, value);
		}

		public function get environmentBlending() : uint
		{
			return getProperty(EnvironmentMappingProperties.ENVIRONMENT_BLENDING) as uint;
		}
		public function set environmentBlending(value : uint) : void
		{
			setProperty(EnvironmentMappingProperties.ENVIRONMENT_BLENDING, value);
		}

		public function RealisticMaterial(properties	: Object	= null,
										  effect		: Effect	= null,
										  name			: String	= DEFAULT_NAME)
		{
			super(properties, effect || DEFAULT_EFFECT, name);
		}

        override public function clone() : IDataProvider
        {
            return new RealisticMaterial(this, effect, name);
        }
	}
}

remove useless imports

remove useless imports


/*
 * Copyright 2008 Adobe Systems Inc., 2008 Google Inc.
 *
 * 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.
 *
 * Contributor(s):
 *   Zwetan Kjukov <zwetan@gmail.com>.
 */

package
{
    import com.google.analytics.AnalyticsTracker;
    import com.google.analytics.GATracker;
    import com.google.analytics.core.TrackerMode;

    import flash.display.Sprite;
    import flash.events.Event;

    /* note:
       Basic example

    */
    [SWF(width="800", height="600", backgroundColor='0xffffff', frameRate='24', pageTitle='example', scriptRecursionLimit='1000', scriptTimeLimit='60')]
    [ExcludeClass]
    public class gaforflash_example extends Sprite
    {
        /* You need to define a valid GA ID here */
        private const GA_ID:String = "UA-111-222";

        public var tracker:AnalyticsTracker;

        public function gaforflash_example()
        {
            super();

            if( stage )
            {
                onAddedToStage();
            }
            else
            {
                addEventListener( Event.ADDED_TO_STAGE, onAddedToStage );
            }

        }

        private function onAddedToStage( event:Event = null ):void
        {
            removeEventListener( Event.ADDED_TO_STAGE, onAddedToStage );
            main();
        }

        private function _gasetup():void
        {
            /* we prevent the factory to build automatically */
            GATracker.autobuild = false;

            /* instanciation of the Google Analytics tracker */
            tracker = new GATracker( this, GA_ID );

            /* note:
               the 'this' reference need to be a DisplayObject
               properly instancied, eg. added to the display list
               so we can access the 'stage' property.
            */

            /* we configure the tracker */
            tracker.mode = TrackerMode.AS3;
            tracker.config.sessionTimeout = 60;
            tracker.config.conversionTimeout = 180;

            /* we force the factory to build the tracker */
            GATracker(tracker).build();
        }

        private function _gatest():void
        {
            //track pageview test
            tracker.trackPageview( "/test" );

            //track event test
            tracker.trackEvent( "say", "hello world", "test", 123 );
        }

        public function main():void
        {
            /* note:
               any call ot the GA API before its setup
               will be cached temporarily

               and once the GATracker build
               the cached functions will run in batch
            */
            tracker.trackPageview( "/before/setup" );

            _gasetup();

            /* note:
               from this point the GATracker is initialized
               and will send data to the Google Analytics server
            */

            _gatest();

        }

    }
}

/*
 * Copyright 2008 Adobe Systems Inc., 2008 Google Inc.
 *
 * 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.
 *
 * Contributor(s):
 *   Zwetan Kjukov <zwetan@gmail.com>.
 */

package
{
    import com.google.analytics.AnalyticsTracker;
    import com.google.analytics.GATracker;
    import com.google.analytics.core.TrackerMode;

    import flash.display.Sprite;
    import flash.events.Event;

    /* note:
       Basic example

    */
    [SWF(width="800", height="600", backgroundColor='0xffffff', frameRate='24', pageTitle='example', scriptRecursionLimit='1000', scriptTimeLimit='60')]
    [ExcludeClass]
    public class gaforflash_example extends Sprite
    {
        /* You need to define a valid GA ID here */
        //private const GA_ID:String = "UA-111-222";
        private const GA_ID:String = "UA-94526-19";

        public var tracker:AnalyticsTracker;

        public function gaforflash_example()
        {
            super();

            if( stage )
            {
                onAddedToStage();
            }
            else
            {
                addEventListener( Event.ADDED_TO_STAGE, onAddedToStage );
            }

        }

        private function onAddedToStage( event:Event = null ):void
        {
            removeEventListener( Event.ADDED_TO_STAGE, onAddedToStage );
            main();
        }

        private function _gasetup():void
        {
            /* we prevent the factory to build automatically */
            GATracker.autobuild = false;

            /* instanciation of the Google Analytics tracker */
            tracker = new GATracker( this, GA_ID );

            /* note:
               the 'this' reference need to be a DisplayObject
               properly instancied, eg. added to the display list
               so we can access the 'stage' property.
            */

            /* we configure the tracker */
            tracker.mode = TrackerMode.AS3;
            tracker.config.sessionTimeout = 60;
            tracker.config.conversionTimeout = 180;

            /* we force the factory to build the tracker */
            GATracker(tracker).build();
        }

        private function _gatest():void
        {
            //track pageview test
            tracker.trackPageview( "/test" );

            //track event test
            tracker.trackEvent( "say", "hello world", "test", 123 );
        }

        public function main():void
        {
            /* note:
               any call ot the GA API before its setup
               will be cached temporarily

               and once the GATracker build
               the cached functions will run in batch
            */
            //tracker.trackPageview( "/before/setup" );

            _gasetup();

            /* note:
               from this point the GATracker is initialized
               and will send data to the Google Analytics server
            */

            _gatest();

        }

    }
}

update example

update example


////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You 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 org.apache.flex.binding
{
	import org.apache.flex.core.IBead;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.core.IDocument;

    /**
     *  The ConstantBinding class is lightweight data-binding class that
     *  is optimized for simple assignments of one object's constant to
     *  another object's property.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
	public class ConstantBinding implements IBead, IDocument
	{
        /**
         *  Constructor.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function ConstantBinding()
		{
		}

        /**
         *  The source object who's property has the value we want.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		protected var source:Object;

        /**
         *  The host mxml document for the source and
         *  destination objects.  The source object
         *  is either this document for simple bindings
         *  like {foo} where foo is a property on
         *  the mxml documnet, or found as document[sourceID]
         *  for simple bindings like {someid.someproperty}
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		protected var document:Object;

        /**
         *  The destination object.  It is always the same
         *  as the strand.  ConstantBindings are attached to
         *  the strand of the destination object.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        protected var destination:Object;

        /**
         *  If not null, the id of the mxml tag who's property
         *  is being watched for changes.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public var sourceID:String;

        /**
         *  If not null, the name of a property on the
         *  mxml document that is being watched for changes.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public var sourcePropertyName:String;

        /**
         *  The name of the property on the strand that
         *  is set when the source property changes.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public var destinationPropertyName:String;

        /**
         *  @copy org.apache.flex.core.IBead#strand
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function set strand(value:IStrand):void
		{
			destination = value;
			source = document[sourceID];
			destination[destinationPropertyName] = source[sourcePropertyName];
		}

        /**
         *  @copy org.apache.flex.core.IDocument#setDocument()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function setDocument(document:Object, id:String = null):void
		{
			this.document = document;
		}

	}
}

////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You 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 org.apache.flex.binding
{
	import org.apache.flex.core.IBead;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.core.IDocument;

    /**
     *  The ConstantBinding class is lightweight data-binding class that
     *  is optimized for simple assignments of one object's constant to
     *  another object's property.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
	public class ConstantBinding implements IBead, IDocument
	{
        /**
         *  Constructor.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function ConstantBinding()
		{
		}

        /**
         *  The source object who's property has the value we want.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		protected var source:Object;

        /**
         *  The host mxml document for the source and
         *  destination objects.  The source object
         *  is either this document for simple bindings
         *  like {foo} where foo is a property on
         *  the mxml documnet, or found as document[sourceID]
         *  for simple bindings like {someid.someproperty}
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		protected var document:Object;

        /**
         *  The destination object.  It is always the same
         *  as the strand.  ConstantBindings are attached to
         *  the strand of the destination object.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public var destination:Object;

        /**
         *  If not null, the id of the mxml tag who's property
         *  is being watched for changes.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public var sourceID:String;

        /**
         *  If not null, the name of a property on the
         *  mxml document that is being watched for changes.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public var sourcePropertyName:String;

        /**
         *  The name of the property on the strand that
         *  is set when the source property changes.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public var destinationPropertyName:String;

        /**
         *  @copy org.apache.flex.core.IBead#strand
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function set strand(value:IStrand):void
		{
            if (destination == null)
                destination = value;

			source = document[sourceID];
			destination[destinationPropertyName] = source[sourcePropertyName];
		}

        /**
         *  @copy org.apache.flex.core.IDocument#setDocument()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function setDocument(document:Object, id:String = null):void
		{
			this.document = document;
		}

	}
}

allow override of destination in ConstantBinding as well


////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You 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 org.apache.flex.html.beads
{
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.text.TextFieldType;

	import org.apache.flex.core.IBead;
    import org.apache.flex.core.IBeadModel;
	import org.apache.flex.core.IScrollBarModel;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.core.IParent;
    import org.apache.flex.core.ValuesManager;
	import org.apache.flex.html.beads.models.ScrollBarModel;
	import org.apache.flex.html.supportClasses.Border;
	import org.apache.flex.html.supportClasses.ScrollBar;

    /**
     *  The TextAreaView class is the default view for
     *  the org.apache.flex.html.TextArea class.
     *  It implements the classic desktop-like TextArea with
     *  a border and scrollbars.  It does not support right-to-left text.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
	public class TextAreaView extends TextFieldViewBase implements IStrand
	{
        /**
         *  Constructor.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function TextAreaView()
		{
			super();

			textField.selectable = true;
			textField.type = TextFieldType.INPUT;
			textField.mouseEnabled = true;
			textField.multiline = true;
			textField.wordWrap = true;
		}

		private var _border:Border;

        /**
         *  The border.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function get border():Border
		{
			return _border;
		}

		private var _vScrollBar:ScrollBar;

        /**
         *  The vertical ScrollBar.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function get vScrollBar():ScrollBar
		{
			if (!_vScrollBar)
				_vScrollBar = createScrollBar();
			return _vScrollBar;
		}

        /**
         *  @private
         */
		override public function set strand(value:IStrand):void
		{
			super.strand = value;

			// add a border to this
			_border = new Border();
			_border.model = new (ValuesManager.valuesImpl.getValue(value, "iBorderModel")) as IBeadModel;
			_border.addBead(new (ValuesManager.valuesImpl.getValue(value, "iBorderBead")) as IBead);
            IParent(host).addElement(border);

			var vb:ScrollBar = vScrollBar;

			// Default size
			var ww:Number = DisplayObject(host).width;
			if( isNaN(ww) || ww == 0 ) DisplayObject(host).width = 100;
			var hh:Number = DisplayObject(host).height;
			if( isNaN(hh) || hh == 0 ) DisplayObject(host).height = 42;

			// for input, listen for changes to the _textField and update
			// the model
			textField.addEventListener(Event.SCROLL, textScrollHandler);

			IEventDispatcher(host).addEventListener("widthChanged", sizeChangedHandler);
			IEventDispatcher(host).addEventListener("heightChanged", sizeChangedHandler);
			sizeChangedHandler(null);
		}

		private function createScrollBar():ScrollBar
		{
			var vsb:ScrollBar;
			vsb = new ScrollBar();
			var vsbm:ScrollBarModel = new ScrollBarModel();
			vsbm.maximum = 100;
			vsbm.minimum = 0;
			vsbm.pageSize = 10;
			vsbm.pageStepSize = 10;
			vsbm.snapInterval = 1;
			vsbm.stepSize = 1;
			vsbm.value = 0;
			vsb.model = vsbm;
			vsb.width = 16;
            IParent(strand).addElement(vsb);

			vsb.addEventListener("scroll", scrollHandler);

			return vsb;
		}

		private function textScrollHandler(event:Event):void
		{
			var visibleLines:int = textField.bottomScrollV - textField.scrollV + 1;
			var scrollableLines:int = textField.numLines - visibleLines + 1;
			var vsbm:ScrollBarModel = ScrollBarModel(vScrollBar.model);
			vsbm.minimum = 0;
			vsbm.maximum = textField.numLines+1;
			vsbm.value = textField.scrollV;
			vsbm.pageSize = visibleLines;
			vsbm.pageStepSize = visibleLines;
		}

		private function sizeChangedHandler(event:Event):void
		{
			var ww:Number = DisplayObject(strand).width - DisplayObject(vScrollBar).width;
			if( !isNaN(ww) && ww > 0 ) {
				textField.width = ww;
				_border.width = ww;
			}

			var hh:Number = DisplayObject(strand).height;
			if( !isNaN(hh) && hh > 0 ) {
				textField.height = hh;
				_border.height = hh;
			}

			var sb:DisplayObject = DisplayObject(vScrollBar);
			sb.y = 0;
			sb.x = textField.width - 1;
			sb.height = textField.height;
		}

		private function scrollHandler(event:Event):void
		{
			var vpos:Number = IScrollBarModel(vScrollBar.model).value;
			textField.scrollV = vpos;
		}

        /**
         *  @copy org.apache.flex.core.UIBase#beads
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public var beads:Array;

		private var _beads:Vector.<IBead>;

        /**
         *  @copy org.apache.flex.core.UIBase#addBead()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function addBead(bead:IBead):void
		{
			if (!_beads)
				_beads = new Vector.<IBead>;
			_beads.push(bead);
			bead.strand = this;
		}

        /**
         *  @copy org.apache.flex.core.UIBase#getBeadByType()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function getBeadByType(classOrInterface:Class):IBead
		{
			for each (var bead:IBead in _beads)
			{
				if (bead is classOrInterface)
					return bead;
			}
			return null;
		}

        /**
         *  @copy org.apache.flex.core.UIBase#removeBead()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function removeBead(value:IBead):IBead
		{
			var n:int = _beads.length;
			for (var i:int = 0; i < n; i++)
			{
				var bead:IBead = _beads[i];
				if (bead == value)
				{
					_beads.splice(i, 1);
					return bead;
				}
			}
			return null;
		}
	}
}

////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You 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 org.apache.flex.html.beads
{
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.text.TextFieldType;

	import org.apache.flex.core.IBead;
    import org.apache.flex.core.IBeadModel;
	import org.apache.flex.core.IScrollBarModel;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.core.IParent;
    import org.apache.flex.core.ValuesManager;
	import org.apache.flex.html.beads.models.ScrollBarModel;
	import org.apache.flex.html.supportClasses.Border;
	import org.apache.flex.html.supportClasses.ScrollBar;

    /**
     *  The TextAreaView class is the default view for
     *  the org.apache.flex.html.TextArea class.
     *  It implements the classic desktop-like TextArea with
     *  a border and scrollbars.  It does not support right-to-left text.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
	public class TextAreaView extends TextFieldViewBase implements IStrand
	{
        /**
         *  Constructor.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function TextAreaView()
		{
			super();

			textField.selectable = true;
			textField.type = TextFieldType.INPUT;
			textField.mouseEnabled = true;
			textField.multiline = true;
			textField.wordWrap = true;
		}

		private var _border:Border;

        /**
         *  The border.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function get border():Border
		{
			return _border;
		}

		private var _vScrollBar:ScrollBar;

        /**
         *  The vertical ScrollBar.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function get vScrollBar():ScrollBar
		{
			if (!_vScrollBar)
				_vScrollBar = createScrollBar();
			return _vScrollBar;
		}

        /**
         *  @private
         */
		override public function set strand(value:IStrand):void
		{
			super.strand = value;

			// add a border to this
			_border = new Border();
			_border.model = new (ValuesManager.valuesImpl.getValue(value, "iBorderModel")) as IBeadModel;
			_border.addBead(new (ValuesManager.valuesImpl.getValue(value, "iBorderBead")) as IBead);
            IParent(host).addElement(border);

			var vb:ScrollBar = vScrollBar;

			// Default size
			var ww:Number = DisplayObject(host).width;
			if( isNaN(ww) || ww == 0 ) DisplayObject(host).width = 100;
			var hh:Number = DisplayObject(host).height;
			if( isNaN(hh) || hh == 0 ) DisplayObject(host).height = 42;

			// for input, listen for changes to the _textField and update
			// the model
			textField.addEventListener(Event.SCROLL, textScrollHandler);

			IEventDispatcher(host).addEventListener("widthChanged", sizeChangedHandler);
			IEventDispatcher(host).addEventListener("heightChanged", sizeChangedHandler);
			sizeChangedHandler(null);
		}

		private function createScrollBar():ScrollBar
		{
			var vsb:ScrollBar;
			vsb = new ScrollBar();
			var vsbm:ScrollBarModel = new ScrollBarModel();
			vsbm.maximum = 100;
			vsbm.minimum = 0;
			vsbm.pageSize = 10;
			vsbm.pageStepSize = 10;
			vsbm.snapInterval = 1;
			vsbm.stepSize = 1;
			vsbm.value = 0;
			vsb.model = vsbm;
			vsb.width = 16;
            IParent(host).addElement(vsb);

			vsb.addEventListener("scroll", scrollHandler);

			return vsb;
		}

		private function textScrollHandler(event:Event):void
		{
			var visibleLines:int = textField.bottomScrollV - textField.scrollV + 1;
			var scrollableLines:int = textField.numLines - visibleLines + 1;
			var vsbm:ScrollBarModel = ScrollBarModel(vScrollBar.model);
			vsbm.minimum = 0;
			vsbm.maximum = textField.numLines+1;
			vsbm.value = textField.scrollV;
			vsbm.pageSize = visibleLines;
			vsbm.pageStepSize = visibleLines;
		}

		private function sizeChangedHandler(event:Event):void
		{
			var ww:Number = DisplayObject(host).width - DisplayObject(vScrollBar).width;
			if( !isNaN(ww) && ww > 0 ) {
				textField.width = ww;
				_border.width = ww;
			}

			var hh:Number = DisplayObject(host).height;
			if( !isNaN(hh) && hh > 0 ) {
				textField.height = hh;
				_border.height = hh;
			}

			var sb:DisplayObject = DisplayObject(vScrollBar);
			sb.y = 0;
			sb.x = textField.width - 1;
			sb.height = textField.height;
		}

		private function scrollHandler(event:Event):void
		{
			var vpos:Number = IScrollBarModel(vScrollBar.model).value;
			textField.scrollV = vpos;
		}

        /**
         *  @copy org.apache.flex.core.UIBase#beads
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public var beads:Array;

		private var _beads:Vector.<IBead>;

        /**
         *  @copy org.apache.flex.core.UIBase#addBead()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function addBead(bead:IBead):void
		{
			if (!_beads)
				_beads = new Vector.<IBead>;
			_beads.push(bead);
			bead.strand = this;
		}

        /**
         *  @copy org.apache.flex.core.UIBase#getBeadByType()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function getBeadByType(classOrInterface:Class):IBead
		{
			for each (var bead:IBead in _beads)
			{
				if (bead is classOrInterface)
					return bead;
			}
			return null;
		}

        /**
         *  @copy org.apache.flex.core.UIBase#removeBead()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function removeBead(value:IBead):IBead
		{
			var n:int = _beads.length;
			for (var i:int = 0; i < n; i++)
			{
				var bead:IBead = _beads[i];
				if (bead == value)
				{
					_beads.splice(i, 1);
					return bead;
				}
			}
			return null;
		}
	}
}

use host

use host


package dolly {
public class ClassWithSomeCopyableFields {

	public static var staticProperty1:String;

	[Cloneable]
	public static var staticProperty2:String;

	[Cloneable]
	public static var staticProperty3:String;

	private var _writableField:String;
	private var _readOnlyField:String = "read-only field value";

	public var property1:String;

	[Cloneable]
	public var property2:String;

	[Cloneable]
	public var property3:String;

	public function ClassWithSomeCopyableFields() {
	}

	[Cloneable]
	public function get writableField():String {
		return _writableField;
	}

	public function set writableField(value:String):void {
		_writableField = value;
	}

	[Cloneable]
	public function get readOnlyField():String {
		return _readOnlyField;
	}
}
}

package dolly {
public class ClassWithSomeCopyableFields {

	public static var staticProperty1:String;

	[Copyable]
	public static var staticProperty2:String;

	[Copyable]
	public static var staticProperty3:String;

	private var _writableField:String;
	private var _readOnlyField:String = "read-only field value";

	public var property1:String;

	[Copyable]
	public var property2:String;

	[Copyable]
	public var property3:String;

	public function ClassWithSomeCopyableFields() {
	}

	[Copyable]
	public function get writableField():String {
		return _writableField;
	}

	public function set writableField(value:String):void {
		_writableField = value;
	}

	[Copyable]
	public function get readOnlyField():String {
		return _readOnlyField;
	}
}
}

Change metadata tags to Copyable in test data class.