You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ah...@apache.org on 2014/03/12 05:36:37 UTC

[3/7] git commit: [flex-asjs] [refs/heads/develop] - more legacy classes need to make mustella happy. Some are stripped down to eliminate undesirable dependencies

more legacy classes need to make mustella happy.  Some are stripped down to eliminate undesirable dependencies


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

Branch: refs/heads/develop
Commit: dec3558fd2e48ffe82bbe41411c3044e80d072cd
Parents: b606f59
Author: Alex Harui <ah...@apache.org>
Authored: Mon Mar 3 15:47:15 2014 -0800
Committer: Alex Harui <ah...@apache.org>
Committed: Tue Mar 11 21:36:03 2014 -0700

----------------------------------------------------------------------
 .../projects/MXMLCClasses/src/MXMLCClasses.as   |    4 +
 .../src/mx/binding/BindabilityInfo.as           |  279 ++++
 .../MXMLCClasses/src/mx/core/FlexGlobals.as     |   55 +
 .../MXMLCClasses/src/mx/core/IMXMLObject.as     |   61 +
 .../src/mx/core/IPropertyChangeNotifier.as      |   67 +-
 .../projects/MXMLCClasses/src/mx/core/IUID.as   |   62 +
 .../src/mx/events/PropertyChangeEvent.as        |   72 +
 .../src/mx/utils/DescribeTypeCache.as           |  172 +++
 .../src/mx/utils/DescribeTypeCacheRecord.as     |  129 ++
 .../MXMLCClasses/src/mx/utils/ObjectProxy.as    |  825 ++++++++++
 .../MXMLCClasses/src/mx/utils/ObjectUtil.as     | 1424 ++++++++++++++++++
 .../MXMLCClasses/src/mx/utils/StringUtil.as     |  364 +++++
 .../MXMLCClasses/src/mx/utils/UIDUtil.as        |  296 ++++
 .../MXMLCClasses/src/mx/utils/object_proxy.as   |   34 +
 14 files changed, 3839 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/dec3558f/frameworks/as/projects/MXMLCClasses/src/MXMLCClasses.as
----------------------------------------------------------------------
diff --git a/frameworks/as/projects/MXMLCClasses/src/MXMLCClasses.as b/frameworks/as/projects/MXMLCClasses/src/MXMLCClasses.as
index 2bb6511..dc3661e 100644
--- a/frameworks/as/projects/MXMLCClasses/src/MXMLCClasses.as
+++ b/frameworks/as/projects/MXMLCClasses/src/MXMLCClasses.as
@@ -42,8 +42,10 @@ internal class MXMLCClasses
     import mx.binding.XMLWatcher; XMLWatcher;
     import mx.core.DeferredInstanceFromClass; DeferredInstanceFromClass;
     import mx.core.DeferredInstanceFromFunction; DeferredInstanceFromFunction;
+    import mx.core.FlexGlobals; FlexGlobals;
     import mx.core.IDeferredInstance; IDeferredInstance;
     import mx.core.IFlexModuleFactory; IFlexModuleFactory;
+    import mx.core.IMXMLObject; IMXMLObject;
     import mx.core.IPropertyChangeNotifier; IPropertyChangeNotifier;
     import mx.core.IStateClient2; IStateClient2;
     import mx.core.mx_internal; use namespace mx_internal;
@@ -54,6 +56,8 @@ internal class MXMLCClasses
     import mx.styles.CSSStyleDeclaration; CSSStyleDeclaration;
     import mx.styles.IStyleManager2; IStyleManager2;
     import mx.styles.StyleManager; StyleManager;    
