////////////////////////////////////////////////////////////////////////////////
//
//  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 {

import flash.display.DisplayObject;
import flash.net.*;
import flash.utils.*;
import flash.events.Event;

[Mixin]
/**
 *  A "marker" class that causes test scripts to write out
 *  bitmaps to the urls instead of reading and comparing
 *  so that baselines/reference-points can be created for
 *  future comparing.
 */
public class SendResultsToRunner
{

	/**
	 *  Mixin callback that gets everything ready to go.
	 *  The UnitTester waits for an event before starting
	 */
	public static function init(root:DisplayObject):void
	{
		TestOutput.getInstance().addEventListener ("result", urlSender);
	}

	public static var midURL:String  = "";

	public static var regExp5:RegExp = /%3D/g;

	public static var u:URLLoader;

	/**
  	 * the way out for the result data
	 */
	public static function urlSender (event:Event):void
	{

		var s:String = (event as MustellaLogEvent).msg;

		var baseURL:String  = "http://localhost:" + UnitTester.runnerPort;

		/// trace it anyway
		trace (s);

		/// Notice what we've got. Send along to Runner if relevant
		var loc:uint;
		var final:String = "";

		var skip:Boolean = false;
		var noSend:Boolean = false;

		if ( (loc =  s.indexOf ("RESULT: ")) != -1) {
			s = s.substr (loc + 8);
			midURL = "/testCaseResult";
		} else if ( (loc =  s.indexOf ("ScriptComplete:")) != -1) {
			midURL = "/ScriptComplete";
			final = "?" + UnitTester.excludedCount;
			skip = true;
		} else if ( (loc =  s.indexOf ("LengthOfTestcases:")) != -1) {
			midURL = "/testCaseLength?";
			final = s.substring (loc+ "LengthOfTestcases:".length+1);
			skip = true;
		} else if ( (loc = s.indexOf ("TestCase Start:")) != -1) {
			/// not relevant
			s = s.substr (loc + 15);
			s = s.replace (" ", "");
			midURL = "/testCaseStart?" + s ;
			skip = true;
		} else  {
			noSend = true;
		}

		if (!skip) {

			/// this should be something like |, because it is confusing this way
			/// putting it on, taking it off
			s=s.replace (" msg=", "|msg=");
			s=s.replace (" result=", "|result=");
			s=s.replace (" phase=", "|phase=");
			s=s.replace (" id=", "|id=");
			s=s.replace (" elapsed=", "|elapsed=");
			s=s.replace (" started=", "|started=");
			s=s.replace (" extraInfo=", "|extraInfo=");

			var hdrs:Array = s.split ("|");

			var i:uint;
			// rebuild url encoded
			for (i=0;i<hdrs.length;i++) {

				if (final =="")
					final="?" + escape(hdrs[i]);
				else
					final+="&" + escape(hdrs[i]);
			}

			final = final.replace (regExp5, "=");

		}

		/**
		 * Probably we don't need to use URLLoader, since we don't care
		 * about the response, but for now, for debugging, using it
		 */
		if (!noSend) {
			trace ("sending: " + baseURL + midURL + final + " at: " + new Date());
			// var u:String= baseURL + midURL + final;
			if (u == null)
			{
				u = new URLLoader();
				u.addEventListener("complete", completeHandler);
				u.addEventListener("complete", httpEvents);
				u.addEventListener("ioError", httpEvents);
				u.addEventListener("open", httpEvents);
				u.addEventListener("progress", httpEvents);
				u.addEventListener("httpStatus", httpEvents);
				u.addEventListener("securityError", httpEvents);
			}
			UnitTester.pendingOutput++;
			u.load (new URLRequest (baseURL + midURL + final));

			/*
			var sock:Socket = new Socket ("localhost",  UnitTester.runnerPort);
			sock.writeUTFBytes(u);
			sock.flush();
			sock.flush();
			*/

		}

	}

	public static function completeHandler (e:Event):void  {
		UnitTester.pendingOutput--;
	}

	public static function httpEvents (e:Event):void  {
		trace (e);
	}

}
}

////////////////////////////////////////////////////////////////////////////////
//
//  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 {

import flash.display.DisplayObject;
import flash.net.*;
import flash.utils.*;
import flash.events.Event;

[Mixin]
/**
 *  A "marker" class that causes test scripts to write out
 *  bitmaps to the urls instead of reading and comparing
 *  so that baselines/reference-points can be created for
 *  future comparing.
 */
public class SendResultsToRunner
{

	/**
	 *  Mixin callback that gets everything ready to go.
	 *  The UnitTester waits for an event before starting
	 */
	public static function init(root:DisplayObject):void
	{
		TestOutput.getInstance().addEventListener ("result", urlSender);
	}

	public static var midURL:String  = "";

	public static var regExp5:RegExp = /%3D/g;

	/**
  	 * the way out for the result data
	 */
	public static function urlSender (event:Event):void
	{

		var s:String = (event as MustellaLogEvent).msg;

		var baseURL:String  = "http://localhost:" + UnitTester.runnerPort;

		/// trace it anyway
		trace (s);

		/// Notice what we've got. Send along to Runner if relevant
		var loc:uint;
		var final:String = "";

		var skip:Boolean = false;
		var noSend:Boolean = false;

		if ( (loc =  s.indexOf ("RESULT: ")) != -1) {
			s = s.substr (loc + 8);
			midURL = "/testCaseResult";
		} else if ( (loc =  s.indexOf ("ScriptComplete:")) != -1) {
			midURL = "/ScriptComplete";
			final = "?" + UnitTester.excludedCount;
			skip = true;
		} else if ( (loc =  s.indexOf ("LengthOfTestcases:")) != -1) {
			midURL = "/testCaseLength?";
			final = s.substring (loc+ "LengthOfTestcases:".length+1);
			skip = true;
		} else if ( (loc = s.indexOf ("TestCase Start:")) != -1) {
			/// not relevant
			s = s.substr (loc + 15);
			s = s.replace (" ", "");
			midURL = "/testCaseStart?" + s ;
			skip = true;
		} else  {
			noSend = true;
		}

		if (!skip) {

			/// this should be something like |, because it is confusing this way
			/// putting it on, taking it off
			s=s.replace (" msg=", "|msg=");
			s=s.replace (" result=", "|result=");
			s=s.replace (" phase=", "|phase=");
			s=s.replace (" id=", "|id=");
			s=s.replace (" elapsed=", "|elapsed=");
			s=s.replace (" started=", "|started=");
			s=s.replace (" extraInfo=", "|extraInfo=");

			var hdrs:Array = s.split ("|");

			var i:uint;
			// rebuild url encoded
			for (i=0;i<hdrs.length;i++) {

				if (final =="")
					final="?" + escape(hdrs[i]);
				else
					final+="&" + escape(hdrs[i]);
			}

			final = final.replace (regExp5, "=");

		}

		/**
		 * Probably we don't need to use URLLoader, since we don't care
		 * about the response, but for now, for debugging, using it
		 */
		if (!noSend) {
			trace ("sending: " + baseURL + midURL + final + " at: " + new Date());
			// var u:String= baseURL + midURL + final;
			var u:URLLoader = new URLLoader (new URLRequest (baseURL + midURL + final));

			/*
			var sock:Socket = new Socket ("localhost",  UnitTester.runnerPort);
			sock.writeUTFBytes(u);
			sock.flush();
			sock.flush();
			*/

			u.addEventListener("complete", completeHandler);
			u.addEventListener("complete", httpEvents);
			u.addEventListener("ioError", httpEvents);
			u.addEventListener("open", httpEvents);
			u.addEventListener("progress", httpEvents);
			u.addEventListener("httpStatus", httpEvents);
			u.addEventListener("securityError", httpEvents);
			u.load (new URLRequest (baseURL + midURL + final));
			UnitTester.pendingOutput++;
			dict[u] = baseURL + midURL + final;
		}

	}

	public static var dict:Dictionary = new Dictionary();

	public static function completeHandler (e:Event):void  {
		UnitTester.pendingOutput--;
		//trace("received complete for", dict[e.target]);
		delete dict[e.target];
	}

	public static function httpEvents (e:Event):void  {
		trace (e);
	}

}
}

Revert last attempt

Revert last attempt

git-svn-id: 7d913817b0a978d84de757191e4bce372605a781@1395325 13f79535-47bb-0310-9956-ffa450edef68


package aerys.minko.scene.node.texture
{
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.geom.Matrix;

	/**
	 * The BitmapTexture class enables the use of BitmapData objects as
	 * textures.
	 *
	 * @author Jean-Marc Le Roux
	 *
	 */
	public class BitmapTexture extends Texture
	{
		private static const TMP_MATRIX : Matrix = new Matrix();

		private var _data		: BitmapData	= null;
		private var _mipmapping	: Boolean		= false;

		protected function get bitmapData()	: BitmapData
		{
			return _data;
		}

		public function updateFromBitmapData(value 		: BitmapData,
											 smooth		: Boolean	= true,
											 downSample	: Boolean	= false) : void
		{
			var bitmapWidth		: uint = value.width;
			var bitmapHeight	: uint = value.height;
			var w				: int;
			var h				: int;

			if (downSample)
			{
				w = 1 << Math.floor(Math.log(bitmapWidth) * Math.LOG2E);
				h = 1 << Math.floor(Math.log(bitmapHeight) * Math.LOG2E);
			}
			else
			{
				w = 1 << Math.ceil(Math.log(bitmapWidth) * Math.LOG2E);
				h = 1 << Math.ceil(Math.log(bitmapHeight) * Math.LOG2E);
			}

			if (!_data || _data.width != w || _data.height != h)
			{
				if (_data)
				{
					_data.dispose();
					_data = null;
				}

				_data = new BitmapData(w, h, value.transparent, 0);
			}

			if (w != bitmapWidth || h != bitmapHeight)
			{
				TMP_MATRIX.identity();
				TMP_MATRIX.scale(w / bitmapWidth, h / bitmapHeight);
				_data.draw(value, TMP_MATRIX, null, null, null, smooth);
			}
			else
			{
				_data.draw(value, null, null, null, null, smooth);
			}

			resource.setContentFromBitmapData(_data, _mipmapping);
			_data = null;
		}

		public function BitmapTexture(bitmapData 	: BitmapData 	= null,
									  mipmapping	: Boolean		= true,
									  styleProperty	: int			= -1)
		{
			super(null, styleProperty);

			_mipmapping	= mipmapping;

			if (bitmapData)
				updateFromBitmapData(bitmapData);
		}

		public static function fromDisplayObject(source : DisplayObject,
												 size 	: int 		= 0,
												 smooth : Boolean 	= false) : BitmapTexture
		{
			var bmp : BitmapData = new BitmapData(size || source.width,
												  size || source.height,
												  true,
												  0);

			if (size)
			{
				TMP_MATRIX.identity();
				TMP_MATRIX.scale(source.width / size, source.height / size);
			}

			bmp.draw(source, TMP_MATRIX, null, null, null, smooth);

			return new BitmapTexture(bmp);
		}
	}
}

