flex-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aha...@apache.org
Subject [13/50] [abbrv] git commit: [flex-asjs] [refs/heads/spark] - more changes to try to get things to run
Date Thu, 25 Aug 2016 15:32:21 GMT
more changes to try to get things to run


Project: http://git-wip-us.apache.org/repos/asf/flex-asjs/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-asjs/commit/aaa01ca6
Tree: http://git-wip-us.apache.org/repos/asf/flex-asjs/tree/aaa01ca6
Diff: http://git-wip-us.apache.org/repos/asf/flex-asjs/diff/aaa01ca6

Branch: refs/heads/spark
Commit: aaa01ca6ac83accbcce80cde4f75936a091abbfc
Parents: 259732a
Author: Alex Harui <aharui@apache.org>
Authored: Thu Jul 28 12:17:25 2016 -0700
Committer: Alex Harui <aharui@apache.org>
Committed: Thu Jul 28 12:17:25 2016 -0700

----------------------------------------------------------------------
 .../main/flex/org/apache/flex/utils/Platform.as |    2 +-
 .../MX/src/main/config/compile-as-config.xml    |    4 +
 .../projects/MX/src/main/flex/MXClasses.as      |    3 +
 .../flashx/textLayout/compose/ISWFContext.as    |   78 +
 .../MX/src/main/flex/flex/display/ModuleInfo.as |   35 +
 .../main/flex/flex/display/TopOfDisplayList.as  |   34 +-
 .../flex/flex/events/FlashEventConverter.as     |  205 ++
 .../MX/src/main/flex/mx/core/Application.as     |   30 +-
 .../MX/src/main/flex/mx/core/UIComponent.as     |   12 +
 .../src/main/flex/mx/managers/LayoutManager.as  | 1259 ++++++++++++
 .../src/main/flex/mx/managers/SystemManager.as  |   46 +-
 .../mx/managers/layoutClasses/PriorityQueue.as  |  398 ++++
 .../mx/managers/systemClasses/ChildManager.as   |  489 +++++
 .../flex/mx/preloaders/DownloadProgressBar.as   | 1916 ++++++++++++++++++
 .../MX/src/main/flex/mx/preloaders/Preloader.as |    3 +-
 .../projects/MX/src/main/resources/defaults.css |  288 +++
 frameworks/projects/MX/src/test/flex/build.xml  |    5 -
 .../MX/src/test/flex/src/TestCompile.mxml       |    2 +
 18 files changed, 4769 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/aaa01ca6/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/Platform.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/Platform.as b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/Platform.as