+    import mx.utils.ObjectUtil; ObjectUtil;
+    import mx.utils.StringUtil; StringUtil;
 }
 
 }

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/dec3558f/frameworks/as/projects/MXMLCClasses/src/mx/binding/BindabilityInfo.as
----------------------------------------------------------------------
diff --git a/frameworks/as/projects/MXMLCClasses/src/mx/binding/BindabilityInfo.as b/frameworks/as/projects/MXMLCClasses/src/mx/binding/BindabilityInfo.as
new file mode 100644
index 0000000..1d48569
--- /dev/null
+++ b/frameworks/as/projects/MXMLCClasses/src/mx/binding/BindabilityInfo.as
@@ -0,0 +1,279 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.binding
+{
+
+import mx.events.PropertyChangeEvent;
+
+[ExcludeClass]
+
+/**
+ *  @private
+ *  Bindability information for children (properties or methods)
+ *  of a given class, based on the describeType() structure for that class.
+ */
+public class BindabilityInfo
+{
+
+	//--------------------------------------------------------------------------
+	//
+	//  Class constants
+	//
+	//--------------------------------------------------------------------------
+	
+	/**
+	 *  Name of [Bindable] metadata.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public static const BINDABLE:String = "Bindable";
+	
+	/**
+	 *  Name of [Managed] metadata.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public static const MANAGED:String = "Managed";
+	
+	/**
+	 *  Name of [ChangeEvent] metadata.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public static const CHANGE_EVENT:String = "ChangeEvent";
+	
+	/**
+	 *  Name of [NonCommittingChangeEvent] metadata.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public static const NON_COMMITTING_CHANGE_EVENT:String =
+		"NonCommittingChangeEvent";
+
+	/**
+	 *  Name of describeType() <accessor> element.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public static const ACCESSOR:String = "accessor";
+	
+	/**
+	 *  Name of describeType() <method> element.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public static const METHOD:String = "method";
+
+	//--------------------------------------------------------------------------
+	//
+	//  Constructor
+	//
+	//--------------------------------------------------------------------------
+
+	/**
+	 *  Constructor.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public function BindabilityInfo(typeDescription:XML)
+	{
+		super();
+
+		this.typeDescription = typeDescription;
+	}
+
+	//--------------------------------------------------------------------------
+	//
+	//  Variables
+	//
+	//--------------------------------------------------------------------------
+
+	/**
+	 *  @private
+	 */
+	private var typeDescription:XML;
+	
+	/**
+	 *  @private
+	 *  event name -> true
+	 */
+	private var classChangeEvents:Object;
+	
+	/**
+	 *  @private
+	 *  child name -> { event name -> true }
+	 */
+	private var childChangeEvents:Object = {};	
+
+	//--------------------------------------------------------------------------
+	//
+	//  Variables
+	//
+	//--------------------------------------------------------------------------
+
+	/**
+	 *  Object containing { eventName: true } for each change event
+	 *  (class- or child-level) that applies to the specified child.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public function getChangeEvents(childName:String):Object
+	{
+		var changeEvents:Object = childChangeEvents[childName];
+
+		if (!changeEvents)
+		{
+			// Seed with class-level events.
+			changeEvents = copyProps(getClassChangeEvents(), {});
+
+			// Get child-specific events.
+			var childDesc:XMLList =
+				typeDescription.accessor.(@name == childName) +
+				typeDescription.method.(@name == childName);
+			
+			var numChildren:int = childDesc.length();
+
+			if (numChildren == 0)
+			{
+				// we've been asked for events on an unknown property
+				if (!typeDescription.@dynamic)
+				{
+					trace("warning: no describeType entry for '" +
+						  childName + "' on non-dynamic type '" +
+						  typeDescription.@name + "'");
+				}
+			}
+			else
+			{
+				if (numChildren > 1)
+				{
+					trace("warning: multiple describeType entries for '" +
+						  childName + "' on type '" + typeDescription.@name +
+						  "':\n" + childDesc);
+				}
+
+				addBindabilityEvents(childDesc.metadata, changeEvents);
+			}
+
+			childChangeEvents[childName] = changeEvents;
+		}
+
+		return changeEvents;
+	}
+
+	/**
+	 *  @private
+	 *  Build or return cached class change events object.
+	 */
+	private function getClassChangeEvents():Object
+	{
+		if (!classChangeEvents)
+		{
+			classChangeEvents = {};
+
+			addBindabilityEvents(typeDescription.metadata, classChangeEvents);
+
+			// Class-level [Managed] means all properties
+			// dispatch propertyChange.
+			if (typeDescription.metadata.(@name == MANAGED).length() > 0)
+			{
+				classChangeEvents[PropertyChangeEvent.PROPERTY_CHANGE] = true;
+			}
+		}
+
+		return classChangeEvents;
+	}
+
+	/**
+	 *  @private
+	 */
+	private function addBindabilityEvents(metadata:XMLList,
+										  eventListObj:Object):void
+	{
+		addChangeEvents(metadata.(@name == BINDABLE), eventListObj, true);
+		addChangeEvents(metadata.(@name == CHANGE_EVENT), eventListObj, true);
+		addChangeEvents(metadata.(@name == NON_COMMITTING_CHANGE_EVENT),
+						eventListObj, false);
+	}
+
+	/**
+	 *  @private
+	 *  Transfer change events from a list of change-event-carrying metadata
+	 *  to an event list object.
+	 *  Note: metadata's first arg value is assumed to be change event name.
+	 */
+	private function addChangeEvents(metadata:XMLList, eventListObj:Object, isCommit:Boolean):void
+	{
+		for each (var md:XML in metadata)
+		{
+			var arg:XMLList = md.arg;
+			if (arg.length() > 0)
+			{
+				var eventName:String = arg[0].@value;
+				eventListObj[eventName] = isCommit;
+			}
+			else
+			{
+				trace("warning: unconverted Bindable metadata in class '" +
+					  typeDescription.@name + "'");
+			}
+		}
+	}
+
+	/**
+	 *  @private
+	 *  Copy properties from one object to another.
+	 */
+	private function copyProps(from:Object, to:Object):Object
+	{
+		for (var propName:String in from)
+		{
+			to[propName] = from[propName];
+		}
+
+		return to;
+	}
+}
+
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/dec3558f/frameworks/as/projects/MXMLCClasses/src/mx/core/FlexGlobals.as
----------------------------------------------------------------------
diff --git a/frameworks/as/projects/MXMLCClasses/src/mx/core/FlexGlobals.as b/frameworks/as/projects/MXMLCClasses/src/mx/core/FlexGlobals.as
new file mode 100644
index 0000000..b07a5d2
--- /dev/null
+++ b/frameworks/as/projects/MXMLCClasses/src/mx/core/FlexGlobals.as
@@ -0,0 +1,55 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.core
+{
+
+/**
+ *  A class that contains variables that are global to all applications within
+ *  the same ApplicationDomain.
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ *
+ */
+public class FlexGlobals
+{
+    //--------------------------------------------------------------------------
+    //
+    //  Class variables
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  The first application run in an ApplicationDomain is the top-level application.
+     *  This property is set to a reference to the top-level application in the top-level 
+     *  application's constructor. Each ApplicationDomain will have its own 
+     *  <code>topLevelApplication</code>.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+	public static var topLevelApplication:Object;
+}
+
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/dec3558f/frameworks/as/projects/MXMLCClasses/src/mx/core/IMXMLObject.as
----------------------------------------------------------------------
diff --git a/frameworks/as/projects/MXMLCClasses/src/mx/core/IMXMLObject.as b/frameworks/as/projects/MXMLCClasses/src/mx/core/IMXMLObject.as
new file mode 100644
index 0000000..9b6ec90
--- /dev/null
+++ b/frameworks/as/projects/MXMLCClasses/src/mx/core/IMXMLObject.as
@@ -0,0 +1,61 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.core
+{
+
+/**
+ *  The IMXMLObject interface defines the APIs that a non-visual component
+ *  must implement in order to work properly with the MXML compiler.
+ *  Currently, the only supported method is the <code>initialized()</code>
+ *  method.
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
+ */
+public interface IMXMLObject
+{
+	//--------------------------------------------------------------------------
+	//
+	//  Methods
+	//
+	//--------------------------------------------------------------------------
+
+    /**
+     *  Called after the implementing object has been created and all
+	 *  component properties specified on the MXML tag have been initialized.
+	 *
+     *  @param document The MXML document that created this object.
+	 *
+     *  @param id The identifier used by <code>document</code> to refer
+	 *  to this object.
+	 *  If the object is a deep property on <code>document</code>,
+	 *  <code>id</code> is null.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    function initialized(document:Object, id:String):void;
+}
+
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/dec3558f/frameworks/as/projects/MXMLCClasses/src/mx/core/IPropertyChangeNotifier.as
----------------------------------------------------------------------
diff --git a/frameworks/as/projects/MXMLCClasses/src/mx/core/IPropertyChangeNotifier.as b/frameworks/as/projects/MXMLCClasses/src/mx/core/IPropertyChangeNotifier.as
index 39d86ed..fbef45e 100644
--- a/frameworks/as/projects/MXMLCClasses/src/mx/core/IPropertyChangeNotifier.as
+++ b/frameworks/as/projects/MXMLCClasses/src/mx/core/IPropertyChangeNotifier.as
@@ -20,13 +20,70 @@
 package mx.core
 {
 
+import flash.events.IEventDispatcher;
+
 /**
- * @private
- * This class is used to satisfy old MXML codegen
- * for both Falcon and MXML, but in FlexJS with mxml.children-as-data output
- * it isn't needed so there is no JS equivalent
+ *  The <code>IPropertyChangeNotifier</code> interface defines a marker 
+ *  interface.
+ *  Classes that support this interface declare support for event propagation
+ *  in a specialized manner.
+ *  Classes that implement this interface must dispatch events for each property
+ *  of this class and any nested classes publicly exposed as properties.
+ *  For those properties that are anonymous (complex and not strongly typed),
+ *  implementing classes provide custom support or directly use the
+ *  ObjectProxy class.
+ *  Implementors of this interface should use the 
+ *  <code>PropertyChangeEvent.createUpdateEvent()</code> method to construct an
+ *  appropriate update event for dispatch.
+ *  @example
+ *  <code><pre>
+ *   
+ * function set myProperty(value:Object):void
+ * {
+ *    var oldValue:IPropertyChangeNotifier = _myProperty;
+ *    var newValue:IPropertyChangeNotifier = value;
+ *    
+ *    // Need to ensure to dispatch changes on the new property.
+ *    // Listeners use the source property to determine which object 
+ *    // actually originated the event.
+ *    // In their event handler code, they can tell if an event has been 
+ *    // propagated from deep within the object graph by comparing 
+ *    // event.target and event.source. If they are equal, then the property
+ *    // change is at the surface of the object. If they are not equal, the
+ *    // property change is somewhere deeper in the object graph.
+ *    newValue.addEventListener(
+ *                PropertyChangeEvent.PROPERTY_CHANGE, 
+ *                dispatchEvent);
+ * 
+ *    // need to stop listening for events from the old property
+ *    oldValue.removeEventListener(
+ *                PropertyChangeEvent.PROPERTY_CHANGE,
+ *                dispatchEvent);
+ * 
+ *    _myProperty = newValue;
+ * 
+ *    // now notify anyone that is listening
+ *    if (dispatcher.hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
+ *    {
+ *         var event:PropertyChangeEvent = 
+ *                         PropertyChangeEvent.createUpdateEvent(
+ *                                                       this,
+ *                                                       "myProperty",
+ *                                                       newValue,
+ *                                                       oldValue);
+ *        dispatchEvent(event);
+ *     }
+ *  }
+ * 
+ *      
+ *  </pre></code>
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
  */
-public interface IPropertyChangeNotifier
+public interface IPropertyChangeNotifier extends IEventDispatcher, IUID
 {
     //--------------------------------------------------------------------------
     //

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/dec3558f/frameworks/as/projects/MXMLCClasses/src/mx/core/IUID.as
----------------------------------------------------------------------
diff --git a/frameworks/as/projects/MXMLCClasses/src/mx/core/IUID.as b/frameworks/as/projects/MXMLCClasses/src/mx/core/IUID.as
new file mode 100644
index 0000000..cd0f321
--- /dev/null
+++ b/frameworks/as/projects/MXMLCClasses/src/mx/core/IUID.as
@@ -0,0 +1,62 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.core
+{
+
+/**
+ *  The IUID interface defines the interface for objects that must have 
+ *  Unique Identifiers (UIDs) to uniquely identify the object.
+ *  UIDs do not need to be universally unique for most uses in Flex.
+ *  One exception is for messages send by data services.
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
+ */
+public interface IUID
+{
+	//--------------------------------------------------------------------------
+	//
+	//  Properties
+	//
+	//--------------------------------------------------------------------------
+
+	//----------------------------------
+	//  uid
+	//----------------------------------
+	
+	/**
+	 *  The unique identifier for this object.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    function get uid():String;
+    
+    /**
+     *  @private
+     */
+    function set uid(value:String):void;
+}
+
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/dec3558f/frameworks/as/projects/MXMLCClasses/src/mx/events/PropertyChangeEvent.as
----------------------------------------------------------------------
diff --git a/frameworks/as/projects/MXMLCClasses/src/mx/events/PropertyChangeEvent.as b/frameworks/as/projects/MXMLCClasses/src/mx/events/PropertyChangeEvent.as
index dcb2996..47033ec 100644
--- a/frameworks/as/projects/MXMLCClasses/src/mx/events/PropertyChangeEvent.as
+++ b/frameworks/as/projects/MXMLCClasses/src/mx/events/PropertyChangeEvent.as
@@ -73,6 +73,78 @@ public class PropertyChangeEvent extends Event
         super(type, bubbles, cancelable);
     }
 
+    //----------------------------------
+    //  kind
+    //----------------------------------
+    
+    /**
+     *  Specifies the kind of change.
+     *  The possible values are <code>PropertyChangeEventKind.UPDATE</code>,
+     *  <code>PropertyChangeEventKind.DELETE</code>, and <code>null</code>.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public var kind:String;
+    
+    //----------------------------------
+    //  newValue
+    //----------------------------------
+    
+    /**
+     *  The value of the property after the change.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public var newValue:Object;
+    
+    //----------------------------------
+    //  oldValue
+    //----------------------------------
+    
+    /**
+     *  The value of the property before the change.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public var oldValue:Object;
+    
+    //----------------------------------
+    //  property
+    //----------------------------------
+    
+    /**
+     *  A String, QName, or int specifying the property that changed.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public var property:Object;
+    
+    //----------------------------------
+    //  source
+    //----------------------------------
+    
+    /**
+     *  The object that the change occured on.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public var source:Object;
+    
 }
 
 }

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/dec3558f/frameworks/as/projects/MXMLCClasses/src/mx/utils/DescribeTypeCache.as
----------------------------------------------------------------------
diff --git a/frameworks/as/projects/MXMLCClasses/src/mx/utils/DescribeTypeCache.as b/frameworks/as/projects/MXMLCClasses/src/mx/utils/DescribeTypeCache.as
new file mode 100644
index 0000000..1517b55
--- /dev/null
+++ b/frameworks/as/projects/MXMLCClasses/src/mx/utils/DescribeTypeCache.as
@@ -0,0 +1,172 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.utils
+{
+
+import flash.utils.describeType;
+import flash.utils.getDefinitionByName;
+import flash.utils.getQualifiedClassName;
+import mx.binding.BindabilityInfo;
+
+[ExcludeClass]
+
+/**
+ *  @private
+ *  DescribeTypeCache is a convenience class that is used to
+ *  cache the return values of <code>flash.utils.describeType()</code>
+ *  so that calls made subsequent times return faster.
+ *
+ *  This class also lets you set handler functions for specific value types.
+ *  These will get called when the user tries to access these values on
+ *  the <code>DescribeTypeCacheRecord</code> class.
+ *
+ *  @see mx.utils.DescribeTypeCacheRecord
+ */
+public class DescribeTypeCache
+{
+
+    //--------------------------------------------------------------------------
+    //
+    //  Class initialization
+    //
+    //--------------------------------------------------------------------------
+
+    registerCacheHandler("bindabilityInfo", bindabilityInfoHandler);
+
+    //--------------------------------------------------------------------------
+    //
+    //  Class variables
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    private static var typeCache:Object = {};
+
+    /**
+     *  @private
+     */
+    private static var cacheHandlers:Object = {};
+
+    //--------------------------------------------------------------------------
+    //
+    //  Class methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Calls <code>flash.utils.describeType()</code> for the first time and caches
+         *  the return value so that subsequent calls return faster.
+         *
+         *  @param o Can be either a string describing a fully qualified class name or any
+         *  ActionScript value, including all available ActionScript types, object instances,
+         *  primitive types (such as <code>uint</code>), and class objects.
+         *
+         *  @return Returns the cached record.
+         *
+         *  @see flash.utils#describeType()
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public static function describeType(o:*):DescribeTypeCacheRecord
+    {
+        var className:String;
+        var cacheKey:String;
+
+        if (o is String)
+            cacheKey = className = o;
+        else
+            cacheKey = className = getQualifiedClassName(o);
+
+        //Need separate entries for describeType(Foo) and describeType(myFoo)
+        if (o is Class)
+            cacheKey += "$";
+
+        if (cacheKey in typeCache)
+        {
+            return typeCache[cacheKey];
+        }
+        else
+        {
+            if (o is String)
+            {
+                try
+                {
+                    o = getDefinitionByName(o);
+                }
+                catch (error:ReferenceError)
+                {
+                    // The o parameter doesn't refer to an ActionScript 
+                    // definition, it's just a string value.
+                }
+            }
+            var typeDescription:XML = flash.utils.describeType(o);
+            var record:DescribeTypeCacheRecord = new DescribeTypeCacheRecord();
+            record.typeDescription = typeDescription;
+            record.typeName = className;
+            typeCache[cacheKey] = record;
+
+            return record;
+        }
+    }
+
+    /**
+     *  registerCacheHandler lets you add function handler for specific strings.
+         *  These functions get called when the user refers to these values on a
+         *  instance of <code>DescribeTypeCacheRecord</code>.
+     *
+     *  @param valueName String that specifies the value for which the handler must be set.
+         *  @param handler Function that should be called when user references valueName.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public static function registerCacheHandler(valueName:String, handler:Function):void
+    {
+        cacheHandlers[valueName] = handler;
+    }
+
+    /**
+     *  @private
+     */
+    internal static function extractValue(valueName:String, record:DescribeTypeCacheRecord):*
+    {
+        if (valueName in cacheHandlers)
+            return cacheHandlers[valueName](record);
+
+        return undefined;
+    }
+
+    /**
+     *  @private
+     */
+    private static function bindabilityInfoHandler(record:DescribeTypeCacheRecord):*
+    {
+        return new BindabilityInfo(record.typeDescription);
+    }
+}
+
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/dec3558f/frameworks/as/projects/MXMLCClasses/src/mx/utils/DescribeTypeCacheRecord.as
----------------------------------------------------------------------
diff --git a/frameworks/as/projects/MXMLCClasses/src/mx/utils/DescribeTypeCacheRecord.as b/frameworks/as/projects/MXMLCClasses/src/mx/utils/DescribeTypeCacheRecord.as
new file mode 100644
index 0000000..ea17f6c
--- /dev/null
+++ b/frameworks/as/projects/MXMLCClasses/src/mx/utils/DescribeTypeCacheRecord.as
@@ -0,0 +1,129 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.utils 
+{
+
+import flash.utils.Proxy;
+import flash.utils.flash_proxy;
+
+use namespace flash_proxy;
+
+[ExcludeClass]
+
+/**
+ *  @private
+ *  This class represents a single cache entry, this gets created
+ *  as part of the <code>describeType</code> method call on the 
+ *  <code>DescribeTypeCache</code>  class.
+ */
+
+public dynamic class DescribeTypeCacheRecord extends Proxy
+{
+    //--------------------------------------------------------------------------
+    //
+    //  Class variables
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    private var cache:Object = {};
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Class properties
+    //
+    //--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  typeDescription
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    public var typeDescription:XML;
+    
+    //----------------------------------
+    //  typeName
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    public var typeName:String;
+
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    public function DescribeTypeCacheRecord()
+    {
+        super();
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    override flash_proxy function getProperty(name:*):*
+    {
+        var result:* = cache[name];
+        
+        if (result === undefined)
+        {
+            result = DescribeTypeCache.extractValue(name, this);
+            cache[name] = result;
+        }
+        
+        return result;
+    }
+
+    /**
+     *  @private
+     */
+    override flash_proxy function hasProperty(name:*):Boolean
+    {
+        if (name in cache)
+            return true;
+        
+        var value:* = DescribeTypeCache.extractValue(name, this);       
+        
+        if (value === undefined)
+            return false;
+        
+        cache[name] = value;
+        
+        return true;
+    }
+}
+
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/dec3558f/frameworks/as/projects/MXMLCClasses/src/mx/utils/ObjectProxy.as
----------------------------------------------------------------------
diff --git a/frameworks/as/projects/MXMLCClasses/src/mx/utils/ObjectProxy.as b/frameworks/as/projects/MXMLCClasses/src/mx/utils/ObjectProxy.as
new file mode 100644
index 0000000..03a8f51
--- /dev/null
+++ b/frameworks/as/projects/MXMLCClasses/src/mx/utils/ObjectProxy.as
@@ -0,0 +1,825 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.utils
+{
+
+import flash.events.Event;
+import flash.events.EventDispatcher;
+import flash.utils.getQualifiedClassName;
+import flash.utils.IDataInput;
+import flash.utils.IDataOutput;
+import flash.utils.IExternalizable;
+import flash.utils.Proxy;
+import flash.utils.flash_proxy;
+import mx.core.IPropertyChangeNotifier;
+import mx.events.PropertyChangeEvent;
+import mx.events.PropertyChangeEventKind;
+
+use namespace flash_proxy;
+use namespace object_proxy;
+
+[Bindable("propertyChange")]
+[RemoteClass(alias="flex.messaging.io.ObjectProxy")]
+
+/**
+ *  This class provides the ability to track changes to an item
+ *  managed by this proxy.
+ *  Any number of objects can "listen" for changes on this
+ *  object, by using the <code>addEventListener()</code> method.
+ *
+ *  @example
+ *  <pre>
+ *  import mx.events.PropertyChangeEvent;
+ *  import mx.utils.ObjectUtil;
+ *  import mx.utils.ObjectProxy;
+ *  import mx.utils.StringUtil;
+ *
+ *  var a:Object = { name: "Tyler", age: 5, ssnum: "555-55-5555" };
+ *  var p:ObjectProxy = new ObjectProxy(a);
+ *  p.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, updateHandler);
+ *  p.name = "Jacey";
+ *  p.age = 2;
+ *  delete p.ssnum;
+ *
+ *  // handler function
+ *  function updateHandler(event:ChangeEvent):void
+ *  {
+ *      trace(StringUtil.substitute("updateHandler('{0}', {1}, {2}, {3}, '{4}')",
+ *                                     event.kind,
+ *                                     event.property,
+ *                                     event.oldValue,
+ *                                     event.newValue,
+ *                                     event.target.object_proxy::UUID));
+ *  }
+ * 
+ *  // The trace output appears as:
+ *  // updateHandler('opUpdate', name, Tyler, Jacey, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
+ *  // updateHandler('opUpdate', age, 5, 2, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
+ *  // updateHandler('opDelete', ssnum, 555-55-5555, null, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
+ *  </pre>
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
+ */
+public dynamic class ObjectProxy extends Proxy
+                                 implements IExternalizable,
+                                 IPropertyChangeNotifier
+{
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Initializes this proxy with the specified object, id and proxy depth.
+     * 
+     *  @param item Object to proxy.
+     *  If no item is specified, an anonymous object will be constructed
+     *  and assigned.
+     *
+     *  @param uid String containing the unique id
+     *  for this object instance.
+     *  Required for IPropertyChangeNotifier compliance as every object must 
+     *  provide a unique way of identifying it.
+     *  If no value is specified, a random id will be assigned.
+     *
+     *  @param proxyDepth An integer indicating how many levels in a complex
+     *  object graph should have a proxy created during property access.
+     *  The default is -1, meaning "proxy to infinite depth".
+     *  
+     *  @example
+     *
+     *  <pre>
+     *  import mx.events.PropertyChangeEvent;
+     *  import mx.utils.ObjectUtil;
+     *  import mx.utils.ObjectProxy;
+     *  import mx.utils.StringUtil;
+     *
+     *  var a:Object = { name: "Tyler", age: 5, ssnum: "555-55-5555" };
+     *  var p:ObjectProxy = new ObjectProxy(a);
+     *  p.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, updateHandler);
+     *  p.name = "Jacey";
+     *  p.age = 2;
+     *  delete p.ssnum;
+     *
+     *  // handler function
+     *  function updateHandler(event:PropertyChangeEvent):void
+     *  {
+     *      trace(StringUtil.substitute("updateHandler('{0}', {1}, {2}, {3}, '{4}')",
+     *                                     event.kind,
+     *                                     event.property,
+     *                                     event.oldValue,
+     *                                     event.newValue,
+     *                                     event.target.uid));
+     *  }
+     *
+     *  // trace output
+     *  updateHandler('opUpdate', name, Jacey, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
+     *  updateHandler('opUpdate', age, 2, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
+     *  updateHandler('opDelete', ssnum, null, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
+     *  </pre>
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function ObjectProxy(item:Object = null, uid:String = null,
+                                proxyDepth:int = -1)
+    {
+        super();
+
+        if (!item)
+            item = {};
+        _item = item;
+
+        _proxyLevel = proxyDepth;
+       
+        notifiers = {};
+
+        dispatcher = new EventDispatcher(this);
+
+        // If we got an id, use it.  Otherwise the UID is lazily
+        // created in the getter for UID.
+        if (uid)
+            _id = uid;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  A reference to the EventDispatcher for this proxy.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    protected var dispatcher:EventDispatcher;
+
+    /**
+     *  A hashmap of property change notifiers that this proxy is 
+     *  listening for changes from; the key of the map is the property name.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    protected var notifiers:Object;
+    
+    /**
+     *  Indicates what kind of proxy to create
+     *  when proxying complex properties.
+     *  Subclasses should assign this value appropriately.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    protected var proxyClass:Class = ObjectProxy;
+    
+    /**
+     *  Contains a list of all of the property names for the proxied object.
+     *  Descendants need to fill this list by overriding the
+     *  <code>setupPropertyList()</code> method.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    protected var propertyList:Array;
+    
+    /**
+     *  Indicates how deep proxying should be performed.
+     *  If -1 (default), always proxy; 
+     *  if this value is zero, no proxying will be performed.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    private var _proxyLevel:int;
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Properties
+    //
+    //--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  object
+    //----------------------------------
+
+    /**
+     *  Storage for the object property.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    private var _item:Object;
+
+    /**
+     *  The object being proxied.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    object_proxy function get object():Object
+    {
+        return _item;
+    }
+
+    //----------------------------------
+    //  type
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the qualified type name.
+     */
+    private var _type:QName;
+
+    /**
+     *  The qualified type name associated with this object.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    object_proxy function get type():QName
+    {
+        return _type;
+    }
+
+    /**
+     *  @private
+     */
+    object_proxy function set type(value:QName):void
+    {
+        _type = value;
+    }
+
+    //----------------------------------
+    //  uid
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the uid property.
+     */
+    private var _id:String;
+
+    /**
+     *  The unique identifier for this object.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function get uid():String
+    {
+        if (_id === null)
+            _id = UIDUtil.createUID();
+            
+        return _id;
+    }
+
+    /**
+     *  @private
+     */
+    public function set uid(value:String):void
+    {
+        _id = value;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Returns the specified property value of the proxied object.
+     *
+     *  @param name Typically a string containing the name of the property,
+     *  or possibly a QName where the property name is found by 
+     *  inspecting the <code>localName</code> property.
+     *
+     *  @return The value of the property.
+     *  In some instances this value may be an instance of 
+     *  <code>ObjectProxy</code>.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    override flash_proxy function getProperty(name:*):*
+    {
+        // if we have a data proxy for this then
+        var result:*;
+
+        if (notifiers[name.toString()])
+            return notifiers[name];
+
+        result = _item[name];
+
+        if (result)
+        {
+            if (_proxyLevel == 0 || ObjectUtil.isSimple(result))
+            {
+                return result;
+            }
+            else
+            {
+                result = object_proxy::getComplexProperty(name, result);
+            } // if we are proxying
+        }
+
+        return result;
+    }
+
+    /**
+     *  Returns the value of the proxied object's method with the specified name.
+     *
+     *  @param name The name of the method being invoked.
+     *
+     *  @param rest An array specifying the arguments to the
+     *  called method.
+     *
+     *  @return The return value of the called method.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    override flash_proxy function callProperty(name:*, ... rest):*
+    {
+        return _item[name].apply(_item, rest)
+    }
+
+    /**
+     *  Deletes the specified property on the proxied object and
+     *  sends notification of the delete to the handler.
+     * 
+     *  @param name Typically a string containing the name of the property,
+     *  or possibly a QName where the property name is found by 
+     *  inspecting the <code>localName</code> property.
+     *
+     *  @return A Boolean indicating if the property was deleted.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    override flash_proxy function deleteProperty(name:*):Boolean
+    {
+        var notifier:IPropertyChangeNotifier = IPropertyChangeNotifier(notifiers[name]);
+        if (notifier)
+        {
+            notifier.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,
+                                         propertyChangeHandler);
+            delete notifiers[name];
+        }
+
+        var oldVal:* = _item[name];
+        var deleted:Boolean = delete _item[name]; 
+
+        if (dispatcher.hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
+        {
+            var event:PropertyChangeEvent = new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
+            event.kind = PropertyChangeEventKind.DELETE;
+            event.property = name;
+            event.oldValue = oldVal;
+            event.source = this;
+            dispatcher.dispatchEvent(event);
+        }
+
+        return deleted;
+    }
+
+    /**
+     *  @private
+     */
+    override flash_proxy function hasProperty(name:*):Boolean
+    {
+        return(name in _item);
+    }
+    
+    /**
+     *  @private
+     */
+    override flash_proxy function nextName(index:int):String
+    {
+        return propertyList[index -1];
+    }
+    
+    /**
+     *  @private
+     */
+    override flash_proxy function nextNameIndex(index:int):int
+    {
+        if (index == 0)
+        {
+            setupPropertyList();
+        }
+        
+        if (index < propertyList.length)
+        {
+            return index + 1;
+        }
+        else
+        {
+            return 0;
+        }
+    }
+    
+    /**
+     *  @private
+     */
+    override flash_proxy function nextValue(index:int):*
+    {
+        return _item[propertyList[index -1]];
+    }
+
+    /**
+     *  Updates the specified property on the proxied object
+     *  and sends notification of the update to the handler.
+     *
+     *  @param name Object containing the name of the property that
+     *  should be updated on the proxied object.
+     *
+     *  @param value Value that should be set on the proxied object.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    override flash_proxy function setProperty(name:*, value:*):void
+    {
+        var oldVal:* = _item[name];
+        if (oldVal !== value)
+        {
+            // Update item.
+            _item[name] = value;
+
+            // Stop listening for events on old item if we currently are.
+            var notifier:IPropertyChangeNotifier =
+                IPropertyChangeNotifier(notifiers[name]);
+            if (notifier)
+            {
+                notifier.removeEventListener(
+                    PropertyChangeEvent.PROPERTY_CHANGE,
+                    propertyChangeHandler);
+                delete notifiers[name];
+            }
+
+            // Notify anyone interested.
+            if (dispatcher.hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
+            {
+                if (name is QName)
+                    name = QName(name).localName;
+                var event:PropertyChangeEvent =
+                    PropertyChangeEvent.createUpdateEvent(
+                        this, name.toString(), oldVal, value);
+                dispatcher.dispatchEvent(event);
+            } 
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  object_proxy methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Provides a place for subclasses to override how a complex property that
+     *  needs to be either proxied or daisy chained for event bubbling is managed.
+     * 
+     *  @param name Typically a string containing the name of the property,
+     *  or possibly a QName where the property name is found by 
+     *  inspecting the <code>localName</code> property.
+     *
+     *  @param value The property value.
+     *
+     *  @return The property value or an instance of <code>ObjectProxy</code>.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */  
+    object_proxy function getComplexProperty(name:*, value:*):*
+    {
+        if (value is IPropertyChangeNotifier)
+        {
+            value.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,
+                                   propertyChangeHandler);
+            notifiers[name] = value;
+            return value;
+        }
+        
+        if (getQualifiedClassName(value) == "Object")
+        {
+            value = new proxyClass(_item[name], null,
+                _proxyLevel > 0 ? _proxyLevel - 1 : _proxyLevel);
+            value.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,
+                                   propertyChangeHandler);
+            notifiers[name] = value;
+            return value;
+        }
+
+        return value;
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  IExternalizable Methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Since Flex only uses ObjectProxy to wrap anonymous objects,
+     *  the server flex.messaging.io.ObjectProxy instance serializes itself
+     *  as a Map that will be returned as a plain ActionScript object. 
+     *  You can then set the object_proxy object property to this value.
+     *
+     *  @param input The source object from which the ObjectProxy is
+     *  deserialized. 
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function readExternal(input:IDataInput):void
+    {
+        var value:Object = input.readObject();
+        _item = value;
+    }
+
+    /**
+     *  Since Flex only serializes the inner ActionScript object that it wraps,
+     *  the server flex.messaging.io.ObjectProxy populates itself
+     *  with this anonymous object's contents and appears to the user
+     *  as a Map.
+     *
+     *  @param output The source object from which the ObjectProxy is
+     *  deserialized.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function writeExternal(output:IDataOutput):void
+    {
+        output.writeObject(_item);
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Registers an event listener object  
+     *  so that the listener receives notification of an event. 
+     *  For more information, including descriptions of the parameters see 
+     *  <code>addEventListener()</code> in the 
+     *  flash.events.EventDispatcher class.
+     *
+     *  @param type The type of event.
+     *  
+     *  @param listener The listener function that processes the event. This function must accept
+     *  an Event object as its only parameter and must return nothing.
+     *  
+     *  @param useCapture Determines whether the listener works in the capture phase or the 
+     *  target and bubbling phases. If <code>useCapture</code> is set to <code>true</code>, 
+     *  the listener processes the event only during the capture phase and not in the 
+     *  target or bubbling phase. If <code>useCapture</code> is <code>false</code>, the
+     *  listener processes the event only during the target or bubbling phase. To listen for
+     *  the event in all three phases, call <code>addEventListener</code> twice, once with 
+     *  <code>useCapture</code> set to <code>true</code>, then again with
+     *  <code>useCapture</code> set to <code>false</code>.
+     * 
+     *  @param priority The priority level of the event listener. 
+     * 
+     *  @param useWeakReference Determines whether the reference to the listener is strong or
+     *  weak. A strong reference (the default) prevents your listener from being garbage-collected.
+     *  A weak reference does not. 
+     *
+     *  @see flash.events.EventDispatcher#addEventListener()
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function addEventListener(type:String, listener:Function,
+                                     useCapture:Boolean = false,
+                                     priority:int = 0,
+                                     useWeakReference:Boolean = false):void
+    {
+        dispatcher.addEventListener(type, listener, useCapture,
+                                    priority, useWeakReference);
+    }
+
+    /**
+     *  Removes an event listener. 
+     *  If there is no matching listener registered with the EventDispatcher object, 
+     *  a call to this method has no effect.
+     *  For more information, see 
+     *  the flash.events.EventDispatcher class.
+     *  
+     *  @param type The type of event.
+     * 
+     *  @param listener The listener object to remove.
+     *
+     *  @param useCapture Specifies whether the listener was registered for the capture 
+     *  phase or the target and bubbling phases. If the listener was registered for both 
+     *  the capture phase and the target and bubbling phases, two calls to 
+     *  <code>removeEventListener()</code> are required to remove both, one call with 
+     *  <code>useCapture</code> 
+     *  set to <code>true</code>, and another call with <code>useCapture</code>
+     *  set to <code>false</code>.
+     *
+     *  @see flash.events.EventDispatcher#removeEventListener()
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function removeEventListener(type:String, listener:Function,
+                                        useCapture:Boolean = false):void
+    {
+        dispatcher.removeEventListener(type, listener, useCapture);
+    }
+
+    /**
+     *  Dispatches an event into the event flow. 
+     *  For more information, see
+     *  the flash.events.EventDispatcher class.
+     *  
+     *  @param event The Event object that is dispatched into the event flow. If the 
+     *  event is being redispatched, a clone of the event is created automatically. 
+     *  After an event is dispatched, its target property cannot be changed, so you 
+     *  must create a new copy of the event for redispatching to work.
+     *
+     *  @return Returns <code>true</code> if the event was successfully dispatched. 
+     *  A value 
+     *  of <code>false</code> indicates failure or that <code>preventDefault()</code>
+     *  was called on the event.
+     *
+     *  @see flash.events.EventDispatcher#dispatchEvent()
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function dispatchEvent(event:Event):Boolean
+    {
+        return dispatcher.dispatchEvent(event);
+    }
+    
+    /**
+     *  Checks whether there are any event listeners registered 
+     *  for a specific type of event. 
+     *  This allows you to determine where an object has altered handling 
+     *  of an event type in the event flow hierarchy. 
+     *  For more information, see
+     *  the flash.events.EventDispatcher class.
+     *
+     *  @param type The type of event
+     *
+     *  @return Returns <code>true</code> if a listener of the specified type is 
+     *  registered; <code>false</code> otherwise.
+     *
+     *  @see flash.events.EventDispatcher#hasEventListener()
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function hasEventListener(type:String):Boolean
+    {
+        return dispatcher.hasEventListener(type);
+    }
+    
+    /**
+     *  Checks whether an event listener is registered with this object 
+     *  or any of its ancestors for the specified event type. 
+     *  This method returns <code>true</code> if an event listener is triggered 
+     *  during any phase of the event flow when an event of the specified 
+     *  type is dispatched to this object or any of its descendants.
+     *  For more information, see the flash.events.EventDispatcher class.
+     *
+     *  @param type The type of event.
+     *
+     *  @return Returns <code>true</code> if a listener of the specified type will 
+     *  be triggered; <code>false</code> otherwise.
+     *
+     *  @see flash.events.EventDispatcher#willTrigger()
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function willTrigger(type:String):Boolean
+    {
+        return dispatcher.willTrigger(type);
+    }
+
+    /**
+     *  Called when a complex property is updated.
+     *
+     *  @param event An event object that has changed.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function propertyChangeHandler(event:PropertyChangeEvent):void
+    {
+        dispatcher.dispatchEvent(event);
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  Protected Methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  This method creates an array of all of the property names for the 
+     *  proxied object.
+     *  Descendants must override this method if they wish to add more 
+     *  properties to this list.
+     *  Be sure to call <code>super.setupPropertyList</code> before making any
+     *  changes to the <code>propertyList</code> property.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    protected function setupPropertyList():void
+    {
+        if (getQualifiedClassName(_item) == "Object")
+        {
+            propertyList = [];
+            for (var prop:String in _item)
+                propertyList.push(prop);
+        }
+        else
+        {
+            propertyList = ObjectUtil.getClassInfo(_item, null, {includeReadOnly:true, uris:["*"]}).properties;
+        }
+    }
+}
+
+}