package aerys.minko.scene.node.texture
{
	import aerys.minko.ns.minko;

	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.geom.Matrix;

	/**
	 * The BitmapTexture class enables the use of BitmapData objects as
	 * textures.
	 *
	 * @author Jean-Marc Le Roux
	 *
	 */

	use namespace minko;

	public class BitmapTexture extends Texture
	{
		private static const TMP_MATRIX : Matrix = new Matrix();

		minko var _data		: BitmapData	= null;
		private var _mipmapping	: Boolean		= false;

		protected function get bitmapData()	: BitmapData
		{
			return _data;
		}

		public function get mipmapping():Boolean
		{
			return _mipmapping;
		}

		public function updateFromBitmapData(value 		: BitmapData,
											 smooth		: Boolean	= true,
											 downSample	: Boolean	= false) : void
		{
			var bitmapWidth		: uint = value.width;
			var bitmapHeight	: uint = value.height;
			var w				: int;
			var h				: int;

			if (downSample)
			{
				w = 1 << Math.floor(Math.log(bitmapWidth) * Math.LOG2E);
				h = 1 << Math.floor(Math.log(bitmapHeight) * Math.LOG2E);
			}
			else
			{
				w = 1 << Math.ceil(Math.log(bitmapWidth) * Math.LOG2E);
				h = 1 << Math.ceil(Math.log(bitmapHeight) * Math.LOG2E);
			}

			if (!_data || _data.width != w || _data.height != h)
			{
				if (_data)
				{
					_data.dispose();
					_data = null;
				}

				_data = new BitmapData(w, h, value.transparent, 0);
			}

			if (w != bitmapWidth || h != bitmapHeight)
			{
				TMP_MATRIX.identity();
				TMP_MATRIX.scale(w / bitmapWidth, h / bitmapHeight);
				_data.draw(value, TMP_MATRIX, null, null, null, smooth);
			}
			else
			{
				_data.draw(value, null, null, null, null, smooth);
			}

			resource.setContentFromBitmapData(_data, _mipmapping);
			_data = null;
		}

		public function BitmapTexture(bitmapData 	: BitmapData 	= null,
									  mipmapping	: Boolean		= true,
									  styleProperty	: int			= -1)
		{
			super(null, styleProperty);

			_mipmapping	= mipmapping;

			if (bitmapData)
				updateFromBitmapData(bitmapData);
		}

		public static function fromDisplayObject(source : DisplayObject,
												 size 	: int 		= 0,
												 smooth : Boolean 	= false) : BitmapTexture
		{
			var bmp : BitmapData = new BitmapData(size || source.width,
												  size || source.height,
												  true,
												  0);

			if (size)
			{
				TMP_MATRIX.identity();
				TMP_MATRIX.scale(source.width / size, source.height / size);
			}

			bmp.draw(source, TMP_MATRIX, null, null, null, smooth);

			return new BitmapTexture(bmp);
		}

	}
}

Add namespace minko around parameter data

M To have access to the bitmapData value (use for BitmapTextureEditorNode)


package aerys.minko.render.shader.compiler
{
	import aerys.minko.ns.minko_math;
	import aerys.minko.type.math.Matrix4x4;
	import aerys.minko.type.math.Vector4;

	import flash.geom.Point;
	import flash.geom.Vector3D;
	import flash.utils.getQualifiedClassName;

	/**
	 * The Serializer class provides a set of static methods to serialize
	 * CPU values into Vector.<Number> than can be used as shader constants.
	 *
	 * @author Jean-Marc Le Roux
	 *
	 */
	public class Serializer
	{
		public function serializeKnownLength(data	: Object,
											 target	: Vector.<Number>,
											 offset	: uint,
											 size	: uint) : void
		{
			if (data is Number)
			{
				var intData : Number = Number(data);

				if (size == 1)
				{
					target[offset] = intData;
				}
				else if (size == 2)
				{
					target[offset] = ((intData & 0xFFFF0000) >>> 16) / Number(0xffff);
					target[int(offset + 2)] = (intData & 0x0000FFFF) / Number(0xffff);
				}
				else if (size == 3)
				{
					target[offset] = ((intData & 0xFF0000) >>> 16) / 255.;
					target[int(offset + 1)] = ((intData & 0x00FF00) >>> 8) / 255.;
					target[int(offset + 2)] = (intData & 0x0000FF) / 255.;
				}
				else if (size == 4)
				{
					target[offset] = ((intData & 0xFF000000) >>> 24) / 255.;
					target[int(offset + 1)] = ((intData & 0x00FF0000) >>> 16) / 255.;
					target[int(offset + 2)] = ((intData & 0x0000FF00) >>> 8) / 255.;
					target[int(offset + 3)] = ((intData & 0x000000FF)) / 255.;
				}
			}
			else if (data is Vector4)
			{
				var vectorData : Vector3D = Vector4(data).minko_math::_vector;

				target[offset] = vectorData.x;
				size >= 2 && (target[int(offset + 1)] = vectorData.y);
				size >= 3 && (target[int(offset + 2)] = vectorData.z);
				size >= 4 && (target[int(offset + 3)] = vectorData.w);
			}
			else if (data is Matrix4x4)
			{
				Matrix4x4(data).getRawData(target, offset, true);
			}
			else if (data is Vector.<Number>)
			{
				var vectorNumberData		: Vector.<Number>	= Vector.<Number>(data);
				var vectorNumberDatalength	: uint				= vectorNumberData.length;

				for (var k : int = 0; k < size && k < vectorNumberDatalength; ++k)
					target[offset + k] = vectorNumberData[k];
			}
			else if (data is Vector.<Vector4>)
			{
				var vectorVectorData		: Vector.<Vector4>	= Vector.<Vector4>(data);
				var vectorVectorDataLength	: uint				= vectorVectorData.length;

				for (var j : uint = 0; j < vectorVectorDataLength; ++j)
				{
					vectorData = vectorVectorData[j].minko_math::_vector;

					target[offset + 4 * j] = vectorData.x;
					target[int(offset + 4 * j + 1)] = vectorData.y;
					target[int(offset + 4 * j + 2)] = vectorData.z;
					target[int(offset + 4 * j + 3)] = vectorData.w;
				}
			}
			else if (data is Vector.<Matrix4x4>)
			{
				var matrixVectorData		: Vector.<Matrix4x4>	= Vector.<Matrix4x4>(data);
				var matrixVectorDataLength	: uint					= matrixVectorData.length;

				for (var i : uint = 0; i < matrixVectorDataLength; ++i)
					matrixVectorData[i].getRawData(target, offset + i * 16, true);
			}
			else if (data == null)
			{
				throw new Error('You cannot serialize a null value.');
			}
			else
			{
				throw new Error('Unsupported type:' + getQualifiedClassName(data);
			}
		}

		public function serializeUnknownLength(data		: Object,
											   target	: Vector.<Number>,
											   offset	: uint) : void
		{
			if (data is Number)
			{
				target[offset] = Number(data);
			}
			else if (data is Point)
			{
				var pointData : Point = Point(data);

				target[offset]			= pointData.x;
				target[int(offset + 1)]	= pointData.y;
			}
			else if (data is Vector4)
			{
				var vectorData : Vector3D = Vector4(data).minko_math::_vector;

				target[offset]			= vectorData.x;
				target[int(offset + 1)]	= vectorData.y;
				target[int(offset + 2)]	= vectorData.z;
				target[int(offset + 3)]	= vectorData.w;
			}
			else if (data is Matrix4x4)
			{
				Matrix4x4(data).getRawData(target, offset, true);
			}
			else if (data is Array || data is Vector.<Number> || data is Vector.<Vector4> || data is Vector.<Matrix4x4>)
			{
				for each (var datum : Object in data)
				{
					serializeUnknownLength(datum, target, offset);
					offset = target.length;
				}
			}
			else if (data == null)
			{
				throw new Error('You cannot serialize a null value.');
			}
			else
			{
				throw new Error('Unsupported type:' + getQualifiedClassName(data));
			}
		}
	}
}

package aerys.minko.render.shader.compiler
{
	import aerys.minko.ns.minko_math;
	import aerys.minko.type.math.Matrix4x4;
	import aerys.minko.type.math.Vector4;

	import flash.geom.Point;
	import flash.geom.Vector3D;
	import flash.utils.getQualifiedClassName;

	/**
	 * The Serializer class provides a set of static methods to serialize
	 * CPU values into Vector.<Number> than can be used as shader constants.
	 *
	 * @author Jean-Marc Le Roux
	 *
	 */
	public class Serializer
	{
		public function serializeKnownLength(data	: Object,
											 target	: Vector.<Number>,
											 offset	: uint,
											 size	: uint) : void
		{
			if (data is Number)
			{
				var intData : Number = Number(data);

				if (size == 1)
				{
					target[offset] = intData;
				}
				else if (size == 2)
				{
					target[offset] = ((intData & 0xFFFF0000) >>> 16) / Number(0xffff);
					target[int(offset + 2)] = (intData & 0x0000FFFF) / Number(0xffff);
				}
				else if (size == 3)
				{
					target[offset] = ((intData & 0xFF0000) >>> 16) / 255.;
					target[int(offset + 1)] = ((intData & 0x00FF00) >>> 8) / 255.;
					target[int(offset + 2)] = (intData & 0x0000FF) / 255.;
				}
				else if (size == 4)
				{
					target[offset] = ((intData & 0xFF000000) >>> 24) / 255.;
					target[int(offset + 1)] = ((intData & 0x00FF0000) >>> 16) / 255.;
					target[int(offset + 2)] = ((intData & 0x0000FF00) >>> 8) / 255.;
					target[int(offset + 3)] = ((intData & 0x000000FF)) / 255.;
				}
			}
			else if (data is Vector4)
			{
				var vectorData : Vector3D = Vector4(data).minko_math::_vector;

				target[offset] = vectorData.x;
				size >= 2 && (target[int(offset + 1)] = vectorData.y);
				size >= 3 && (target[int(offset + 2)] = vectorData.z);
				size >= 4 && (target[int(offset + 3)] = vectorData.w);
			}
			else if (data is Matrix4x4)
			{
				Matrix4x4(data).getRawData(target, offset, true);
			}
			else if (data is Vector.<Number>)
			{
				var vectorNumberData		: Vector.<Number>	= Vector.<Number>(data);
				var vectorNumberDatalength	: uint				= vectorNumberData.length;

				for (var k : int = 0; k < size && k < vectorNumberDatalength; ++k)
					target[offset + k] = vectorNumberData[k];
			}
			else if (data is Vector.<Vector4>)
			{
				var vectorVectorData		: Vector.<Vector4>	= Vector.<Vector4>(data);
				var vectorVectorDataLength	: uint				= vectorVectorData.length;

				for (var j : uint = 0; j < vectorVectorDataLength; ++j)
				{
					vectorData = vectorVectorData[j].minko_math::_vector;

					target[offset + 4 * j] = vectorData.x;
					target[int(offset + 4 * j + 1)] = vectorData.y;
					target[int(offset + 4 * j + 2)] = vectorData.z;
					target[int(offset + 4 * j + 3)] = vectorData.w;
				}
			}
			else if (data is Vector.<Matrix4x4>)
			{
				var matrixVectorData		: Vector.<Matrix4x4>	= Vector.<Matrix4x4>(data);
				var matrixVectorDataLength	: uint					= matrixVectorData.length;

				for (var i : uint = 0; i < matrixVectorDataLength; ++i)
					matrixVectorData[i].getRawData(target, offset + i * 16, true);
			}
			else if (data == null)
			{
				throw new Error('You cannot serialize a null value.');
			}
			else
			{
				throw new Error('Unsupported type:' + getQualifiedClassName(data));
			}
		}

		public function serializeUnknownLength(data		: Object,
											   target	: Vector.<Number>,
											   offset	: uint) : void
		{
			if (data is Number)
			{
				target[offset] = Number(data);
			}
			else if (data is Point)
			{
				var pointData : Point = Point(data);

				target[offset]			= pointData.x;
				target[int(offset + 1)]	= pointData.y;
			}
			else if (data is Vector4)
			{
				var vectorData : Vector3D = Vector4(data).minko_math::_vector;

				target[offset]			= vectorData.x;
				target[int(offset + 1)]	= vectorData.y;
				target[int(offset + 2)]	= vectorData.z;
				target[int(offset + 3)]	= vectorData.w;
			}
			else if (data is Matrix4x4)
			{
				Matrix4x4(data).getRawData(target, offset, true);
			}
			else if (data is Array || data is Vector.<Number> || data is Vector.<Vector4> || data is Vector.<Matrix4x4>)
			{
				for each (var datum : Object in data)
				{
					serializeUnknownLength(datum, target, offset);
					offset = target.length;
				}
			}
			else if (data == null)
			{
				throw new Error('You cannot serialize a null value.');
			}
			else
			{
				throw new Error('Unsupported type:' + getQualifiedClassName(data));
			}
		}
	}
}

fix missing )