index 35725cf..4b667b7 100644
--- a/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/Platform.as
+++ b/frameworks/projects/Core/src/main/flex/org/apache/flex/utils/Platform.as
@@ -89,7 +89,7 @@ package org.apache.flex.utils
 		{
 			COMPILE::SWF
 			{
-				if (!platform)
+				if (!_platform)
 				{
 					var cap: Class = Capabilities;
 					var version:  String = Capabilities.version;

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/aaa01ca6/frameworks/projects/MX/src/main/config/compile-as-config.xml
----------------------------------------------------------------------
diff --git a/frameworks/projects/MX/src/main/config/compile-as-config.xml b/frameworks/projects/MX/src/main/config/compile-as-config.xml
index 7f3365e..7dcbd89 100644
--- a/frameworks/projects/MX/src/main/config/compile-as-config.xml
+++ b/frameworks/projects/MX/src/main/config/compile-as-config.xml
@@ -80,6 +80,10 @@
     </compiler>
     
     <include-file>
+        <name>defaults.css</name>
+        <path>../resources/defaults.css</path>
+    </include-file>
+    <include-file>
         <name>js/out/*</name>
         <path>../../../../../js/FlexJS/projects/MXJS/target/generated-sources/flexjs/*</path>
     </include-file>

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/aaa01ca6/frameworks/projects/MX/src/main/flex/MXClasses.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/MX/src/main/flex/MXClasses.as b/frameworks/projects/MX/src/main/flex/MXClasses.as
index d637ae9..060f351 100644
--- a/frameworks/projects/MX/src/main/flex/MXClasses.as
+++ b/frameworks/projects/MX/src/main/flex/MXClasses.as
@@ -28,8 +28,11 @@ package
 internal class MXClasses
 {
 
+    import flashx.textLayout.compose.ISWFContext; ISWFContext;
     import mx.core.UIComponent; UIComponent;
     import mx.modules.IModule; IModule;
+    import mx.preloaders.DownloadProgressBar; DownloadProgressBar;
+	import mx.managers.systemClasses.ChildManager; ChildManager;
 }
 
 }

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/aaa01ca6/frameworks/projects/MX/src/main/flex/flashx/textLayout/compose/ISWFContext.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/MX/src/main/flex/flashx/textLayout/compose/ISWFContext.as b/frameworks/projects/MX/src/main/flex/flashx/textLayout/compose/ISWFContext.as
new file mode 100644
index 0000000..10c1028
--- /dev/null
+++ b/frameworks/projects/MX/src/main/flex/flashx/textLayout/compose/ISWFContext.as
@@ -0,0 +1,78 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{
+	/** 
+	 * The ISWFContext interface allows a SWF file to share its context with other SWF files that load it.
+	 * An application that loads a SWF file of type ISWFContext can call methods in the context of the loaded SWF file.
+	 * The main usage is for calling the FTE TextLine creation methods.
+	 * 
+	 * <p>There are two reasons for an application to use 
+	 * this interface to control TextLine creation: </p>
+	 * <ul>
+	 *   <li><strong>Reuse an embedded font: </strong> if an application wants to use a font embedded in a loaded SWF file,
+	 * the application can access the font if a TextLine
+	 * is created in the context of the loaded SWF file.</li>
+	 *   <li><strong>Reuse existing TextLine instances</strong>: reusing existing TextLine instances can result in faster recompose times. 
+	 * TLF reuses existing TextLine instances internally. TLF reuses 
+	 * a TextLine by calling <code>TextBlock.recreateTextLine()</code>
+	 * instead of <code>TextBlock.createTextLine()</code> when TLF recognizes that a TextLine is extant.</li>
+	 * </ul>
+	 *
+	 * 
+	 * <p>Your application may have additional TextLine instances that can be reused. 
+	 * To manually reuse existing TextLine instances:</p>
+	 * <ol>
+	 *   <li>trap calls to <code>TextBlock.createTextLine()</code>, then</li>
+	 *   <li>call <code>TextBlock.recreateTextLine()</code> with the extant TextLine instance instead 
+	 * of <code>TextBlock.createTextLine()</code>.</li>
+	 * </ol>
+	 * <p>Please note, however, that the <code>TextBlock.recreateTextLine()</code> is available
+	 * only in Flash Player 10.1 and later.</p>
+	 *
+	 * @see flash.text.engine.TextBlock#createTextLine()
+	 * @see flash.text.engine.TextBlock#recreateTextLine()
+	 * @includeExample examples\EmbeddedFontLineCreator.as -noswf
+	 * @includeExample examples\FontConsumer.as -noswf
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public interface ISWFContext
+	{
+	    /**
+	     *  A way to call a method in a client controlled context.
+	     *
+	     *  @param fn The function or method to call
+	     *  @param thisArg The this pointer for the function
+	     *  @param argArray The arguments for the function
+	     *  @param returns If true, the function returns a value
+	     *
+	     *  @return Whatever the function returns, if anything.
+	     *
+	     *  @see Function#apply()
+	
+	     *  @langversion 3.0
+	     *  @playerversion Flash 10
+	     *  @playerversion AIR 1.5
+	     */
+	    function callInContext(fn:Function, thisArg:Object, argArray:Array, returns:Boolean=true):*;
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/aaa01ca6/frameworks/projects/MX/src/main/flex/flex/display/ModuleInfo.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/MX/src/main/flex/flex/display/ModuleInfo.as b/frameworks/projects/MX/src/main/flex/flex/display/ModuleInfo.as
index 2ce5c93..2bf9996 100644
--- a/frameworks/projects/MX/src/main/flex/flex/display/ModuleInfo.as
+++ b/frameworks/projects/MX/src/main/flex/flex/display/ModuleInfo.as
@@ -54,6 +54,12 @@ package flex.display
 			return loaderInfo.url;
 		}
 		
+		COMPILE::SWF
+		public function get parameters():Object
+		{
+			return loaderInfo.parameters;
+		}
+		
 		COMPILE::JS
 		public function get height():Number
 		{
@@ -71,5 +77,34 @@ package flex.display
 		{
 			return document.URL;
 		}
+		
+		COMPILE::JS
+		private var _parameters:Object;
+		
+		COMPILE::JS
+		public function get parameters():Object
+		{
+			if (!_parameters)
+				_parameters = makeParameters(document.URL);
+			return _parameters;
+		}
+		
+		COMPILE::JS
+		private function makeParameters(url:String):Object
+		{
+			if (url == null || url.length == 0)
+				return {};
+			
+			url = url.substring(1); // remove leading ?
+			var parts:Array = url.split("&");
+			var parms:Object = {};
+			for each (var part:String in parts)
+			{
+				var subParts:Array = part.split("=");
+				parms[subParts[0]] = subParts[1];
+			}
+			return parms;
+		}
+
 	}
 }

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/aaa01ca6/frameworks/projects/MX/src/main/flex/flex/display/TopOfDisplayList.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/MX/src/main/flex/flex/display/TopOfDisplayList.as b/frameworks/projects/MX/src/main/flex/flex/display/TopOfDisplayList.as
index b56732f..5588393 100644
--- a/frameworks/projects/MX/src/main/flex/flex/display/TopOfDisplayList.as
+++ b/frameworks/projects/MX/src/main/flex/flex/display/TopOfDisplayList.as
@@ -19,8 +19,12 @@
 
 package flex.display
 {
+	import org.apache.flex.events.EventDispatcher;
+
 COMPILE::SWF
 {
+	import flash.display.DisplayObject;
+	import flash.display.InteractiveObject;
 	import flash.display.Stage;
 }
 COMPILE::JS
@@ -31,7 +35,7 @@ COMPILE::JS
 }
 
 COMPILE::SWF
-public class TopOfDisplayList extends Stage
+public class TopOfDisplayList extends EventDispatcher
 {
 	public function TopOfDisplayList(stage:Stage)
 	{
@@ -39,16 +43,40 @@ public class TopOfDisplayList extends Stage
 		_stage = stage;
 	}
 	
-	override public function get width():Number
+	public function get width():Number
 	{
 		return _stage.stageWidth;
 	}
 	
-	override public function get height():Number
+	public function get height():Number
 	{
 		return _stage.stageHeight;
 	}
 	
+	public function getChildAt(index:int):flash.display.DisplayObject
+	{
+		return _stage.getChildAt(index);
+	}
+	
+	/**
+	 */
+	public function get focus():flash.display.InteractiveObject
+	{
+		return _stage.focus;
+	}
+	
+	/**
+	 */
+	public function set focus(value:flash.display.InteractiveObject):void
+	{
+		_stage.focus = value;
+	}
+	
+	public function invalidate():void
+	{
+		_stage.invalidate();
+	}
+	
 	private var _stage:Stage;
 	
 }

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/aaa01ca6/frameworks/projects/MX/src/main/flex/flex/events/FlashEventConverter.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/MX/src/main/flex/flex/events/FlashEventConverter.as b/frameworks/projects/MX/src/main/flex/flex/events/FlashEventConverter.as
new file mode 100644
index 0000000..bfab166
--- /dev/null
+++ b/frameworks/projects/MX/src/main/flex/flex/events/FlashEventConverter.as
@@ -0,0 +1,205 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flex.events
+{	
+	import flash.display.DisplayObject;
+    import flash.events.Event;
+    import flash.events.FocusEvent;
+    import flash.events.IEventDispatcher;
+    import flash.utils.Dictionary;
+    
+    import flex.display.InteractiveObject;
+        
+	/**
+	 *  Mouse events conversion.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10.2
+     *  @playerversion AIR 2.6
+     *  @productversion FlexJS 0.0
+	 */
+    COMPILE::SWF
+	public class FlashEventConverter
+	{
+        private static function mouseEventConverter(event:flash.events.Event):void
+        {
+			var srcClass:Class;
+			var destClass:Class;
+			var converter:Function;
+			for (var c:Class in eventClassMap)
+			{
+				if (event is c)
+				{
+					srcClass = c;
+					destClass = eventClassMap[c];
+					converter = eventClassConverters[c];
+				}
+			}
+			if (!srcClass)
+			{
+				srcClass = flash.events.Event;
+				destClass = flex.events.Event;
+				converter = eventConverter;
+			}
+            if (!(event is destClass))
+            {
+				var newEvent:flex.events.Event = converter(event) as flex.events.Event;
+				event.stopImmediatePropagation();
+				event.target.dispatchEvent(newEvent);
+            }
+        }
+        
+		/**
+		 *  The map of events classes to convert.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10.2
+		 *  @playerversion AIR 2.6
+		 *  @productversion FlexJS 0.0
+		 */
+		public static var eventClassMap:Dictionary = new Dictionary();
+		
+		/**
+		 *  The map of events class conversion functions.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10.2
+		 *  @playerversion AIR 2.6
+		 *  @productversion FlexJS 0.0
+		 */
+		public static var eventClassConverters:Dictionary = new Dictionary();
+		
+        /**
+         *  The list of events to convert by intercepting in capture phase
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 10.2
+         *  @playerversion AIR 2.6
+         *  @productversion FlexJS 0.0
+         */
+        public static var captureConvertedEvents:Array = [
+			flash.events.Event.ACTIVATE,
+			flash.events.Event.ADDED,
+			flash.events.Event.DEACTIVATE,
+			flash.events.Event.REMOVED
+            ];
+            
+		/**
+		 *  The list of stage events to convert that can't be captured
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10.2
+		 *  @playerversion AIR 2.6
+		 *  @productversion FlexJS 0.0
+		 */
+		public static var stageConvertedEvents:Array = [
+			flash.events.Event.ACTIVATE,
+			flash.events.Event.ADDED,
+			flash.events.Event.DEACTIVATE,
+			flash.events.Event.ENTER_FRAME,
+			flash.events.Event.REMOVED,
+			flash.events.Event.RENDER
+		];
+		
+        /**
+         *  The event handler that converts the events.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 10.2
+         *  @playerversion AIR 2.6
+         *  @productversion FlexJS 0.0
+         */
+        public static var eventHandler:Function = mouseEventConverter;
+        
+		/**
+		 *  The target used to capture and convert the events.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10.2
+		 *  @playerversion AIR 2.6
+		 *  @productversion FlexJS 0.0
+		 */
+		private static var captureTarget:DisplayObject;
+		
+        /**
+         *  Set up the top level converter.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 10.2
+         *  @playerversion AIR 2.6
+         *  @productversion FlexJS 0.0
+         */
+        public static function setupAllConverters(target:DisplayObject):void
+        {
+			captureTarget = target;
+            for each (var eventType:String in captureConvertedEvents)
+                target.addEventListener(eventType, eventHandler, true, 9999);
+	
+			if (target.stage) 
+				for each (eventType in stageConvertedEvents)
+					target.stage.addEventListener(eventType, eventHandler, false, 9999);
+				
+			// don't add this.  It is the default if no other matches
+			// eventClassMap[flash.events.Event] = flex.events.Event;
+			eventClassMap[flash.events.FocusEvent] = flex.events.FocusEvent;
+			eventClassConverters[flash.events.FocusEvent] = focusEventConverter;
+        }
+
+		/**
+		 *  Set up the top level converter.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10.2
+		 *  @playerversion AIR 2.6
+		 *  @productversion FlexJS 0.0
+		 */
+		public static function removeAllConverters(target:DisplayObject):void
+		{
+			captureTarget = target;
+			for each (var eventType:String in captureConvertedEvents)
+				target.removeEventListener(eventType, eventHandler, true);
+		}
+		
+        /**
+         *  Add another event to convert.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 10.2
+         *  @playerversion AIR 2.6
+         *  @productversion FlexJS 0.0
+         */
+        public static function addEventType(type:String):void
+        {
+			if (!captureTarget)
+				captureConvertedEvents.push(type);
+			else
+                captureTarget.addEventListener(type, eventHandler, false, 9999);
+        }
+		
+		private static function focusEventConverter(e:flash.events.FocusEvent):flex.events.FocusEvent
+		{
+			return new flex.events.FocusEvent(e.type, e.bubbles, e.cancelable, e.relatedObject as flex.display.InteractiveObject, e.shiftKey, e.keyCode);
+		}
+		
+		private static function eventConverter(e:flash.events.Event):flex.events.Event
+		{
+			return new flex.events.Event(e.type, e.bubbles, e.cancelable);
+		}
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/aaa01ca6/frameworks/projects/MX/src/main/flex/mx/core/Application.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/MX/src/main/flex/mx/core/Application.as b/frameworks/projects/MX/src/main/flex/mx/core/Application.as
index 431e56b..4cfb16a 100644
--- a/frameworks/projects/MX/src/main/flex/mx/core/Application.as
+++ b/frameworks/projects/MX/src/main/flex/mx/core/Application.as
@@ -49,6 +49,8 @@ import mx.managers.FocusManager;
 import mx.managers.IActiveWindowManager;
 import mx.managers.ILayoutManager;
 import mx.managers.ISystemManager;
+// force-link this here. In flex-sdk, it gets dragged in by Effect.
+import mx.managers.LayoutManager; LayoutManager; 
 import mx.styles.CSSStyleDeclaration;
 import mx.styles.IStyleClient;
 import mx.utils.LoaderUtil;
@@ -1048,16 +1050,8 @@ public class Application extends LayoutContainer
 
         var sm:ISystemManager = systemManager;
         
-		COMPILE::SWF
-		{
-	        _url = LoaderUtil.normalizeURL(root.loaderInfo);
-	        _parameters = root.loaderInfo.parameters;
-		}
-		COMPILE::JS
-		{
-			_url = LoaderUtil.normalizeURL(window.location.href);
-			_parameters = makeParameters(window.location.search);			
-		}
+        _url = LoaderUtil.normalizeURL(sm.moduleInfo);
+        _parameters = sm.moduleInfo.parameters;
 		
         initManagers(sm);
         _descriptor = null;
@@ -1884,22 +1878,6 @@ public class Application extends LayoutContainer
         invalidateDisplayList();      
     }
 	
-	COMPILE::JS
-	private function makeParameters(url:String):Object
-	{
-		if (url == null || url.length == 0)
-			return {};
-		
-		url = url.substring(1); // remove leading ?
-		var parts:Array = url.split("&");
-		var parms:Object = {};
-		for each (var part:String in parts)
-		{
-			var subParts:Array = part.split("=");
-			parms[subParts[0]] = subParts[1];
-		}
-		return parms;
-	}
 }
 
 }

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/aaa01ca6/frameworks/projects/MX/src/main/flex/mx/core/UIComponent.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/MX/src/main/flex/mx/core/UIComponent.as b/frameworks/projects/MX/src/main/flex/mx/core/UIComponent.as
index bf66b1e..6fe7bff 100644
--- a/frameworks/projects/MX/src/main/flex/mx/core/UIComponent.as
+++ b/frameworks/projects/MX/src/main/flex/mx/core/UIComponent.as
@@ -14964,6 +14964,18 @@ public class UIComponent extends Sprite
 		return NameUtil.displayObjectToString(this);
 	}	
 