fix missing )


package aerys.minko.render.material.phong
{
	import aerys.minko.render.DataBindingsProxy;
	import aerys.minko.render.Effect;
	import aerys.minko.render.RenderTarget;
	import aerys.minko.render.resource.texture.CubeTextureResource;
	import aerys.minko.render.resource.texture.ITextureResource;
	import aerys.minko.render.resource.texture.TextureResource;
	import aerys.minko.render.shader.Shader;
	import aerys.minko.scene.data.LightDataProvider;
	import aerys.minko.scene.node.light.AmbientLight;
	import aerys.minko.scene.node.light.DirectionalLight;
	import aerys.minko.scene.node.light.PointLight;
	import aerys.minko.type.enum.ShadowMappingQuality;
	import aerys.minko.type.enum.ShadowMappingType;

	public class PhongEffect extends Effect
	{
        private var _singlePassShader   : Shader;
        private var _baseShader         : Shader;

		public function PhongEffect(singlePassShader    : Shader    = null,
                                    baseShader          : Shader    = null)
		{
            super();

            _singlePassShader = singlePassShader || new PhongSinglePassShader(null, 0);
            _baseShader = baseShader || new PhongBaseShader(null, .5);
		}

        override protected function initializePasses(sceneBindings	: DataBindingsProxy,
                                                     meshBindings	: DataBindingsProxy) : Vector.<Shader>
        {
            var passes : Vector.<Shader>    = super.initializePasses(sceneBindings, meshBindings);

            for (var lightId : uint = 0;
                lightPropertyExists(sceneBindings, lightId, 'enabled');
                ++lightId)
            {
                if (lightPropertyExists(sceneBindings, lightId, 'shadowCastingType'))
                {
                    var lightType			: uint	= getLightProperty(sceneBindings, lightId, 'type');
                    var shadowMappingType 	: uint	= getLightProperty(
                        sceneBindings, lightId, 'shadowCastingType'
                    );

                    switch (shadowMappingType)
                    {
                        case ShadowMappingType.PCF:
                            if (lightType == PointLight.LIGHT_TYPE)
                                pushCubeShadowMappingPass(sceneBindings, lightId, passes);
                            else
                                pushPCFShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.DUAL_PARABOLOID:
                            pushDualParaboloidShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.VARIANCE:
                            pushVarianceShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.EXPONENTIAL:
                            pushExponentialShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                    }
                }
            }

            passes.push(new PhongSinglePassShader(null, 0));

            return passes;
        }

        override protected function initializeFallbackPasses(sceneBindings  : DataBindingsProxy,
                                                             meshBindings   : DataBindingsProxy) : Vector.<Shader>
        {
            var passes              : Vector.<Shader>   = super.initializeFallbackPasses(sceneBindings, meshBindings);
            var discardDirectional  : Boolean           = true;

			for (var lightId : uint = 0;
                lightPropertyExists(sceneBindings, lightId, 'enabled');
                ++lightId)
			{
                var lightType   : uint	= getLightProperty(sceneBindings, lightId, 'type');

                if (lightType != AmbientLight.LIGHT_TYPE
                    && getLightProperty(sceneBindings, lightId, 'enabled'))
                {
                    if (lightType == DirectionalLight.LIGHT_TYPE && discardDirectional)
                        discardDirectional = false;
                    else
                        passes.push(new PhongAdditionalShader(null, 0, lightId));
                }

				if (lightPropertyExists(sceneBindings, lightId, 'shadowCastingType'))
				{
					var shadowMappingType 	: uint	= getLightProperty(
						sceneBindings, lightId, 'shadowCastingType'
					);

					switch (shadowMappingType)
					{
						case ShadowMappingType.PCF:
							if (lightType == PointLight.LIGHT_TYPE)
								pushCubeShadowMappingPass(sceneBindings, lightId, passes);
							else
								pushPCFShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.DUAL_PARABOLOID:
							pushDualParaboloidShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.VARIANCE:
							pushVarianceShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.EXPONENTIAL:
							pushExponentialShadowMappingPass(sceneBindings, lightId, passes);
							break ;
					}
				}
			}

            passes.push(new PhongBaseShader(null, .5));

            return passes;
		}

		private function pushPCFShadowMappingPass(sceneBindings	: DataBindingsProxy,
													 lightId 		: uint,
													 passes 		: Vector.<Shader>) : void
		{
			var textureResource : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMap'
			);
			var renderTarget	: RenderTarget		= new RenderTarget(
				textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
			);

			passes.push(new PCFShadowMapShader(lightId, lightId + 1, renderTarget));
		}

		private function pushDualParaboloidShadowMappingPass(sceneBindings	: DataBindingsProxy,
															 lightId 		: uint,
															 passes 		: Vector.<Shader>) : void
		{
			var frontTextureResource : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMapFront'
			);
			var backTextureResource	 : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMapBack'
			);
			var size				 : uint				= frontTextureResource.width;
			var frontRenderTarget	 : RenderTarget		= new RenderTarget(
				size, size, frontTextureResource, 0, 0xffffffff
			);
			var backRenderTarget	 : RenderTarget		= new RenderTarget(
				size, size, backTextureResource, 0, 0xffffffff
			);

			passes.push(
				new ParaboloidShadowMapShader(lightId, true, lightId + 0.5, frontRenderTarget),
				new ParaboloidShadowMapShader(lightId, false, lightId + 1, backRenderTarget)
			);
		}

		private function pushCubeShadowMappingPass(sceneBindings	: DataBindingsProxy,
												   lightId 			: uint,
												   passes 			: Vector.<Shader>) : void
		{
			var cubeTexture	: CubeTextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMap'
			);
			var textureSize	: uint					= cubeTexture.size;

			for (var i : uint = 0; i < 6; ++i)
				passes.push(new PCFShadowMapShader(
					lightId,
					lightId + .1 * i,
					new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff),
					i
				));
		}

		private function pushVarianceShadowMappingPass(sceneBindings	: DataBindingsProxy,
													   lightId 			: uint,
													   passes 			: Vector.<Shader>) : void
		{
			var lightType	: uint	= getLightProperty(
				sceneBindings, lightId, 'type'
			);

			if (lightType != PointLight.LIGHT_TYPE)
			{
				var textureResource : ITextureResource	= null;
				var renderTarget	: RenderTarget		= null;

				if (hasShadowBlurPass(sceneBindings, lightId))
					textureResource	= getLightProperty(sceneBindings, lightId, 'rawShadowMap');
				else
					textureResource	= getLightProperty(sceneBindings, lightId, 'shadowMap');

				renderTarget		= new RenderTarget(
					textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
				);

				passes.push(new VarianceShadowMapShader(lightId, 4, lightId + 1, renderTarget));
			}
			else
			{
				var cubeTexture		: CubeTextureResource	= getLightProperty(
					sceneBindings, lightId, 'shadowMap'
				);
				var textureSize		: uint					= cubeTexture.size;

				for (var i : uint = 0; i < 6; ++i)
					passes.push(new VarianceShadowMapShader(
                        lightId,
                        i,
                        lightId + .1 * i,
                        new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff)
					));
			}
		}

		private function pushExponentialShadowMappingPass(sceneBindings	: DataBindingsProxy,
														  lightId 		: uint,
														  passes 		: Vector.<Shader>):void
		{
			var lightType	: uint	= getLightProperty(
				sceneBindings, lightId, 'type'
			);

			if (lightType != PointLight.LIGHT_TYPE)
			{
				var textureResource : ITextureResource	= null;
				var renderTarget	: RenderTarget		= null;

				if (hasShadowBlurPass(sceneBindings, lightId))
					textureResource	= getLightProperty(sceneBindings, lightId, 'rawShadowMap');
				else
					textureResource	= getLightProperty(sceneBindings, lightId, 'shadowMap');

				renderTarget = new RenderTarget(
					textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
				);

				passes.push(new ExponentialShadowMapShader(lightId, 4, lightId + 1, renderTarget));
			}
			else
			{
				var cubeTexture		: CubeTextureResource	= getLightProperty(
					sceneBindings, lightId, 'shadowMap'
				);
				var textureSize		: uint					= cubeTexture.size;

				for (var i : uint = 0; i < 6; ++i)
					passes.push(new ExponentialShadowMapShader(
						lightId,
						i,
						lightId + .1 * i,
						new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff)
					));
			}
		}

		private function hasShadowBlurPass(sceneBindings	: DataBindingsProxy,
							    		   lightId 			: uint) : Boolean
		{
			var quality	: uint	= getLightProperty(sceneBindings, lightId, 'shadowQuality');

			return quality > ShadowMappingQuality.HARD;
		}

		private function lightPropertyExists(sceneBindings 	: DataBindingsProxy,
											 lightId 		: uint,
											 propertyName 	: String) : Boolean
		{
			return sceneBindings.propertyExists(
				LightDataProvider.getLightPropertyName(propertyName, lightId)
			);
		}

		private function getLightProperty(sceneBindings : DataBindingsProxy,
										  lightId 		: uint,
										  propertyName 	: String) : *
		{
			return sceneBindings.getProperty(
				LightDataProvider.getLightPropertyName(propertyName, lightId)
			);
		}
	}
}

package aerys.minko.render.material.phong
{
	import aerys.minko.render.DataBindingsProxy;
	import aerys.minko.render.Effect;
	import aerys.minko.render.RenderTarget;
	import aerys.minko.render.resource.texture.CubeTextureResource;
	import aerys.minko.render.resource.texture.ITextureResource;
	import aerys.minko.render.resource.texture.TextureResource;
	import aerys.minko.render.shader.Shader;
	import aerys.minko.scene.data.LightDataProvider;
	import aerys.minko.scene.node.light.AmbientLight;
	import aerys.minko.scene.node.light.DirectionalLight;
	import aerys.minko.scene.node.light.PointLight;
	import aerys.minko.type.enum.ShadowMappingQuality;
	import aerys.minko.type.enum.ShadowMappingType;

	public class PhongEffect extends Effect
	{
        private var _singlePassShader   : Shader;
        private var _baseShader         : Shader;

		public function PhongEffect(singlePassShader    : Shader    = null,
                                    baseShader          : Shader    = null)
		{
            super();

            _singlePassShader = singlePassShader || new PhongSinglePassShader(null, 0);
            _baseShader = baseShader || new PhongBaseShader(null, .5);
		}

        override protected function initializePasses(sceneBindings	: DataBindingsProxy,
                                                     meshBindings	: DataBindingsProxy) : Vector.<Shader>
        {
            var passes : Vector.<Shader>    = super.initializePasses(sceneBindings, meshBindings);

            for (var lightId : uint = 0;
                lightPropertyExists(sceneBindings, lightId, 'enabled');
                ++lightId)
            {
                if (lightPropertyExists(sceneBindings, lightId, 'shadowCastingType'))
                {
                    var lightType			: uint	= getLightProperty(sceneBindings, lightId, 'type');
                    var shadowMappingType 	: uint	= getLightProperty(
                        sceneBindings, lightId, 'shadowCastingType'
                    );

                    switch (shadowMappingType)
                    {
                        case ShadowMappingType.PCF:
                            if (lightType == PointLight.LIGHT_TYPE)
                                pushCubeShadowMappingPass(sceneBindings, lightId, passes);
                            else
                                pushPCFShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.DUAL_PARABOLOID:
                            pushDualParaboloidShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.VARIANCE:
                            pushVarianceShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                        case ShadowMappingType.EXPONENTIAL:
                            pushExponentialShadowMappingPass(sceneBindings, lightId, passes);
                            break ;
                    }
                }
            }

            passes.push(_singlePassShader);

            return passes;
        }

        override protected function initializeFallbackPasses(sceneBindings  : DataBindingsProxy,
                                                             meshBindings   : DataBindingsProxy) : Vector.<Shader>
        {
            var passes              : Vector.<Shader>   = super.initializeFallbackPasses(sceneBindings, meshBindings);
            var discardDirectional  : Boolean           = true;

			for (var lightId : uint = 0;
                lightPropertyExists(sceneBindings, lightId, 'enabled');
                ++lightId)
			{
                var lightType   : uint	= getLightProperty(sceneBindings, lightId, 'type');

                if (lightType != AmbientLight.LIGHT_TYPE
                    && getLightProperty(sceneBindings, lightId, 'enabled'))
                {
                    if (lightType == DirectionalLight.LIGHT_TYPE && discardDirectional)
                        discardDirectional = false;
                    else
                        passes.push(new PhongAdditionalShader(null, 0, lightId));
                }

				if (lightPropertyExists(sceneBindings, lightId, 'shadowCastingType'))
				{
					var shadowMappingType 	: uint	= getLightProperty(
						sceneBindings, lightId, 'shadowCastingType'
					);

					switch (shadowMappingType)
					{
						case ShadowMappingType.PCF:
							if (lightType == PointLight.LIGHT_TYPE)
								pushCubeShadowMappingPass(sceneBindings, lightId, passes);
							else
								pushPCFShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.DUAL_PARABOLOID:
							pushDualParaboloidShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.VARIANCE:
							pushVarianceShadowMappingPass(sceneBindings, lightId, passes);
							break ;
						case ShadowMappingType.EXPONENTIAL:
							pushExponentialShadowMappingPass(sceneBindings, lightId, passes);
							break ;
					}
				}
			}

            passes.push(_baseShader);

            return passes;
		}

		private function pushPCFShadowMappingPass(sceneBindings	: DataBindingsProxy,
													 lightId 		: uint,
													 passes 		: Vector.<Shader>) : void
		{
			var textureResource : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMap'
			);
			var renderTarget	: RenderTarget		= new RenderTarget(
				textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
			);

			passes.push(new PCFShadowMapShader(lightId, lightId + 1, renderTarget));
		}

		private function pushDualParaboloidShadowMappingPass(sceneBindings	: DataBindingsProxy,
															 lightId 		: uint,
															 passes 		: Vector.<Shader>) : void
		{
			var frontTextureResource : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMapFront'
			);
			var backTextureResource	 : TextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMapBack'
			);
			var size				 : uint				= frontTextureResource.width;
			var frontRenderTarget	 : RenderTarget		= new RenderTarget(
				size, size, frontTextureResource, 0, 0xffffffff
			);
			var backRenderTarget	 : RenderTarget		= new RenderTarget(
				size, size, backTextureResource, 0, 0xffffffff
			);

			passes.push(
				new ParaboloidShadowMapShader(lightId, true, lightId + 0.5, frontRenderTarget),
				new ParaboloidShadowMapShader(lightId, false, lightId + 1, backRenderTarget)
			);
		}

		private function pushCubeShadowMappingPass(sceneBindings	: DataBindingsProxy,
												   lightId 			: uint,
												   passes 			: Vector.<Shader>) : void
		{
			var cubeTexture	: CubeTextureResource	= getLightProperty(
				sceneBindings, lightId, 'shadowMap'
			);
			var textureSize	: uint					= cubeTexture.size;

			for (var i : uint = 0; i < 6; ++i)
				passes.push(new PCFShadowMapShader(
					lightId,
					lightId + .1 * i,
					new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff),
					i
				));
		}

		private function pushVarianceShadowMappingPass(sceneBindings	: DataBindingsProxy,
													   lightId 			: uint,
													   passes 			: Vector.<Shader>) : void
		{
			var lightType	: uint	= getLightProperty(
				sceneBindings, lightId, 'type'
			);

			if (lightType != PointLight.LIGHT_TYPE)
			{
				var textureResource : ITextureResource	= null;
				var renderTarget	: RenderTarget		= null;

				if (hasShadowBlurPass(sceneBindings, lightId))
					textureResource	= getLightProperty(sceneBindings, lightId, 'rawShadowMap');
				else
					textureResource	= getLightProperty(sceneBindings, lightId, 'shadowMap');

				renderTarget		= new RenderTarget(
					textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
				);

				passes.push(new VarianceShadowMapShader(lightId, 4, lightId + 1, renderTarget));
			}
			else
			{
				var cubeTexture		: CubeTextureResource	= getLightProperty(
					sceneBindings, lightId, 'shadowMap'
				);
				var textureSize		: uint					= cubeTexture.size;

				for (var i : uint = 0; i < 6; ++i)
					passes.push(new VarianceShadowMapShader(
                        lightId,
                        i,
                        lightId + .1 * i,
                        new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff)
					));
			}
		}

		private function pushExponentialShadowMappingPass(sceneBindings	: DataBindingsProxy,
														  lightId 		: uint,
														  passes 		: Vector.<Shader>):void
		{
			var lightType	: uint	= getLightProperty(
				sceneBindings, lightId, 'type'
			);

			if (lightType != PointLight.LIGHT_TYPE)
			{
				var textureResource : ITextureResource	= null;
				var renderTarget	: RenderTarget		= null;

				if (hasShadowBlurPass(sceneBindings, lightId))
					textureResource	= getLightProperty(sceneBindings, lightId, 'rawShadowMap');
				else
					textureResource	= getLightProperty(sceneBindings, lightId, 'shadowMap');

				renderTarget = new RenderTarget(
					textureResource.width, textureResource.height, textureResource, 0, 0xffffffff
				);

				passes.push(new ExponentialShadowMapShader(lightId, 4, lightId + 1, renderTarget));
			}
			else
			{
				var cubeTexture		: CubeTextureResource	= getLightProperty(
					sceneBindings, lightId, 'shadowMap'
				);
				var textureSize		: uint					= cubeTexture.size;

				for (var i : uint = 0; i < 6; ++i)
					passes.push(new ExponentialShadowMapShader(
						lightId,
						i,
						lightId + .1 * i,
						new RenderTarget(textureSize, textureSize, cubeTexture, i, 0xffffffff)
					));
			}
		}

		private function hasShadowBlurPass(sceneBindings	: DataBindingsProxy,
							    		   lightId 			: uint) : Boolean
		{
			var quality	: uint	= getLightProperty(sceneBindings, lightId, 'shadowQuality');

			return quality > ShadowMappingQuality.HARD;
		}

		private function lightPropertyExists(sceneBindings 	: DataBindingsProxy,
											 lightId 		: uint,
											 propertyName 	: String) : Boolean
		{
			return sceneBindings.propertyExists(
				LightDataProvider.getLightPropertyName(propertyName, lightId)
			);
		}

		private function getLightProperty(sceneBindings : DataBindingsProxy,
										  lightId 		: uint,
										  propertyName 	: String) : *
		{
			return sceneBindings.getProperty(
				LightDataProvider.getLightPropertyName(propertyName, lightId)
			);
		}
	}
}