+	COMPILE::SWF
+	override public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
+	{
+		super.addEventListener(type, listener, useCapture, priority, useWeakReference);
+		super.addEventListener(type, flashListener, true, 9999);
+	}
+	
+	COMPILE::SWF
+	private function flashListener(e:flash.events.Event):void
+	{
+		trace(e.type, e.target);
+	}
 }
 
 }

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/aaa01ca6/frameworks/projects/MX/src/main/flex/mx/managers/LayoutManager.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/MX/src/main/flex/mx/managers/LayoutManager.as b/frameworks/projects/MX/src/main/flex/mx/managers/LayoutManager.as
new file mode 100644
index 0000000..066dc50
--- /dev/null
+++ b/frameworks/projects/MX/src/main/flex/mx/managers/LayoutManager.as
@@ -0,0 +1,1259 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 mx.managers
+{
+COMPILE::SWF
+{
+import flash.display.Stage;
+import flash.events.Event;
+import flash.events.EventDispatcher;
+}
+COMPILE::JS
+{
+	import flex.events.Event;
+	import org.apache.flex.events.EventDispatcher;
+}
+
+import mx.core.ILayoutElement;
+import mx.core.UIComponent;
+import mx.core.UIComponentGlobals;
+import mx.core.mx_internal;
+import mx.events.DynamicEvent;
+import mx.events.FlexEvent;
+import mx.managers.layoutClasses.PriorityQueue;
+
+CONFIG::performanceInstrumentation
+{
+import mx.utils.PerfUtil; 
+}
+
+use namespace mx_internal;
+
+/**
+ *  The LayoutManager is the engine behind
+ *  Flex's measurement and layout strategy.
+ *  Layout is performed in three phases; commit, measurement, and layout.
+ *
+ *  <p>Each phase is distinct from the others and all UIComponents of
+ *  one phase are processed prior to moving on to the next phase.
+ *  During the processing of UIComponents in a phase, requests for
+ *  UIComponents to get re-processed by some phase may occur.
+ *  These requests are queued and are only processed
+ *  during the next run of the phase.</p>
+ *
+ *  <p>The <b>commit</b> phase begins with a call to
+ *  <code>validateProperties()</code>, which walks through a list
+ *  (reverse sorted by nesting level) of objects calling each object's
+ *  <a href="../core/UIComponent.html#validateProperties()">
+ *  <code>validateProperties()</code></a>method.</p>
+ *
+ *  <p>The objects in the list are processed in reversed nesting order,
+ *  with the <b>least</b> deeply nested object accessed first.
+ *  This can also be referred to as top-down or outside-in ordering.</p>
+ *
+ *  <p>This phase allows components whose contents depend on property
+ *  settings to configure themselves prior to the measurement
+ *  and the layout phases.
+ *  For the sake of performance, sometimes a component's property setter
+ *  method does not do all the work to update to the new property value.
+ *  Instead, the property setter calls the <code>invalidateProperties()</code>
+ *  method, deferring the work until this phase runs.
+ *  This prevents unnecessary work if the property is set multiple times.</p>
+ *
+ *  <p>The <b>measurement</b> phase begins with a call to
+ *  <code>validateSize()</code>, which walks through a list
+ *  (sorted by nesting level) of objects calling each object's
+ *  <a href="../core/UIComponent.html#validateSize()"><code>validateSize()</code></a>
+ *  method to determine if the object has changed in size.</p>
+ *
+ *  <p>If an object's <a href="../core/UIComponent.html#invalidateSize()">
+ *  <code>invalidateSize()</code></a> method was previously called,
+ *  then the <code>validateSize()</code> method is called.
+ *  If the size or position of the object was changed as a result of the
+ *  <code>validateSize()</code> call, then the object's
+ *  <a href="../core/UIComponent.html#invalidateDisplayList()">
+ *  <code>invalidateDisplayList()</code></a> method is called, thus adding
+ *  the object to the processing queue for the next run of the layout phase.
+ *  Additionally, the object's parent is marked for both measurement
+ *  and layout phases, by calling
+ *  <a href="../core/UIComponent.html#invalidateSize()">
+ *  <code>invalidateSize()</code></a> and
+ *  <a href="../core/UIComponent.html#invalidateDisplayList()">
+ *  <code>invalidateDisplayList()</code></a> respectively.</p>
+ *
+ *  <p>The objects in the list are processed by nesting order,
+ *  with the <b>most</b> deeply nested object accessed first.
+ *  This can also be referred to as bottom-up inside-out ordering.</p>
+ *
+ *  <p>The <b>layout</b> phase begins with a call to the 
+ *  <code>validateDisplayList()</code> method, which walks through a list
+ *  (reverse sorted by nesting level) of objects calling each object's
+ *  <a href="../core/UIComponent.html#validateDisplayList()">
+ *  <code>validateDisplayList()</code></a> method to request the object to size
+ *  and position all components contained within it (i.e. its children).</p>
+ *
+ *  <p>If an object's <a href="../core/UIComponent.html#invalidateDisplayList()">
+ *  <code>invalidateDisplayList()</code></a> method was previously called,
+ *  then <code>validateDisplayList()</code> method for the object is called.</p>
+ *
+ *  <p>The objects in the list are processed in reversed nesting order,
+ *  with the <b>least</b> deeply nested object accessed first.
+ *  This can also be referred to as top-down or outside-in ordering.</p>
+ *
+ *  <p>In general, components do not override the <code>validateProperties()</code>, 
+ *  <code>validateSize()</code>, or <code>validateDisplayList()</code> methods.  
+ *  In the case of UIComponents, most components override the 
+ *  <code>commitProperties()</code>, <code>measure()</code>, or 
+ *  <code>updateDisplayList()</code> methods, which are called
+ *  by the <code>validateProperties()</code>, 
+ *  <code>validateSize()</code>, or 
+ *  <code>validateDisplayList()</code> methods, respectively.</p>
+ *
+ *  <p>At application startup, a single instance of the LayoutManager is created
+ *  and stored in the <code>UIComponent.layoutManager</code> property.  
+ *  All components are expected to use that instance.  
+ *  If you do not have access to the UIComponent object, 
+ *  you can also access the LayoutManager using the static 
+ *  <code>LayoutManager.getInstance()</code> method.</p>
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
+ */
+public class LayoutManager extends EventDispatcher implements ILayoutManager
+{
+    include "../core/Version.as";
+
+    //--------------------------------------------------------------------------
+    //
+    //  Class variables
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  The sole instance of this singleton class.
+     */
+    private static var instance:LayoutManager;
+
+    //--------------------------------------------------------------------------
+    //
+    //  Class methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Returns the sole instance of this singleton class,
+     *  creating it if it does not already exist.
+         *
+         *  @return Returns the sole instance of this singleton class,
+     *  creating it if it does not already exist.
+         *  
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+    public static function getInstance():LayoutManager
+    {
+        if (!instance)
+            instance = new LayoutManager();
+
+        return instance;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Constructor.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     *  @private
+     */
+    public function LayoutManager()
+    {
+        super();
+
+        systemManager = SystemManagerGlobals.topLevelSystemManagers[0];
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  A queue of objects that need to dispatch updateComplete events
+     *  when invalidation processing is complete
+     */
+    private var updateCompleteQueue:PriorityQueue = new PriorityQueue();
+
+    /**
+     *  @private
+     *  A queue of objects to be processed during the first phase
+     *  of invalidation processing, when an ILayoutManagerClient  has
+     *  its validateProperties() method called (which in a UIComponent
+     *  calls commitProperties()).
+     *  Objects are added to this queue by invalidateProperties()
+     *  and removed by validateProperties().
+     */
+    private var invalidatePropertiesQueue:PriorityQueue = new PriorityQueue();
+
+    /**
+     *  @private
+     *  A flag indicating whether there are objects
+     *  in the invalidatePropertiesQueue.
+     *  It is set true by invalidateProperties()
+     *  and set false by validateProperties().
+     */
+    private var invalidatePropertiesFlag:Boolean = false;
+
+    // flag when in validateClient to check the properties queue again
+    private var invalidateClientPropertiesFlag:Boolean = false;
+
+    /**
+     *  @private
+     *  A queue of objects to be processed during the second phase
+     *  of invalidation processing, when an ILayoutManagerClient  has
+     *  its validateSize() method called (which in a UIComponent
+     *  calls measure()).
+     *  Objects are added to this queue by invalidateSize().
+     *  and removed by validateSize().
+     */
+    private var invalidateSizeQueue:PriorityQueue = new PriorityQueue();
+
+    /**
+     *  @private
+     *  A flag indicating whether there are objects
+     *  in the invalidateSizeQueue.
+     *  It is set true by invalidateSize()
+     *  and set false by validateSize().
+     */
+    private var invalidateSizeFlag:Boolean = false;
+
+    // flag when in validateClient to check the size queue again
+    private var invalidateClientSizeFlag:Boolean = false;
+
+    /**
+     *  @private
+     *  A queue of objects to be processed during the third phase
+     *  of invalidation processing, when an ILayoutManagerClient  has
+     *  its validateDisplayList() method called (which in a
+     *  UIComponent calls updateDisplayList()).
+     *  Objects are added to this queue by invalidateDisplayList()
+     *  and removed by validateDisplayList().
+     */
+    private var invalidateDisplayListQueue:PriorityQueue = new PriorityQueue();
+
+    /**
+     *  @private
+     *  A flag indicating whether there are objects
+     *  in the invalidateDisplayListQueue.
+     *  It is set true by invalidateDisplayList()
+     *  and set false by validateDisplayList().
+     */
+    private var invalidateDisplayListFlag:Boolean = false;
+
+    /**
+     *  @private
+     */
+    private var waitedAFrame:Boolean = false;
+
+    /**
+     *  @private
+     */
+    private var listenersAttached:Boolean = false;
+
+    /**
+     *  @private
+     */
+    private var originalFrameRate:Number;
+
+    /**
+     *  @private
+     *  used in validateClient to quickly estimate whether we have to
+     *  search the queues again
+     */
+    private var targetLevel:int = int.MAX_VALUE;
+
+    /**
+     *  @private
+     *  the top level systemmanager
+     */
+    private var systemManager:ISystemManager;
+
+	/**
+	 *  @private
+	 *  the current object being validated
+	 *  it could be wrong if the validating object calls validateNow on something.
+	 */
+	private var currentObject:ILayoutManagerClient;
+	
+    //--------------------------------------------------------------------------
+    //
+    //  Properties
+    //
+    //--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  usePhasedInstantiation
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the usePhasedInstantiation property.
+     */
+    private var _usePhasedInstantiation:Boolean = false;
+
+    /**
+     *  A flag that indicates whether the LayoutManager allows screen updates
+     *  between phases.
+     *  If <code>true</code>, measurement and layout are done in phases, one phase
+     *  per screen update.
+     *  All components have their <code>validateProperties()</code> 
+     *  and <code>commitProperties()</code> methods 
+     *  called until all their properties are validated.  
+     *  The screen will then be updated.  
+     * 
+     *  <p>Then all components will have their <code>validateSize()</code> 
+     *  and <code>measure()</code>
+     *  methods called until all components have been measured, then the screen
+     *  will be updated again.  </p>
+     *
+     *  <p>Finally, all components will have their
+     *  <code>validateDisplayList()</code> and 
+     *  <code>updateDisplayList()</code> methods called until all components
+     *  have been validated, and the screen will be updated again.  
+     *  If in the validation of one phase, an earlier phase gets invalidated, 
+     *  the LayoutManager starts over.  
+     *  This is more efficient when large numbers of components
+     *  are being created an initialized.  The framework is responsible for setting
+     *  this property.</p>
+     *
+     *  <p>If <code>false</code>, all three phases are completed before the screen is updated.</p>
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function get usePhasedInstantiation():Boolean
+    {
+        return _usePhasedInstantiation;
+    }
+
+    /**
+     *  @private
+     */
+    public function set usePhasedInstantiation(value:Boolean):void
+    {
+        if (_usePhasedInstantiation != value)
+        {
+            _usePhasedInstantiation = value;
+
+            // While we're doing phased instantiation, temporarily increase
+            // the frame rate.  That will cause the enterFrame and render
+            // events to fire more promptly, which improves performance.
+			COMPILE::SWF
+			{
+            try {
+                // can't use FlexGlobals here.  It may not be setup yet
+                var stage:Stage = systemManager.stage;
+                if (stage)
+                {
+                    if (value)
+                    {
+                        originalFrameRate = stage.frameRate;
+                        stage.frameRate = 1000;
+                    }
+                    else
+                    {
+                        stage.frameRate = originalFrameRate;
+                    }
+                }
+            }
+            catch (e:SecurityError)
+            {
+                // trace("ignoring security error changing the framerate " + e);
+            }
+			}
+        }
+    }
+
+    //----------------------------------
+    //  debugHelper
+    //----------------------------------
+    
+    /* 
+    // LAYOUT_DEBUG
+    import mx.managers.layoutClasses.LayoutDebugHelper;
+    private static var _layoutDebugHelper:LayoutDebugHelper;
+    
+    public static function get debugHelper():LayoutDebugHelper
+    {
+        if (!_layoutDebugHelper)
+        {
+            _layoutDebugHelper = new LayoutDebugHelper();
+            _layoutDebugHelper.mouseEnabled = false;
+            var sm:ISystemManager = SystemManagerGlobals.topLevelSystemManagers[0]
+            sm.addChild(_layoutDebugHelper);
+        }
+        return _layoutDebugHelper;
+    } */
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Methods: Invalidation
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Adds an object to the list of components that want their 
+     *  <code>validateProperties()</code> method called.
+     *  A component should call this method when a property changes.  
+     *  Typically, a property setter method
+     *  stores a the new value in a temporary variable and calls 
+     *  the <code>invalidateProperties()</code> method 
+     *  so that its <code>validateProperties()</code> 
+     *  and <code>commitProperties()</code> methods are called
+     *  later, when the new value will actually be applied to the component and/or
+     *  its children.  The advantage of this strategy is that often, more than one
+     *  property is changed at a time and the properties may interact with each
+     *  other, or repeat some code as they are applied, or need to be applied in
+     *  a specific order.  This strategy allows the most efficient method of
+     *  applying new property values.
+     *
+     *  @param obj The object whose property changed.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function invalidateProperties(obj:ILayoutManagerClient ):void
+    {
+        if (!invalidatePropertiesFlag && systemManager)
+        {
+            invalidatePropertiesFlag = true;
+
+            if (!listenersAttached)
+                attachListeners(systemManager);
+        }
+
+        // trace("LayoutManager adding " + Object(obj) + " to invalidatePropertiesQueue");
+
+        if (targetLevel <= obj.nestLevel)
+            invalidateClientPropertiesFlag = true;
+
+        invalidatePropertiesQueue.addObject(obj, obj.nestLevel);
+
+        // trace("LayoutManager added " + Object(obj) + " to invalidatePropertiesQueue");
+    }
+
+    /**
+     *  Adds an object to the list of components that want their 
+     *  <code>validateSize()</code> method called.
+     *  Called when an object's size changes.
+     *
+     *  <p>An object's size can change for two reasons:</p>
+     *
+     *  <ol>
+     *    <li>The content of the object changes. For example, the size of a
+     *    button changes when its <code>label</code> is changed.</li>
+     *    <li>A script explicitly changes one of the following properties:
+     *    <code>minWidth</code>, <code>minHeight</code>,
+     *    <code>explicitWidth</code>, <code>explicitHeight</code>,
+     *    <code>maxWidth</code>, or <code>maxHeight</code>.</li>
+     *  </ol>
+     *
+     *  <p>When the first condition occurs, it's necessary to recalculate
+     *  the measurements for the object.
+     *  When the second occurs, it's not necessary to recalculate the
+     *  measurements because the new size of the object is known.
+     *  However, it's necessary to remeasure and relayout the object's
+     *  parent.</p>
+     *
+     *  @param obj The object whose size changed.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function invalidateSize(obj:ILayoutManagerClient ):void
+    {
+        if (!invalidateSizeFlag && systemManager)
+        {
+            invalidateSizeFlag = true;
+
+            if (!listenersAttached)
+            {
+                attachListeners(systemManager);
+            }
+        }
+
+        // trace("LayoutManager adding " + Object(obj) + " to invalidateSizeQueue");
+
+        if (targetLevel <= obj.nestLevel)
+            invalidateClientSizeFlag = true;
+
+        invalidateSizeQueue.addObject(obj, obj.nestLevel);
+
+        // trace("LayoutManager added " + Object(obj) + " to invalidateSizeQueue");
+    }
+
+    /**
+     *  Called when a component changes in some way that its layout and/or visuals
+     *  need to be changed.
+     *  In that case, it is necessary to run the component's layout algorithm,
+     *  even if the component's size hasn't changed.  For example, when a new child component
+     *  is added, or a style property changes or the component has been given
+     *  a new size by its parent.
+     *
+     *  @param obj The object that changed.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function invalidateDisplayList(obj:ILayoutManagerClient ):void
+    {
+        if (!invalidateDisplayListFlag && systemManager)
+        {
+            invalidateDisplayListFlag = true;
+
+            if (!listenersAttached)
+            {
+                attachListeners(systemManager);
+            }
+        }
+        else if (!invalidateDisplayListFlag && !systemManager)
+        {
+            // trace("systemManager is null");
+        }
+
+        // trace("LayoutManager adding " + Object(obj) + " to invalidateDisplayListQueue");
+
+        invalidateDisplayListQueue.addObject(obj, obj.nestLevel);
+
+        // trace("LayoutManager added " + Object(obj) + " to invalidateDisplayListQueue");
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Methods: Commitment, measurement, layout, and drawing
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Validates all components whose properties have changed and have called
+     *  the <code>invalidateProperties()</code> method.  
+     *  It calls the <code>validateProperties()</code> method on those components
+     *  and will call <code>validateProperties()</code> on any other components that are 
+     *  invalidated while validating other components.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    private function validateProperties():void
+    {
+        // trace("--- LayoutManager: validateProperties --->");
+        CONFIG::performanceInstrumentation
+        {
+            var perfUtil:PerfUtil = PerfUtil.getInstance();
+            perfUtil.markTime("validateProperties().start");
+        }
+
+        // Keep traversing the invalidatePropertiesQueue until we've reached the end.
+        // More elements may get added to the queue while we're in this loop, or a
+        // a recursive call to this function may remove elements from the queue while
+        // we're in this loop.
+        var obj:ILayoutManagerClient = ILayoutManagerClient(invalidatePropertiesQueue.removeSmallest());
+        while (obj)
+        {
+            // trace("LayoutManager calling validateProperties() on " + Object(obj) + " " + DisplayObject(obj).width + " " + DisplayObject(obj).height);
+
+            CONFIG::performanceInstrumentation
+            {
+                var token:int = perfUtil.markStart();
+            }
+            
+			if (obj.nestLevel)
+			{
+				currentObject = obj;
+	            obj.validateProperties();
+	            if (!obj.updateCompletePendingFlag)
+	            {
+	                updateCompleteQueue.addObject(obj, obj.nestLevel);
+	                obj.updateCompletePendingFlag = true;
+	            }
+			}            
+            CONFIG::performanceInstrumentation
+            {
+                perfUtil.markEnd(".validateProperties()", token, 2 /*tolerance*/, obj);
+            }
+
+            // Once we start, don't stop.
+            obj = ILayoutManagerClient(invalidatePropertiesQueue.removeSmallest());
+        }
+
+        if (invalidatePropertiesQueue.isEmpty())
+        {
+            // trace("Properties Queue is empty");
+
+            invalidatePropertiesFlag = false;
+        }
+
+        // trace("<--- LayoutManager: validateProperties ---");
+        CONFIG::performanceInstrumentation
+        {
+            perfUtil.markTime("validateProperties().end");
+        }
+    }
+
+    /**
+     *  Validates all components whose properties have changed and have called
+     *  the <code>invalidateSize()</code> method.  
+     *  It calls the <code>validateSize()</code> method on those components
+     *  and will call the <code>validateSize()</code> method 
+     *  on any other components that are 
+     *  invalidated while validating other components.  
+     *  The </code>validateSize()</code> method  starts with
+     *  the most deeply nested child in the tree of display objects
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    private function validateSize():void
+    {
+        // trace("--- LayoutManager: validateSize --->");
+        CONFIG::performanceInstrumentation
+        {
+            var perfUtil:PerfUtil = PerfUtil.getInstance();
+            perfUtil.markTime("validateSize().start");
+        }
+
+        var obj:ILayoutManagerClient = ILayoutManagerClient(invalidateSizeQueue.removeLargest());
+        while (obj)
+        {
+            // trace("LayoutManager calling validateSize() on " + Object(obj));
+            CONFIG::performanceInstrumentation
+            {
+                var objToken:int;
+                if (PerfUtil.detailedSampling)
+                    objToken = perfUtil.markStart();
+            }
+            
+			if (obj.nestLevel)
+			{
+				currentObject = obj;
+		        obj.validateSize();
+		        if (!obj.updateCompletePendingFlag)
+		        {
+		            updateCompleteQueue.addObject(obj, obj.nestLevel);
+		            obj.updateCompletePendingFlag = true;
+		        }
+			}
+
+            CONFIG::performanceInstrumentation
+            {
+                if (PerfUtil.detailedSampling)
+                    perfUtil.markEnd(".validateSize()", objToken, 2 /*tolerance*/, obj);
+            }
+            // trace("LayoutManager validateSize: " + Object(obj) + " " + IFlexDisplayObject(obj).measuredWidth + " " + IFlexDisplayObject(obj).measuredHeight);
+
+            obj = ILayoutManagerClient(invalidateSizeQueue.removeLargest());
+        }
+
+        if (invalidateSizeQueue.isEmpty())
+        {
+            // trace("Measurement Queue is empty");
+
+            invalidateSizeFlag = false;
+        }
+
+        CONFIG::performanceInstrumentation
+        {
+            perfUtil.markTime("validateSize().end");
+        }
+        // trace("<--- LayoutManager: validateSize ---");
+    }
+
+    /**
+     *  Validates all components whose properties have changed and have called
+     *  the <code>invalidateDisplayList()</code> method.  
+     *  It calls <code>validateDisplayList()</code> method on those components
+     *  and will call the <code>validateDisplayList()</code> method 
+     *  on any other components that are 
+     *  invalidated while validating other components.  
+     *  The <code>validateDisplayList()</code> method starts with
+     *  the least deeply nested child in the tree of display objects
+     *
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    private function validateDisplayList():void
+    {
+        // trace("--- LayoutManager: validateDisplayList --->");        
+        CONFIG::performanceInstrumentation
+        {
+            var perfUtil:PerfUtil = PerfUtil.getInstance();
+            perfUtil.markTime("validateDisplayList().start");
+        }
+
+        var obj:ILayoutManagerClient = ILayoutManagerClient(invalidateDisplayListQueue.removeSmallest());
+        while (obj)
+        {
+            // trace("LayoutManager calling validateDisplayList on " + Object(obj) + " " + DisplayObject(obj).width + " " + DisplayObject(obj).height);
+            CONFIG::performanceInstrumentation
+            {
+                var objToken:int;
+                if (PerfUtil.detailedSampling)
+                    objToken = perfUtil.markStart();
+            }
+            
+			if (obj.nestLevel)
+			{
+				currentObject = obj;
+	            obj.validateDisplayList();
+	            if (!obj.updateCompletePendingFlag)
+	            {
+	                updateCompleteQueue.addObject(obj, obj.nestLevel);
+	                obj.updateCompletePendingFlag = true;
+	            }
+			}
+            // trace("LayoutManager return from validateDisplayList on " + Object(obj) + " " + DisplayObject(obj).width + " " + DisplayObject(obj).height);
+            
+            CONFIG::performanceInstrumentation
+            {
+                if (PerfUtil.detailedSampling)
+                    perfUtil.markEnd(".validateDisplayList()", objToken, 2 /*tolerance*/, obj);
+            }
+
+            // Once we start, don't stop.
+            obj = ILayoutManagerClient(invalidateDisplayListQueue.removeSmallest());
+        }
+
+
+        if (invalidateDisplayListQueue.isEmpty())
+        {
+            // trace("Layout Queue is empty");
+
+            invalidateDisplayListFlag = false;
+        }
+
+        CONFIG::performanceInstrumentation
+        {
+            perfUtil.markTime("validateDisplayList().end");
+        }
+        // trace("<--- LayoutManager: validateDisplayList ---");
+    }
+
+    /**
+     *  @private
+     */
+    private function doPhasedInstantiation():void
+    {
+        // trace(">>DoPhasedInstantation");
+
+        // If phasing, do only one phase: validateProperties(),
+        // validateSize(), or validateDisplayList().
+        if (usePhasedInstantiation)
+        {
+            if (invalidatePropertiesFlag)
+            {
+                validateProperties();
+
+                // The Preloader listens for this event.
+                systemManager.document.dispatchEvent(
+                    new Event("validatePropertiesComplete"));
+            }
+
+            else if (invalidateSizeFlag)
+            {
+                validateSize();
+
+                // The Preloader listens for this event.
+                systemManager.document.dispatchEvent(
+                    new Event("validateSizeComplete"));
+            }
+
+            else if (invalidateDisplayListFlag)
+            {
+                validateDisplayList();
+
+                // The Preloader listens for this event.
+                systemManager.document.dispatchEvent(
+                    new Event("validateDisplayListComplete"));
+            }
+        }
+
+        // Otherwise, do one pass of all three phases.
+        else
+        {
+            if (invalidatePropertiesFlag)
+                validateProperties();
+
+            if (invalidateSizeFlag)
+                validateSize();
+
+            if (invalidateDisplayListFlag)
+                validateDisplayList();
+        }
+
+        // trace("invalidatePropertiesFlag " + invalidatePropertiesFlag);
+        // trace("invalidateSizeFlag " + invalidateSizeFlag);
+        // trace("invalidateDisplayListFlag " + invalidateDisplayListFlag);
+
+        if (invalidatePropertiesFlag ||
+            invalidateSizeFlag ||
+            invalidateDisplayListFlag)
+        {
+            attachListeners(systemManager);
+        }
+        else
+        {
+            usePhasedInstantiation = false;
+
+			listenersAttached = false;
+
+			var obj:ILayoutManagerClient = ILayoutManagerClient(updateCompleteQueue.removeLargest());
+            while (obj)
+            {
+                if (!obj.initialized && obj.processedDescriptors)
+                    obj.initialized = true;
+                if (obj.hasEventListener(FlexEvent.UPDATE_COMPLETE))
+                    obj.dispatchEvent(new FlexEvent(FlexEvent.UPDATE_COMPLETE));
+                obj.updateCompletePendingFlag = false;
+                obj = ILayoutManagerClient(updateCompleteQueue.removeLargest());
+            }
+
+            // trace("updateComplete");
+
+            dispatchEvent(new FlexEvent(FlexEvent.UPDATE_COMPLETE));
+        }
+
+        // trace("<<DoPhasedInstantation");
+    }
+
+    /**
+     *  When properties are changed, components generally do not apply those changes immediately.
+     *  Instead the components usually call one of the LayoutManager's invalidate methods and
+     *  apply the properties at a later time.  The actual property you set can be read back
+     *  immediately, but if the property affects other properties in the component or its
+     *  children or parents, those other properties may not be immediately updated.  To
+     *  guarantee that the values are updated, you can call the <code>validateNow()</code> method.  
+     *  It updates all properties in all components before returning.  
+     *  Call this method only when necessary as it is a computationally intensive call.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function validateNow():void
+    {
+        if (!usePhasedInstantiation)
+        {
+            var infiniteLoopGuard:int = 0;
+            while (listenersAttached && infiniteLoopGuard++ < 100)
+                doPhasedInstantiation();
+        }
+    }
+
+    /**
+     *  When properties are changed, components generally do not apply those changes immediately.
+     *  Instead the components usually call one of the LayoutManager's invalidate methods and
+     *  apply the properties at a later time.  The actual property you set can be read back
+     *  immediately, but if the property affects other properties in the component or its
+     *  children or parents, those other properties may not be immediately updated.  
+     *
+     *  <p>To guarantee that the values are updated, 
+     *  you can call the <code>validateClient()</code> method.  
+     *  It updates all properties in all components whose nest level is greater than or equal
+     *  to the target component before returning.  
+     *  Call this method only when necessary as it is a computationally intensive call.</p>
+     *
+     *  @param target The component passed in is used to test which components
+     *  should be validated.  All components contained by this component will have their
+     *  <code>validateProperties()</code>, <code>commitProperties()</code>, 
+     *  <code>validateSize()</code>, <code>measure()</code>, 
+     *  <code>validateDisplayList()</code>, 
+     *  and <code>updateDisplayList()</code> methods called.
+     *
+     *    @param skipDisplayList If <code>true</code>, 
+     *  does not call the <code>validateDisplayList()</code> 
+     *  and <code>updateDisplayList()</code> methods.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function validateClient(target:ILayoutManagerClient, skipDisplayList:Boolean = false):void
+    {
+        CONFIG::performanceInstrumentation
+        {
+            var perfUtil:PerfUtil = PerfUtil.getInstance();
+            var token:int = perfUtil.markStart();
+        }
+
+		var lastCurrentObject:ILayoutManagerClient = currentObject;
+		
+        var obj:ILayoutManagerClient;
+        var i:int = 0;
+        var done:Boolean = false;
+        var oldTargetLevel:int = targetLevel;
+
+        // the theory here is that most things that get validated are deep in the tree
+        // and so there won't be nested calls to validateClient.  However if there is,
+        // we don't want to have a more sophisticated scheme of keeping track
+        // of dirty flags at each level that is being validated, but we definitely
+        // do not want to keep scanning the queues unless we're pretty sure that
+        // something might be dirty so we just say that if something got dirty
+        // during this call at a deeper nesting than the first call to validateClient
+        // then we'll scan the queues.  So we only change targetLevel if we're the
+        // outer call to validateClient and only that call restores it.
+        if (targetLevel == int.MAX_VALUE)
+            targetLevel = target.nestLevel;
+
+        // trace("--- LayoutManager: validateClient ---> target = " + target);
+
+        while (!done)
+        {
+            // assume we won't find anything
+            done = true;
+
+            // Keep traversing the invalidatePropertiesQueue until we've reached the end.
+            // More elements may get added to the queue while we're in this loop, or a
+            // a recursive call to this function may remove elements from the queue while
+            // we're in this loop.
+            obj = ILayoutManagerClient(invalidatePropertiesQueue.removeSmallestChild(target));
+            while (obj)
+            {
+                // trace("LayoutManager calling validateProperties() on " + Object(obj) + " " + DisplayObject(obj).width + " " + DisplayObject(obj).height);
+
+				if (obj.nestLevel)
+				{
+					currentObject = obj;
+	                obj.validateProperties();
+	                if (!obj.updateCompletePendingFlag)
+	                {
+	                    updateCompleteQueue.addObject(obj, obj.nestLevel);
+	                    obj.updateCompletePendingFlag = true;
+	                }
+				}
+				
+                // Once we start, don't stop.
+                obj = ILayoutManagerClient(invalidatePropertiesQueue.removeSmallestChild(target));
+            }
+
+            if (invalidatePropertiesQueue.isEmpty())
+            {
+                // trace("Properties Queue is empty");
+
+                invalidatePropertiesFlag = false;
+                invalidateClientPropertiesFlag = false;
+            }
+            
+            // trace("--- LayoutManager: validateSize --->");
+
+            obj = ILayoutManagerClient(invalidateSizeQueue.removeLargestChild(target));
+            while (obj)
+            {
+                // trace("LayoutManager calling validateSize() on " + Object(obj));
+
+				if (obj.nestLevel)
+				{
+					currentObject = obj;
+	                obj.validateSize();
+	                if (!obj.updateCompletePendingFlag)
+	                {
+	                    updateCompleteQueue.addObject(obj, obj.nestLevel);
+	                    obj.updateCompletePendingFlag = true;
+	                }
+				}
+
+                // trace("LayoutManager validateSize: " + Object(obj) + " " + IFlexDisplayObject(obj).measuredWidth + " " + IFlexDisplayObject(obj).measuredHeight);
+                
+                if (invalidateClientPropertiesFlag)
+                {
+                    // did any properties get invalidated while validating size?
+                    obj = ILayoutManagerClient(invalidatePropertiesQueue.removeSmallestChild(target));
+                    if (obj)
+                    {
+                        // re-queue it. we'll pull it at the beginning of the loop
+                        invalidatePropertiesQueue.addObject(obj, obj.nestLevel);
+                        done = false;
+                        break;
+                    }
+                }
+                
+                obj = ILayoutManagerClient(invalidateSizeQueue.removeLargestChild(target));
+            }
+
+            if (invalidateSizeQueue.isEmpty())
+            {
+                // trace("Measurement Queue is empty");
+
+                invalidateSizeFlag = false;
+                invalidateClientSizeFlag = false;
+            }
+
+            if (!skipDisplayList)
+            {
+                // trace("--- LayoutManager: validateDisplayList --->");
+
+                obj = ILayoutManagerClient(invalidateDisplayListQueue.removeSmallestChild(target));
+                while (obj)
+                {
+                    // trace("LayoutManager calling validateDisplayList on " + Object(obj) + " " + DisplayObject(obj).width + " " + DisplayObject(obj).height);
+
+					if (obj.nestLevel)
+					{
+						currentObject = obj;
+	                    obj.validateDisplayList();
+	                    if (!obj.updateCompletePendingFlag)
+	                    {
+	                        updateCompleteQueue.addObject(obj, obj.nestLevel);
+	                        obj.updateCompletePendingFlag = true;
+	                    }
+					}
+                    // trace("LayoutManager return from validateDisplayList on " + Object(obj) + " " + DisplayObject(obj).width + " " + DisplayObject(obj).height);
+
+                    if (invalidateClientPropertiesFlag)
+                    {
+                        // did any properties get invalidated while validating size?
+                        obj = ILayoutManagerClient(invalidatePropertiesQueue.removeSmallestChild(target));
+                        if (obj)
+                        {
+                            // re-queue it. we'll pull it at the beginning of the loop
+                            invalidatePropertiesQueue.addObject(obj, obj.nestLevel);
+                            done = false;
+                            break;
+                        }
+                    }
+
+                    if (invalidateClientSizeFlag)
+                    {
+                        obj = ILayoutManagerClient(invalidateSizeQueue.removeLargestChild(target));
+                        if (obj)
+                        {
+                            // re-queue it. we'll pull it at the beginning of the loop
+                            invalidateSizeQueue.addObject(obj, obj.nestLevel);
+                            done = false;
+                            break;
+                        }
+                    }
+
+                    // Once we start, don't stop.
+                    obj = ILayoutManagerClient(invalidateDisplayListQueue.removeSmallestChild(target));
+                }
+
+
+                if (invalidateDisplayListQueue.isEmpty())
+                {
+                    // trace("Layout Queue is empty");
+
+                    invalidateDisplayListFlag = false;
+                }
+            }
+        }
+
+        if (oldTargetLevel == int.MAX_VALUE)
+        {
+            targetLevel = int.MAX_VALUE;
+            if (!skipDisplayList)
+            {
+                obj = ILayoutManagerClient(updateCompleteQueue.removeLargestChild(target));
+                while (obj)
+                {
+                    if (!obj.initialized)
+                        obj.initialized = true;
+                    
+                    if (obj.hasEventListener(FlexEvent.UPDATE_COMPLETE))
+                        obj.dispatchEvent(new FlexEvent(FlexEvent.UPDATE_COMPLETE));
+                    obj.updateCompletePendingFlag = false;
+                    obj = ILayoutManagerClient(updateCompleteQueue.removeLargestChild(target));
+                }
+            }
+        }
+
+		currentObject = lastCurrentObject;
+		
+        CONFIG::performanceInstrumentation
+        {
+            perfUtil.markEnd(" validateClient()", token, 2 /*tolerance*/, target);
+        }
+		
+        // trace("<--- LayoutManager: validateClient --- target = " + target);
+    }
+
+    /**
+     *  Returns <code>true</code> if there are components that need validating;
+     *  <code>false</code> if all components have been validated.
+         *
+         *  @return Returns <code>true</code> if there are components that need validating;
+     *  <code>false</code> if all components have been validated.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function isInvalid():Boolean
+    {
+        return invalidatePropertiesFlag ||
+               invalidateSizeFlag ||
+               invalidateDisplayListFlag;
+    }
+
+    /**
+     *  @private
+     *  callLater() is called immediately after an object is created.
+     *  We really want to wait one more frame before starting in.
+     */
+    private function waitAFrame(event:Event):void
+    {
+        // trace(">>LayoutManager:WaitAFrame");
+
+        systemManager.removeEventListener(Event.ENTER_FRAME, waitAFrame);
+        systemManager.addEventListener(Event.ENTER_FRAME, doPhasedInstantiationCallback);
+        waitedAFrame = true;
+
+        // trace("<<LayoutManager:WaitAFrame");
+    }
+
+    public function attachListeners(systemManager:ISystemManager):void
+    {
+        if (!waitedAFrame)
+        {
+            systemManager.addEventListener(Event.ENTER_FRAME, waitAFrame);
+        }
+        else
+        {
+            systemManager.addEventListener(Event.ENTER_FRAME, doPhasedInstantiationCallback);
+            if (!usePhasedInstantiation)
+            {
+				COMPILE::SWF
+				{
+                if (systemManager && (systemManager.stage || usingBridge(systemManager)))
+                {
+                    systemManager.addEventListener(Event.RENDER, doPhasedInstantiationCallback);
+                    if (systemManager.stage)
+                        systemManager.stage.invalidate();
+                }
+				}
+            }
+        }
+
+        listenersAttached = true;
+    }
+
+    private function doPhasedInstantiationCallback(event:Event):void
+    {
+        // if our background processing is suspended, then we shouldn't do any 
+        // validation
+        if (UIComponentGlobals.callLaterSuspendCount > 0)
+            return;
+        
+        systemManager.removeEventListener(Event.ENTER_FRAME, doPhasedInstantiationCallback);
+		COMPILE::SWF
+		{
+        systemManager.removeEventListener(Event.RENDER, doPhasedInstantiationCallback);		
+		}
+
+        if (!UIComponentGlobals.catchCallLaterExceptions)
+        {
+            doPhasedInstantiation();
+        }
+
+        else
+        {
+            try
+            {
+                doPhasedInstantiation();
+            }
+            catch(e:Error)
+            {
+                // Dispatch a callLaterError dynamic event for Design View. 
+                var callLaterErrorEvent:DynamicEvent = new DynamicEvent("callLaterError");
+                callLaterErrorEvent.error = e;
+                callLaterErrorEvent.source = this; 
+				callLaterErrorEvent.object = currentObject;
+                systemManager.dispatchEvent(callLaterErrorEvent);
+            }
+        }
+		currentObject = null;
+    }
+
+    private var _usingBridge:int = -1;
+
+    /**
+     *  @private
+     */
+    private function usingBridge(sm:ISystemManager):Boolean
+    {
+		COMPILE::LATER
+		{	
+        if (_usingBridge == 0) return false;
+        if (_usingBridge == 1) return true;
+
+        if (!sm) return false;
+
+        // no types so no dependencies
+        var mp:Object = sm.getImplementation("mx.managers::IMarshalSystemManager");
+        if (!mp)
+        {
+            _usingBridge = 0;
+            return false;
+        }
+        if (mp.useSWFBridge())
+        {
+            _usingBridge = 1;
+            return true;
+        }
+        _usingBridge = 0;
+		}
+        return false;
+    }
+
+}
+
+}
+

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/aaa01ca6/frameworks/projects/MX/src/main/flex/mx/managers/SystemManager.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/MX/src/main/flex/mx/managers/SystemManager.as b/frameworks/projects/MX/src/main/flex/mx/managers/SystemManager.as
index b54bc51..ab629e3 100644
--- a/frameworks/projects/MX/src/main/flex/mx/managers/SystemManager.as
+++ b/frameworks/projects/MX/src/main/flex/mx/managers/SystemManager.as
@@ -25,10 +25,10 @@ COMPILE::SWF
 	import flash.display.DisplayObject;
 	import flash.display.DisplayObjectContainer;
 	import flash.display.Graphics;