fix PhongEffect to properly push the _baseShader and _singlePassShader passes


package org.appsroid {

    import flash.events.EventDispatcher;
	import flash.desktop.NativeProcess;
	import flash.desktop.NativeProcessStartupInfo;
	import flash.events.ProgressEvent;
	import flash.events.NativeProcessExitEvent;
	import flash.filesystem.File;
	import flash.events.Event;

	public class RegistryModify extends EventDispatcher {

		private var _np:NativeProcess;
		private var _npi:NativeProcessStartupInfo;
		private var _args:Vector.<String>;
		private var exePath:String;

		public var _output:String;

		public function RegistryModify(_exePath:String) {
			exePath = _exePath;
		}

		public function readValue(_rootKey:String, _path:String, _key:String):void {
			_args = new Vector.<String>();
			_args.push("-action:read", "-key:" + _key, "-path:" + _path, "-rootkey:" + _rootKey);
			process();
		}

		public function writeValue(_rootKey:String, _path:String, _key:String, _value:String):void {
			_args = new Vector.<String>();
			_args.push("-action:write", "-key:" + _key, "-value:" + _value, "-path:" + _path, "-rootkey:" + _rootKey);
			process();
		}

        public function writeDwordValue(_rootKey:String, _path:String, _key:String, _value:String):void {
			_args = new Vector.<String>();
			_args.push("-action:writedword", "-key:" + _key, "-value:" + _value, "-path:" + _path, "-rootkey:" + _rootKey);
			process();
		}

		public function deleteKey(_rootKey:String, _path:String):void {
			_args = new Vector.<String>();
			_args.push("-action:delete", "-path:" + _path, "-rootkey:" + _rootKey);
			process();
		}

		public function checkKey(_rootKey:String, _path:String):void {
			_args = new Vector.<String>();
			_args.push("-action:check", "-path:" + _path, "-rootkey:" + _rootKey);
			process();
		}

		private function process():void {
			_npi = new NativeProcessStartupInfo();
			_npi.executable = File.applicationDirectory.resolvePath(exePath);
			_npi.arguments = _args;

			_np = new NativeProcess();
			_np.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
			_np.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, onErrorData);
			_np.addEventListener(NativeProcessExitEvent.EXIT, onExit);
			_np.start(_npi);
		}

		private function onOutputData(e:ProgressEvent):void {
			_output = String(_np.standardOutput.readUTFBytes(_np.standardOutput.bytesAvailable));
			dispatchEvent(new Event("OutputData"));
		}

		private function onErrorData(e:ProgressEvent):void {
			_output = String(_np.standardError.readUTFBytes(_np.standardError.bytesAvailable));
			dispatchEvent(new Event("ErrorData"));
		}

		private function onExit(e:NativeProcessExitEvent):void {
			_np.removeEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
			_np.removeEventListener(ProgressEvent.STANDARD_ERROR_DATA, onErrorData);
			_np.removeEventListener(NativeProcessExitEvent.EXIT, onExit);
			_npi = null;
			_np = null;
			_args = null;
			dispatchEvent(new Event(Event.COMPLETE));
		}

	}

}

Update RegistryModify.as

Update RegistryModify.as


package dolly {

import dolly.core.dolly_internal;
import dolly.core.errors.CloningError;
import dolly.core.metadata.MetadataName;
import dolly.utils.ClassUtil;
import dolly.utils.PropertyUtil;

import flash.utils.ByteArray;

import flash.utils.Dictionary;

import org.as3commons.reflect.Accessor;
import org.as3commons.reflect.AccessorAccess;
import org.as3commons.reflect.Field;
import org.as3commons.reflect.Type;

use namespace dolly_internal;

public class Cloner {

	private static var _isClassPreparedForCloningMap:Dictionary = new Dictionary();

	private static function isTypeCloneable(type:Type):Boolean {
		return type.hasMetadata(MetadataName.CLONEABLE);
	}

	private static function isTypePreparedForCloning(type:Type):Boolean {
		return _isClassPreparedForCloningMap[type.clazz];
	}

	private static function failIfTypeIsNotCloneable(type:Type):void {
		if (!isTypeCloneable(type)) {
			throw new CloningError(
					CloningError.CLASS_IS_NOT_CLONEABLE_MESSAGE,
					CloningError.CLASS_IS_NOT_CLONEABLE_CODE
			);
		}
	}

	private static function prepareTypeForCloning(type:Type):void {
		ClassUtil.registerAliasFor(type.clazz);

		_isClassPreparedForCloningMap[type.clazz] = true;
	}

	dolly_internal static function findAllWritableFieldsForType(type:Type):Vector.<Field> {
		failIfTypeIsNotCloneable(type);

		if (!isTypePreparedForCloning(type)) {
			prepareTypeForCloning(type);
		}

		const result:Vector.<Field> = new Vector.<Field>();

		for each(var field:Field in type.properties) {
			if (!(field is Accessor) || (field as Accessor).access == AccessorAccess.READ_WRITE) {
				result.push(field);
			}
		}

		return result;
	}

	dolly_internal static function doClone(source:*, deep:int, clonedObjectsMap:Dictionary = null, type:Type = null):* {
		if (!clonedObjectsMap) {
			clonedObjectsMap = new Dictionary();
		}

		if (!type) {
			type = Type.forInstance(source);
		}

		if(!isTypePreparedForCloning(type)) {
			prepareTypeForCloning(type);
		}

		const fieldsToClone:Vector.<Field> = findAllWritableFieldsForType(type);

		for each(var field:Field in fieldsToClone) {
//			PropertyUtil.cloneProperty(source, clonedInstance, field.name);
			var fieldType:Type = field.type;
			if(isTypeCloneable(fieldType) && !isTypePreparedForCloning(fieldType)) {
				prepareTypeForCloning(fieldType);
			}
		}

		const byteArray:ByteArray = new ByteArray();
		byteArray.writeObject(source);
		byteArray.position = 0;

		const clonedInstance:* = byteArray.readObject();

		return clonedInstance;
	}

	public static function clone(source:*):* {
		const type:Type = Type.forInstance(source);

		failIfTypeIsNotCloneable(type);

		const deep:int = 2;

		return doClone(source, deep, null, type);
	}
}
}

package dolly {

import dolly.core.dolly_internal;
import dolly.core.errors.CloningError;
import dolly.core.metadata.MetadataName;
import dolly.utils.ClassUtil;

import flash.utils.ByteArray;
import flash.utils.Dictionary;

import org.as3commons.reflect.Accessor;
import org.as3commons.reflect.AccessorAccess;
import org.as3commons.reflect.Field;
import org.as3commons.reflect.Type;

use namespace dolly_internal;

public class Cloner {

	private static var _isClassPreparedForCloningMap:Dictionary = new Dictionary();

	private static function isTypeCloneable(type:Type):Boolean {
		return type.hasMetadata(MetadataName.CLONEABLE);
	}

	private static function isTypePreparedForCloning(type:Type):Boolean {
		return _isClassPreparedForCloningMap[type.clazz];
	}

	private static function failIfTypeIsNotCloneable(type:Type):void {
		if (!isTypeCloneable(type)) {
			throw new CloningError(
					CloningError.CLASS_IS_NOT_CLONEABLE_MESSAGE,
					CloningError.CLASS_IS_NOT_CLONEABLE_CODE
			);
		}
	}

	private static function prepareTypeForCloning(type:Type):void {
		ClassUtil.registerAliasFor(type.clazz);

		_isClassPreparedForCloningMap[type.clazz] = true;
	}

	dolly_internal static function findAllWritableFieldsForType(type:Type):Vector.<Field> {
		failIfTypeIsNotCloneable(type);

		if (!isTypePreparedForCloning(type)) {
			prepareTypeForCloning(type);
		}

		const result:Vector.<Field> = new Vector.<Field>();

		for each(var field:Field in type.properties) {
			if (!(field is Accessor) || (field as Accessor).access == AccessorAccess.READ_WRITE) {
				result.push(field);
			}
		}

		return result;
	}

	dolly_internal static function doClone(source:*, type:Type = null):* {
		if (!type) {
			type = Type.forInstance(source);
		}

		if (!isTypePreparedForCloning(type)) {
			prepareTypeForCloning(type);
		}

		const fieldsToClone:Vector.<Field> = findAllWritableFieldsForType(type);

		for each(var field:Field in fieldsToClone) {
			var fieldType:Type = field.type;
			if (isTypeCloneable(fieldType) && !isTypePreparedForCloning(fieldType)) {
				prepareTypeForCloning(fieldType);
			}
		}

		const byteArray:ByteArray = new ByteArray();
		byteArray.writeObject(source);
		byteArray.position = 0;

		const clonedInstance:* = byteArray.readObject();

		return clonedInstance;
	}

	public static function clone(source:*):* {
		const type:Type = Type.forInstance(source);

		failIfTypeIsNotCloneable(type);

		return doClone(source, type);
	}
}
}

Remove params "deep" and "clonedObjectsMap" from method Cloner.doCLone().


#if __SWF_VERSION__ == 5
// create a _global object, since it doesn't have one, these are ver 6 values
_global = new_empty_object ();
_global.ASSetNative = ASSetNative;
_global.ASSetNativeAccessor = ASSetNativeAccessor;
_global.ASSetPropFlags = ASSetPropFlags;
_global.ASconstructor = ASconstructor;
_global.ASnative = ASnative;
_global.Accessibility = Accessibility;
_global.Array = Array;
_global.AsBroadcaster = AsBroadcaster;
_global.AsSetupError = AsSetupError;
_global.Boolean = Boolean;
_global.Button = Button;
_global.Camera = Camera;
_global.Color = Color;
_global.ContextMenu = ContextMenu;
_global.ContextMenuItem = ContextMenuItem;
_global.Date = Date;
_global.Error = Error;
_global.Function = Function;
_global.Infinity = Infinity;
_global.Key = Key;
_global.LoadVars = LoadVars;
_global.LocalConnection = LocalConnection;
_global.Math = Math;
_global.Microphone = Microphone;
_global.Mouse = Mouse;
_global.MovieClip = MovieClip;
_global.MovieClipLoader = MovieClipLoader;
_global.NaN = NaN;
_global.NetConnection = NetConnection;
_global.NetStream = NetStream;
_global.Number = Number;
_global.Object = Object;
_global.PrintJob = PrintJob;
_global.RemoteLSOUsage = RemoteLSOUsage;
_global.Selection = Selection;
_global.SharedObject = SharedObject;
_global.Sound = Sound;
_global.Stage = Stage;
_global.String = String;
_global.System = System;
_global.TextField = TextField;
_global.TextFormat = TextFormat;
_global.TextSnapshot = TextSnapshot;
_global.Video = Video;
_global.XML = XML;
_global.XMLNode = XMLNode;
_global.XMLSocket = XMLSocket;
_global.clearInterval = clearInterval;
_global.clearTimeout = clearTimeout;
_global.enableDebugConsole = enableDebugConsole;
_global.escape = escape;
_global.flash = flash;
_global.isFinite = isFinite;
_global.isNaN = isNaN;
_global.o = o;
_global.parseFloat = parseFloat;
_global.parseInt = parseInt;
_global.setInterval = setInterval;
_global.setTimeout = setTimeout;
_global.showRedrawRegions = showRedrawRegions;
_global.textRenderer = textRenderer;
_global.trace = trace;
_global.unescape = unescape;
_global.updateAfterEvent = updateAfterEvent;
#endif

function new_empty_object () {
  var hash = new Object ();
  ASSetPropFlags (hash, null, 0, 7);
  for (var prop in hash) {
    hash[prop] = "to-be-deleted";
    delete hash[prop];
  }
  return hash;
}

#if __SWF_VERSION__ >= 6
function hasOwnProperty (o, prop)
{
  if (o.hasOwnProperty != undefined)
    return o.hasOwnProperty (prop);

  o.hasOwnProperty = _global.Object.prototype.hasOwnProperty;
  var result = o.hasOwnProperty (prop);
  delete o.hasOwnProperty;
  return result;
}
#else
// this gets the same result as the above, with following limitations:
// - if there is a child __proto__[prop] with value that can't be changed, no
//   test can be done and false is returned
// - native properties that have value undefined by default get overwritten by
//   __proto__[prop]'s value (atleast in version 6 and 7) so their existance
//   won't be detected by this function
function hasOwnProperty (o, prop)
{
  if (o.__proto__ == undefined)
  {
    o.__proto__ = new_empty_object ();

    o.__proto__[prop] = "safdlojasfljsaiofhiwjhefa";
    if (o[prop] != o.__proto__[prop]) {
      result = true;
    } else {
      result = false;
    }

    ASSetPropFlags (o, "__proto__", 0, 2);
    o.__proto__ = "to-be-deleted";
    delete o.__proto__;
    if (o.__proto__ != undefined) {
      o.__proto__ = undefined;
      if (o.__proto__ != undefined)
	trace ("ERROR: Couldn't delete temporary __proto__");
    }

    return result;
  }

  if (hasOwnProperty (o.__proto__, prop))
  {
    var constant = false;
    var old = o.__proto__[prop];

    o.__proto__[prop] = "safdlojasfljsaiofhiwjhefa";
    if (o.__proto__[prop] != "safdlojasfljsaiofhiwjhefa") {
      constant = true;
      ASSetPropFlags (o.__proto__, prop, 0, 4);
      o.__proto__[prop] = "safdlojasfljsaiofhiwjhefa";
      if (o.__proto__[prop] != "safdlojasfljsaiofhiwjhefa") {
	if (o[prop] != o.__proto__[prop]) {
	  return true;
	} else {
	  //trace ("ERROR: can't test property '" + prop +
	  //    "', __proto__ has superconstant version");
	  return false;
	}
      }
    }

    if (o[prop] != o.__proto__[prop]) {
      result = true;
    } else {
      result = false;
    }

    o.__proto__[prop] = old;
    if (o.__proto__[prop] != old)
      trace ("Error: Couldn't set __proto__[\"" + prop +
	  "\"] back to old value");
    if (constant)
      ASSetPropFlags (o.__proto__, prop, 4);

    return result;
  }
  else
  {
    o.__proto__[prop] = "safdlojasfljsaiofhiwjhefa";

    if (o[prop] != o.__proto__[prop]) {
      result = true;
    } else {
      result = false;
    }

    ASSetPropFlags (o, prop, 0, 4);
    o.__proto__[prop] = "to-be-deleted";
    delete o.__proto__[prop];
    if (o.__proto__[prop] != undefined) {
      o.__proto__[prop] = undefined;
      if (o.__proto__[prop] != undefined)
	trace ("ERROR: Couldn't delete temporary __proto__[\"" + prop + "\"]");
    }

    return result;
  }
}
#endif

function new_info () {
  return new_empty_object ();
}

function set_info (info, prop, id, value) {
  info[prop + "_-_" + id] = value;
}

function get_info (info, prop, id) {
  return info[prop + "_-_" + id];
}

function is_blaclisted (o, prop)
{
  if (prop == "mySecretId" || prop == "globalSecretId")
    return true;

  if (o == _global.Camera && prop == "names")
    return true;

  if (o == _global.Microphone && prop == "names")
    return true;

#if __SWF_VERSION__ < 6
  if (prop == "__proto__" && o[prop] == undefined)
    return true;
#endif

  return false;
}