+	import flash.display.Loader;
+	import flash.display.LoaderInfo;
 	import flash.display.MovieClip;
 	import flash.display.Sprite;
-	import flash.display.LoaderInfo;
-	import flash.display.Loader;
 	import flash.display.Stage;
 	import flash.display.StageAlign;
 	import flash.display.StageQuality;
@@ -39,12 +39,14 @@ COMPILE::SWF
 	import flash.events.KeyboardEvent;
 	import flash.events.MouseEvent;
 	import flash.events.TimerEvent;
-	import flash.ui.Keyboard;
 	import flash.geom.Point;
 	import flash.system.ApplicationDomain;
 	import flash.text.Font;
 	import flash.text.TextFormat;
-	import flash.utils.Dictionary;		
+	import flash.ui.Keyboard;
+	import flash.utils.Dictionary;
+	
+	import flex.events.FlashEventConverter;
 }
 COMPILE::JS
 {
@@ -1695,6 +1697,7 @@ public class SystemManager extends MovieClip
                     // Use weak listener because we don't always know when we
                     // no longer need this listener
                     stage.addEventListener(type, stageEventHandler, false, 0, true);
+					stage.addEventListener(type, flashListener, true, 9999);
                 }
             }
             catch (error:SecurityError)
@@ -1726,10 +1729,12 @@ public class SystemManager extends MovieClip
                 if (stage)
                 {
                     stage.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler, false, 0, true);