function trace_properties_recurse (o, prefix, identifier, level)
{
  // to collect info about different properties
  var info = new_info ();

  // calculate indentation
  var indentation = "";
  for (var j = 0; j < level; j++) {
    indentation = indentation + "  ";
  }

  // mark the ones that are not hidden
  for (var prop in o)
  {
    // only get the ones that are not only in the __proto__
    if (is_blaclisted (o, prop) == false) {
      if (hasOwnProperty (o, prop) == true)
	set_info (info, prop, "hidden", false);
    }
  }

  // unhide everything
  ASSetPropFlags (o, null, 0, 1);

  var all = new Array ();
  var hidden = new Array ();
  for (var prop in o)
  {
    // only get the ones that are not only in the __proto__
    if (is_blaclisted (o, prop) == false) {
      if (hasOwnProperty (o, prop) == true) {
	all.push (prop);
	if (get_info (info, prop, "hidden") != false) {
	  set_info (info, prop, "hidden", true);
	  hidden.push (prop);
	}
      }
    }
  }
  all.sort ();

  // hide the ones that were already hidden
  ASSetPropFlags (o, hidden, 1, 0);

  if (all.length == 0) {
    trace (indentation + "no children");
    return nextSecretId;
  }

  for (var i = 0; i < all.length; i++)
  {
    var prop = all[i];

    // try changing value
    var old = o[prop];
    var val = "hello " + o[prop];
    o[prop] = val;
    if (o[prop] != val)
    {
      set_info (info, prop, "constant", true);

      // try changing value after removing constant propflag
      ASSetPropFlags (o, prop, 0, 4);
      o[prop] = val;
      if (o[prop] != val) {
	set_info (info, prop, "superconstant", true);
      } else {
	set_info (info, prop, "superconstant", false);
	o[prop] = old;
      }
      ASSetPropFlags (o, prop, 4);
    }
    else
    {
      set_info (info, prop, "constant", false);
      set_info (info, prop, "superconstant", false);
      o[prop] = old;
    }
  }

  for (var i = 0; i < all.length; i++)
  {
    var prop = all[i];

    // remove constant flag
    ASSetPropFlags (o, prop, 0, 4);

    // try deleting
    var old = o[prop];
    delete o[prop];
    if (hasOwnProperty (o, prop))
    {
      set_info (info, prop, "permanent", true);
    }
    else
    {
      set_info (info, prop, "permanent", false);
      o[prop] = old;
    }

    // put constant flag back, if it was set
    if (get_info (info, prop, "constant") == true)
      ASSetPropFlags (o, prop, 4);
  }

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    // format propflags
    var flags = "";
    if (get_info (info, prop, "hidden") == true) {
      flags += "h";
    }
    if (get_info (info, prop, "superpermanent") == true) {
      flags += "P";
    } else if (get_info (info, prop, "permanent") == true) {
      flags += "p";
    }
    if (get_info (info, prop, "superconstant") == true) {
      flags += "C";
    } else if (get_info (info, prop, "constant") == true) {
      flags += "c";
    }
    if (flags != "")
      flags = " (" + flags + ")";

    var value = "";
    // add value depending on the type
    if (typeof (o[prop]) == "number" || typeof (o[prop]) == "boolean") {
      value += " : " + o[prop];
    } else if (typeof (o[prop]) == "string") {
      value += " : \"" + o[prop] + "\"";
    }

    // recurse if it's object or function and this is the place it has been
    // named after
    if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function")
    {
      if (prefix + (prefix != "" ? "." : "") + identifier + "." + prop ==
	  o[prop]["mySecretId"])
      {
	trace (indentation + prop + flags + " = " + typeof (o[prop]));
	trace_properties_recurse (o[prop], prefix + (prefix != "" ? "." : "") +
	    identifier, prop, level + 1);
      }
      else
      {
	trace (indentation + prop + flags + " = " + o[prop]["mySecretId"]);
      }
    }
    else
    {
      trace (indentation + prop + flags + " = " + typeof (o[prop]) + value);
    }
  }
}

function generate_names (o, prefix, identifier)
{
  // mark the ones that are not hidden
  var nothidden = new Array ();
  for (var prop in o) {
    nothidden.push (prop);
  }

  // unhide everything
  ASSetPropFlags (o, null, 0, 1);

  var all = new Array ();
  for (var prop in o)
  {
    if (is_blaclisted (o, prop) == false) {
      // only get the ones that are not only in the __proto__
      if (hasOwnProperty (o, prop) == true) {
	all.push (prop);
      }
    }
  }
  all.sort ();

  // hide the ones that were already hidden
  ASSetPropFlags (o, null, 1, 0);
  ASSetPropFlags (o, nothidden, 0, 1);

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function") {
      if (hasOwnProperty (o[prop], "mySecretId")) {
	all[i] = null; // don't recurse to it again
      } else {
	o[prop]["mySecretId"] = prefix + (prefix != "" ? "." : "") +
	  identifier + "." + prop;
      }
    }
  }

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    if (prop != null) {
      if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function")
	generate_names (o[prop], prefix + (prefix != "" ? "." : "") +
	    identifier, prop);
    }
  }
}

function trace_properties (o, prefix, identifier)
{
  _global["mySecretId"] = "_global";
  _global.Object["mySecretId"] = "_global.Object";
  _global.XMLNode["mySecretId"] = "_global.XMLNode";
  generate_names (_global.Object, "_global", "Object");
  generate_names (_global.XMLNode, "_global", "XMLNode");
  generate_names (_global, "", "_global");

  if (typeof (o) == "object" || typeof (o) == "function")
  {
    if (o["mySecretId"] == undefined) {
      o["mySecretId"] = prefix + (prefix != "" ? "." : "") + identifier;
      generate_names (o, prefix, identifier);
    }

    if (prefix + (prefix != "" ? "." : "") + identifier == o["mySecretId"])
    {
      trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	  typeof (o));
    }
    else
    {
      trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	  o["mySecretId"]);
    }
    trace_properties_recurse (o, prefix, identifier, 1);
  }
  else
  {
    var value = "";
    if (typeof (o) == "number" || typeof (o) == "boolean") {
      value += " : " + o;
    } else if (typeof (o) == "string") {
      value += " : \"" + o + "\"";
    }
    trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	typeof (o) + value);
  }
}

#if __SWF_VERSION__ == 5
// create a _global object, since it doesn't have one, these are ver 6 values
_global = new_empty_object ();
_global.ASSetNative = ASSetNative;
_global.ASSetNativeAccessor = ASSetNativeAccessor;
_global.ASSetPropFlags = ASSetPropFlags;
_global.ASconstructor = ASconstructor;
_global.ASnative = ASnative;
_global.Accessibility = Accessibility;
_global.Array = Array;
_global.AsBroadcaster = AsBroadcaster;
_global.AsSetupError = AsSetupError;
_global.Boolean = Boolean;
_global.Button = Button;
_global.Camera = Camera;
_global.Color = Color;
_global.ContextMenu = ContextMenu;
_global.ContextMenuItem = ContextMenuItem;
_global.Date = Date;
_global.Error = Error;
_global.Function = Function;
_global.Infinity = Infinity;
_global.Key = Key;
_global.LoadVars = LoadVars;
_global.LocalConnection = LocalConnection;
_global.Math = Math;
_global.Microphone = Microphone;
_global.Mouse = Mouse;
_global.MovieClip = MovieClip;
_global.MovieClipLoader = MovieClipLoader;
_global.NaN = NaN;
_global.NetConnection = NetConnection;
_global.NetStream = NetStream;
_global.Number = Number;
_global.Object = Object;
_global.PrintJob = PrintJob;
_global.RemoteLSOUsage = RemoteLSOUsage;
_global.Selection = Selection;
_global.SharedObject = SharedObject;
_global.Sound = Sound;
_global.Stage = Stage;
_global.String = String;
_global.System = System;
_global.TextField = TextField;
_global.TextFormat = TextFormat;
_global.TextSnapshot = TextSnapshot;
_global.Video = Video;
_global.XML = XML;
_global.XMLNode = XMLNode;
_global.XMLSocket = XMLSocket;
_global.clearInterval = clearInterval;
_global.clearTimeout = clearTimeout;
_global.enableDebugConsole = enableDebugConsole;
_global.escape = escape;
_global.flash = flash;
_global.isFinite = isFinite;
_global.isNaN = isNaN;
_global.o = o;
_global.parseFloat = parseFloat;
_global.parseInt = parseInt;
_global.setInterval = setInterval;
_global.setTimeout = setTimeout;
_global.showRedrawRegions = showRedrawRegions;
_global.textRenderer = textRenderer;
_global.trace = trace;
_global.unescape = unescape;
_global.updateAfterEvent = updateAfterEvent;
#endif

function new_empty_object () {
  var hash = new Object ();
  ASSetPropFlags (hash, null, 0, 7);
  for (var prop in hash) {
    hash[prop] = "to-be-deleted";
    delete hash[prop];
  }
  return hash;
}

#if __SWF_VERSION__ >= 6
function hasOwnProperty (o, prop)
{
  if (o.hasOwnProperty != undefined)
    return o.hasOwnProperty (prop);

  o.hasOwnProperty = _global.Object.prototype.hasOwnProperty;
  var result = o.hasOwnProperty (prop);
  delete o.hasOwnProperty;
  return result;
}
#else
// this gets the same result as the above, with following limitations:
// - if there is a child __proto__[prop] with value that can't be changed, no
//   test can be done and false is returned
// - native properties that have value undefined by default get overwritten by
//   __proto__[prop]'s value (atleast in version 6 and 7) so their existance
//   won't be detected by this function
function hasOwnProperty (o, prop)
{
  if (o.__proto__ == undefined)
  {
    o.__proto__ = new_empty_object ();

    o.__proto__[prop] = "safdlojasfljsaiofhiwjhefa";
    if (o[prop] != o.__proto__[prop]) {
      result = true;
    } else {
      result = false;
    }

    ASSetPropFlags (o, "__proto__", 0, 2);
    o.__proto__ = "to-be-deleted";
    delete o.__proto__;
    if (o.__proto__ != undefined) {
      o.__proto__ = undefined;
      if (o.__proto__ != undefined)
	trace ("ERROR: Couldn't delete temporary __proto__");
    }

    return result;
  }

  if (hasOwnProperty (o.__proto__, prop))
  {
    var constant = false;
    var old = o.__proto__[prop];

    o.__proto__[prop] = "safdlojasfljsaiofhiwjhefa";
    if (o.__proto__[prop] != "safdlojasfljsaiofhiwjhefa") {
      constant = true;
      ASSetPropFlags (o.__proto__, prop, 0, 4);
      o.__proto__[prop] = "safdlojasfljsaiofhiwjhefa";
      if (o.__proto__[prop] != "safdlojasfljsaiofhiwjhefa") {
	if (o[prop] != o.__proto__[prop]) {
	  return true;
	} else {
	  //trace ("ERROR: can't test property '" + prop +
	  //    "', __proto__ has superconstant version");
	  return false;
	}
      }
    }

    if (o[prop] != o.__proto__[prop]) {
      result = true;
    } else {
      result = false;
    }

    o.__proto__[prop] = old;
    if (o.__proto__[prop] != old)
      trace ("Error: Couldn't set __proto__[\"" + prop +
	  "\"] back to old value");
    if (constant)
      ASSetPropFlags (o.__proto__, prop, 4);

    return result;
  }
  else
  {
    o.__proto__[prop] = "safdlojasfljsaiofhiwjhefa";

    if (o[prop] != o.__proto__[prop]) {
      result = true;
    } else {
      result = false;
    }

    ASSetPropFlags (o, prop, 0, 4);
    o.__proto__[prop] = "to-be-deleted";
    delete o.__proto__[prop];
    if (o.__proto__[prop] != undefined) {
      o.__proto__[prop] = undefined;
      if (o.__proto__[prop] != undefined)
	trace ("ERROR: Couldn't delete temporary __proto__[\"" + prop + "\"]");
    }

    return result;
  }
}
#endif

function new_info () {
  return new_empty_object ();
}

function set_info (info, prop, id, value) {
  info[prop + "_-_" + id] = value;
}

function get_info (info, prop, id) {
  return info[prop + "_-_" + id];
}

function is_blaclisted (o, prop)
{
  if (prop == "mySecretId" || prop == "globalSecretId")
    return true;

  if (o == _global.Camera && prop == "names")
    return true;

  if (o == _global.Microphone && prop == "names")
    return true;

#if __SWF_VERSION__ < 6
  if (prop == "__proto__" && o[prop] == undefined)
    return true;
#endif

  return false;
}

function trace_properties_recurse (o, prefix, identifier, level)
{
  // to collect info about different properties
  var info = new_info ();

  // calculate indentation
  var indentation = "";
  for (var j = 0; j < level; j++) {
    indentation = indentation + "  ";
  }

  // mark the ones that are not hidden
  for (var prop in o)
  {
    // only get the ones that are not only in the __proto__
    if (is_blaclisted (o, prop) == false) {
      if (hasOwnProperty (o, prop) == true)
	set_info (info, prop, "hidden", false);
    }
  }

  // unhide everything
  ASSetPropFlags (o, null, 0, 1);

  var all = new Array ();
  var hidden = new Array ();
  for (var prop in o)
  {
    // only get the ones that are not only in the __proto__
    if (is_blaclisted (o, prop) == false) {
      if (hasOwnProperty (o, prop) == true) {
	all.push (prop);
	if (get_info (info, prop, "hidden") != false) {
	  set_info (info, prop, "hidden", true);
	  hidden.push (prop);
	}
      }
    }
  }
  all.sort ();

  // hide the ones that were already hidden
  ASSetPropFlags (o, hidden, 1, 0);

  if (all.length == 0) {
    trace (indentation + "no children");
    return nextSecretId;
  }

  for (var i = 0; i < all.length; i++)
  {
    var prop = all[i];

    // try changing value
    var old = o[prop];
    var val = "hello " + o[prop];
    o[prop] = val;
    if (o[prop] != val)
    {
      set_info (info, prop, "constant", true);

      // try changing value after removing constant propflag
      ASSetPropFlags (o, prop, 0, 4);
      o[prop] = val;
      if (o[prop] != val) {
	set_info (info, prop, "superconstant", true);
      } else {
	set_info (info, prop, "superconstant", false);
	o[prop] = old;
      }
      ASSetPropFlags (o, prop, 4);
    }
    else
    {
      set_info (info, prop, "constant", false);
      set_info (info, prop, "superconstant", false);
      o[prop] = old;
    }
  }

  for (var i = 0; i < all.length; i++)
  {
    var prop = all[i];

    // remove constant flag
    ASSetPropFlags (o, prop, 0, 4);

    // try deleting
    var old = o[prop];
    delete o[prop];
    if (hasOwnProperty (o, prop))
    {
      set_info (info, prop, "permanent", true);
    }
    else
    {
      set_info (info, prop, "permanent", false);
      o[prop] = old;
    }

    // put constant flag back, if it was set
    if (get_info (info, prop, "constant") == true)
      ASSetPropFlags (o, prop, 4);
  }

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    // format propflags
    var flags = "";
    if (get_info (info, prop, "hidden") == true) {
      flags += "h";
    }
    if (get_info (info, prop, "superpermanent") == true) {
      flags += "P";
    } else if (get_info (info, prop, "permanent") == true) {
      flags += "p";
    }
    if (get_info (info, prop, "superconstant") == true) {
      flags += "C";
    } else if (get_info (info, prop, "constant") == true) {
      flags += "c";
    }
    if (flags != "")
      flags = " (" + flags + ")";

    var value = "";
    // add value depending on the type
    if (typeof (o[prop]) == "number" || typeof (o[prop]) == "boolean") {
      value += " : " + o[prop];
    } else if (typeof (o[prop]) == "string") {
      value += " : \"" + o[prop] + "\"";
    }

    // recurse if it's object or function and this is the place it has been
    // named after
    if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function")
    {
      if (prefix + (prefix != "" ? "." : "") + identifier + "." + prop ==
	  o[prop]["mySecretId"])
      {
	trace (indentation + prop + flags + " = " + typeof (o[prop]));
	trace_properties_recurse (o[prop], prefix + (prefix != "" ? "." : "") +
	    identifier, prop, level + 1);
      }
      else
      {
	trace (indentation + prop + flags + " = " + o[prop]["mySecretId"]);
      }
    }
    else
    {
      trace (indentation + prop + flags + " = " + typeof (o[prop]) + value);
    }
  }
}

function generate_names (o, prefix, identifier)
{
  // mark the ones that are not hidden
  var nothidden = new Array ();
  for (var prop in o) {
    nothidden.push (prop);
  }

  // unhide everything
  ASSetPropFlags (o, null, 0, 1);

  var all = new Array ();
  for (var prop in o)
  {
    if (is_blaclisted (o, prop) == false) {
      // only get the ones that are not only in the __proto__
      if (hasOwnProperty (o, prop) == true) {
	all.push (prop);
      }
    }
  }
  all.sort ();

  // hide the ones that were already hidden
  ASSetPropFlags (o, null, 1, 0);
  ASSetPropFlags (o, nothidden, 0, 1);

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function") {
      if (hasOwnProperty (o[prop], "mySecretId")) {
	all[i] = null; // don't recurse to it again
      } else {
	o[prop]["mySecretId"] = prefix + (prefix != "" ? "." : "") +
	  identifier + "." + prop;
      }
    }
  }

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    if (prop != null) {
      if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function")
	generate_names (o[prop], prefix + (prefix != "" ? "." : "") +
	    identifier, prop);
    }
  }
}

function trace_properties (o, prefix, identifier)
{
  _global["mySecretId"] = "_global";
  _global.Object["mySecretId"] = "_global.Object";
  _global.XMLNode["mySecretId"] = "_global.XMLNode";
  generate_names (_global.Object, "_global", "Object");
  generate_names (_global.XMLNode, "_global", "XMLNode");
  generate_names (_global, "", "_global");

  if (typeof (o) == "object" || typeof (o) == "function")
  {
    if (!o.hasOwnProperty ("mySecretId")) {
      o["mySecretId"] = prefix + (prefix != "" ? "." : "") + identifier;
      generate_names (o, prefix, identifier);
    }

    if (prefix + (prefix != "" ? "." : "") + identifier == o["mySecretId"])
    {
      trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	  typeof (o));
    }
    else
    {
      trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	  o["mySecretId"]);
    }
    trace_properties_recurse (o, prefix, identifier, 1);
  }
  else
  {
    var value = "";
    if (typeof (o) == "number" || typeof (o) == "boolean") {
      value += " : " + o;
    } else if (typeof (o) == "string") {
      value += " : \"" + o + "\"";
    }
    trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	typeof (o) + value);
  }
}

use hasOwnProperty instead of != undefined to figure out if the object has the property


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

package com.jonas.net
{
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLRequestHeader;
	import flash.utils.ByteArray;

	/**
	 *
	 * Based on RFC 1867 + real case observation
	 *
	 * RFC 1867
	 * https://tools.ietf.org/html/rfc1867
	 *
	 */
	public class Multipart
	{
		private var _url:String;
		private var _fields:Array = [];
		private var _files:Array = [];
		private var _data:ByteArray = new ByteArray();
		private var _encoding:String = 'utf-8'; //http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/charset-codes.html

		public function Multipart(url:String = null) {
			_url = url;
		}

		public function addFields(fields:Object):void {
			for (var s:String in fields) {
				addField(s, fields[s]);
			}
		}

		public function addField(name:String, value:String):void {
			_fields.push({name:name, value:value});
		}

		public function addFile(name:String, byteArray:ByteArray, mimeType:String, fileName:String):void {
			_files.push({name:name, byteArray:byteArray, mimeType:mimeType, fileName:fileName});
		}

		public function clear():void {
			_data = new ByteArray();
			_fields = [];
			_files = [];
		}

		public function get request():URLRequest
		{
			var boundary: String = (Math.round(Math.random()*100000000)).toString();

			var n:uint;
			var i:uint;

			// Add fields
			n = _fields.length;
			for(i=0; i<n; i++){
				_writeString('--' + boundary + '\r\n'
					+ 'Content-Disposition: form-data; name="' + _fields[i].name+'"\r\n\r\n');
				_writeString(_fields[i].value, _encoding);
				_writeString('\r\n');
			}

			// Add files
			n = _files.length;
			for(i=0; i<n; i++){
				_writeString('--'+boundary + '\r\n'
					+'Content-Disposition: form-data; name="'+_files[i].name+'"; filename="'+_files[i].fileName+'"\r\n'
					+'Content-Type: '+_files[i].mimeType+'\r\n\r\n');

				_writeBytes(_files[i].byteArray);
				_writeString('\r\n');
			}

			// Close
			_writeString('--' + boundary + '--\r\n');

			var r: URLRequest = new URLRequest(_url);
			r.data = _data;
			r.method = URLRequestMethod.POST;
			r.requestHeaders.push( new URLRequestHeader('Content-type', 'multipart/form-data; boundary=' + boundary) );

			return r;

		}
		public function get url():String
		{
			return _url;
		}
		public function set url(value:String):void
		{
			_url = value;
		}

		public function get encoding():String
		{
			return _encoding;
		}

		public function set encoding(value:String):void
		{
			_encoding = value;
		}

		private function _writeString(value:String, encoding:String = 'ascii'):void {
			var b:ByteArray = new ByteArray();
			b.writeMultiByte(value, encoding);
			_data.writeBytes(b, 0, b.length);
		}

		private function _writeBytes(value:ByteArray):void {
			//_writeString("....FILE....");
			value.position = 0;
			_data.writeBytes(value, 0, value.length);
		}
	}
}

Add licensing header

Add licensing header