+					stage.addEventListener(type, flashListener, false, 9999);
                 }
                 else
                 {
                     super.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler, false, 0, true);
+					super.addEventListener(type, flashListener, true, 9999);
                 }
             }
             catch (error:SecurityError)
@@ -1750,9 +1755,15 @@ public class SystemManager extends MovieClip
             try
             {
                 if (stage)
+				{
                     stage.addEventListener(type, listener, useCapture, priority, useWeakReference);
+					stage.addEventListener(type, flashListener, false, 9999);
+				}
                 else
+				{
                     super.addEventListener(type, listener, useCapture, priority, useWeakReference);
+					super.addEventListener(type, flashListener, true, 9999);
+				}
             }
             catch (error:SecurityError)
             {
@@ -1785,8 +1796,15 @@ public class SystemManager extends MovieClip
 		
 
         super.addEventListener(type, listener, useCapture, priority, useWeakReference);
+		super.addEventListener(type, flashListener, true, 9999);
     }
 
+	COMPILE::SWF
+	private function flashListener(e:flash.events.Event):void
+	{
+		trace(e.type, e.target);
+	}
+	
     /**
      *  @private
      */
@@ -2296,6 +2314,21 @@ public class SystemManager extends MovieClip
             domain);
 		}
 		}
+		COMPILE::SWF
+		{
+			// Initialize the preloader.
+			preloader.initialize(
+				usePreloader,
+				preloaderDisplayClass,
+				preloaderBackgroundColor,
+				preloaderBackgroundAlpha,
+				preloaderBackgroundImage,
+				preloaderBackgroundSize,
+				isStageRoot ? stage.stageWidth : loaderInfo.width,
+				isStageRoot ? stage.stageHeight : loaderInfo.height,
+				null,
+				null);
+		}
 		
 		COMPILE::JS
 		{
@@ -2912,6 +2945,10 @@ public class SystemManager extends MovieClip
 		}
         // Add the application as child 1.
         noTopMostIndex = noTopMostIndex + 1;
+		COMPILE::SWF
+		{
+			FlashEventConverter.removeAllConverters(app as DisplayObject);
+		}			
         super.addChildAt(DisplayObject(app), 1);
 
         CONFIG::performanceInstrumentation
@@ -3243,6 +3280,7 @@ public class SystemManager extends MovieClip
             stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler, false, 1000);
             stage.addEventListener(MouseEvent.MOUSE_WHEEL, mouseEventHandler, false, 1000);
             stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseEventHandler, false, 1000);
+			FlashEventConverter.setupAllConverters(this);
         }
 		}
         

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/aaa01ca6/frameworks/projects/MX/src/main/flex/mx/managers/layoutClasses/PriorityQueue.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/MX/src/main/flex/mx/managers/layoutClasses/PriorityQueue.as b/frameworks/projects/MX/src/main/flex/mx/managers/layoutClasses/PriorityQueue.as
new file mode 100644
index 0000000..4aca9b9
--- /dev/null
+++ b/frameworks/projects/MX/src/main/flex/mx/managers/layoutClasses/PriorityQueue.as
@@ -0,0 +1,398 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 mx.managers.layoutClasses
+{
+
+COMPILE::SWF
+{
+import flash.display.DisplayObject;
+import flash.display.DisplayObjectContainer;
+}
+COMPILE::JS
+{
+	import flex.display.DisplayObject;
+	import flex.display.DisplayObjectContainer;
+}
+
+import mx.core.IChildList;
+import mx.core.IRawChildrenContainer;
+import mx.managers.ILayoutManagerClient;
+
+[ExcludeClass]
+
+/**
+ *  @private
+ *  The PriorityQueue class provides a general purpose priority queue.
+ *  It is used internally by the LayoutManager.
+ */
+public class PriorityQueue
+{
+    include "../../core/Version.as";
+
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  Constructor.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function PriorityQueue()
+    {
+        super();
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    //--------------------------------------------------------------------------
+    
+    /**
+     *  @private
+     */
+    private var priorityBins:Array = [];
+
+    /**
+     *  @private
+     *  The smallest occupied index in arrayOfDictionaries.
+     */
+    private var minPriority:int = 0;
+    
+    /**
+     *  @private
+     *  The largest occupied index in arrayOfDictionaries.
+     */
+    private var maxPriority:int = -1;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    public function addObject(obj:Object, priority:int):void
+    {       
+        // Update our min and max priorities.
+        if (maxPriority < minPriority)
+        {
+            minPriority = maxPriority = priority;
+        }
+        else
+        {
+            if (priority < minPriority)
+                minPriority = priority;
+            if (priority > maxPriority)
+                maxPriority = priority;
+        }
+            
+        var bin:PriorityBin = priorityBins[priority];
+        
+        if (!bin)
+        {
+            // If no hash exists for the specified priority, create one.
+            bin = new PriorityBin();
+            priorityBins[priority] = bin;
+            bin.items[obj] = true;
+            bin.length++;
+        }
+        else
+        {
+            // If we don't already hold the obj in the specified hash, add it
+            // and update our item count.
+            if (bin.items[obj] == null)
+            { 
+                bin.items[obj] = true;
+                bin.length++;
+            }
+        }
+        
+    }
+
+    /**
+     *  @private
+     */
+    public function removeLargest():Object
+    {
+        var obj:Object = null;
+
+        if (minPriority <= maxPriority)
+        {
+            var bin:PriorityBin = priorityBins[maxPriority];
+            while (!bin || bin.length == 0)
+            {
+                maxPriority--;
+                if (maxPriority < minPriority)
+                    return null;
+                bin = priorityBins[maxPriority];
+            }
+        
+            // Remove the item with largest priority from our priority queue.
+            // Must use a for loop here since we're removing a specific item
+            // from a 'Dictionary' (no means of directly indexing).
+            for (var key:Object in bin.items )
+            {
+                obj = key;
+                removeChild(ILayoutManagerClient(key), maxPriority);
+                break;
+            }
+
+            // Update maxPriority if applicable.
+            while (!bin || bin.length == 0)
+            {
+                maxPriority--;
+                if (maxPriority < minPriority)
+                    break;
+                bin = priorityBins[maxPriority];
+            }
+            
+        }
+        
+        return obj;
+    }
+
+    /**
+     *  @private
+     */
+    public function removeLargestChild(client:ILayoutManagerClient ):Object
+    {
+        var max:int = maxPriority;
+        var min:int = client.nestLevel;
+
+        while (min <= max)
+        {
+            var bin:PriorityBin = priorityBins[max];
+            if (bin && bin.length > 0)
+            {
+                if (max == client.nestLevel)
+                {
+                    // If the current level we're searching matches that of our
+                    // client, no need to search the entire list, just check to see
+                    // if the client exists in the queue (it would be the only item
+                    // at that nestLevel).
+                    if (bin.items[client])
+                    {
+                        removeChild(ILayoutManagerClient(client), max);
+                        return client;
+                    }
+                }
+                else
+                {
+                    for (var key:Object in bin.items )
+                    {
+                        if ((key is DisplayObject) && contains(DisplayObject(client), DisplayObject(key)))
+                        {
+                            removeChild(ILayoutManagerClient(key), max);
+                            return key;
+                        }
+                    }
+                }
+                
+                max--;
+            }
+            else
+            {
+                if (max == maxPriority)
+                    maxPriority--;
+                max--;
+                if (max < min)
+                    break;
+            }           
+        }
+
+        return null;
+    }
+
+    /**
+     *  @private
+     */
+    public function removeSmallest():Object
+    {
+        var obj:Object = null;
+
+        if (minPriority <= maxPriority)
+        {
+            var bin:PriorityBin = priorityBins[minPriority];
+            while (!bin || bin.length == 0)
+            {
+                minPriority++;
+                if (minPriority > maxPriority)
+                    return null;
+                bin = priorityBins[minPriority];
+            }           
+
+            // Remove the item with smallest priority from our priority queue.
+            // Must use a for loop here since we're removing a specific item
+            // from a 'Dictionary' (no means of directly indexing).
+            for (var key:Object in bin.items )
+            {
+                obj = key;
+                removeChild(ILayoutManagerClient(key), minPriority);
+                break;
+            }
+
+            // Update minPriority if applicable.
+            while (!bin || bin.length == 0)
+            {
+                minPriority++;
+                if (minPriority > maxPriority)
+                    break;
+                bin = priorityBins[minPriority];
+            }           
+        }
+
+        return obj;
+    }
+
+    /**
+     *  @private
+     */
+    public function removeSmallestChild(client:ILayoutManagerClient ):Object
+    {
+        var min:int = client.nestLevel;
+
+        while (min <= maxPriority)
+        {
+            var bin:PriorityBin = priorityBins[min];
+            if (bin && bin.length > 0)
+            {   
+                if (min == client.nestLevel)
+                {
+                    // If the current level we're searching matches that of our
+                    // client, no need to search the entire list, just check to see
+                    // if the client exists in the queue (it would be the only item
+                    // at that nestLevel).
+                    if (bin.items[client])
+                    {
+                        removeChild(ILayoutManagerClient(client), min);
+                        return client;
+                    }
+                }
+                else
+                {
+                    for (var key:Object in bin.items)
+                    {
+                        if ((key is DisplayObject) && contains(DisplayObject(client), DisplayObject(key)))
+                        {
+                            removeChild(ILayoutManagerClient(key), min);
+                            return key;
+                        }
+                    }
+                }
+                
+                min++;
+            }
+            else
+            {
+                if (min == minPriority)
+                    minPriority++;
+                min++;
+                if (min > maxPriority)
+                    break;
+            }           
+        }
+        
+        return null;
+    }
+
+    /**
+     *  @private
+     */
+    public function removeChild(client:ILayoutManagerClient, level:int=-1):Object
+    {
+        var priority:int = (level >= 0) ? level : client.nestLevel;
+        var bin:PriorityBin = priorityBins[priority];
+        if (bin && bin.items[client] != null)
+        {
+            delete bin.items[client];
+            bin.length--;
+            return client;
+        }
+        return null;
+    }
+    
+    /**
+     *  @private
+     */
+    public function removeAll():void
+    {
+        priorityBins.length = 0;
+        minPriority = 0;
+        maxPriority = -1;
+    }
+
+    /**
+     *  @private
+     */
+    public function isEmpty():Boolean
+    {
+        return minPriority > maxPriority;
+    }
+
+    /**
+     *  @private
+     */
+    private function contains(parent:DisplayObject, child:DisplayObject):Boolean
+    {
+        if (parent is IRawChildrenContainer)
+        {
+            var rawChildren:IChildList = IRawChildrenContainer(parent).rawChildren;
+            return rawChildren.contains(child);
+        }
+        else if (parent is DisplayObjectContainer)
+        {
+            return DisplayObjectContainer(parent).contains(child);
+        }
+
+        return parent == child;
+    }
+
+}
+
+}
+
+COMPILE::LATER
+{
+import flash.utils.Dictionary;
+}
+
+/**
+ *  Represents one priority bucket of entries.
+ *  @private
+ */
+class PriorityBin 
+{
+    public var length:int;
+	COMPILE::LATER
+	{
+    public var items:Dictionary = new Dictionary();
+	}
+	public var items:Object = new Object();
+    
+}


Mime
View raw message