This is an automated email from the ASF dual-hosted git repository.
pent pushed a commit to branch feature/MXRoyale
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
The following commit(s) were added to refs/heads/feature/MXRoyale by this push:
new 3135e47 ArrayList and ArrayUtil now compile along some ancillary
classes.
3135e47 is described below
commit 3135e4747505fc6439cbdf105377419b6daf129d
Author: Peter Ent <[email protected]>
AuthorDate: Thu Mar 29 16:51:51 2018 -0400
ArrayList and ArrayUtil now compile along some ancillary classes.
---
.../MXRoyale/src/main/royale/MXRoyaleClasses.as | 2 +
.../src/main/royale/mx/collections/ArrayList.as | 849 +++++++++++++++
.../src/main/royale/mx/collections/IList.as | 271 +++++
.../src/main/royale/mx/events/CollectionEvent.as | 281 +++++
.../main/royale/mx/events/CollectionEventKind.as | 133 +++
.../main/royale/mx/events/PropertyChangeEvent.as | 282 +++++
.../royale/mx/events/PropertyChangeEventKind.as | 63 ++
.../MXRoyale/src/main/royale/mx/utils/ArrayUtil.as | 215 ++++
.../src/main/royale/mx/utils/ObjectProxy.as | 831 ++++++++++++++
.../src/main/royale/mx/utils/ObjectUtil.as | 1130 ++++++++++++++++++++
10 files changed, 4057 insertions(+)
diff --git a/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
b/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
index 39b68a1..9c62e94 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
@@ -27,6 +27,7 @@ package
*/
internal class MXRoyaleClasses
{
+ import mx.collections.ArrayList; ArrayList;
import mx.core.UIComponent; UIComponent;
import mx.core.Container; Container;
import mx.containers.beads.ApplicationLayout; ApplicationLayout;
@@ -34,6 +35,7 @@ internal class MXRoyaleClasses
import mx.containers.beads.CanvasLayout; CanvasLayout;
import mx.controls.ToolTip; ToolTip;
import mx.controls.beads.ToolTipBead; ToolTipBead;
+ import mx.utils.ArrayUtil; ArrayUtil;
COMPILE::SWF
{
diff --git
a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ArrayList.as
b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ArrayList.as
new file mode 100644
index 0000000..e6606ac
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/ArrayList.as
@@ -0,0 +1,849 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.collections
+{
+COMPILE::JS {
+ import goog.DEBUG;
+}
+import mx.events.CollectionEvent;
+import mx.events.CollectionEventKind;
+import mx.events.PropertyChangeEvent;
+import mx.events.PropertyChangeEventKind;
+
+import org.apache.royale.events.Event;
+import org.apache.royale.events.EventDispatcher;
+import org.apache.royale.events.IEventDispatcher;
+/*
+import mx.resources.IResourceManager;
+import mx.resources.ResourceManager;
+*/
+import mx.utils.ArrayUtil;
+/*
+import mx.utils.UIDUtil;
+*/
+
+//--------------------------------------
+// Events
+//--------------------------------------
+
+/**
+ * Dispatched when the IList has been updated in some way.
+ *
+ * @eventType mx.events.CollectionEvent.COLLECTION_CHANGE
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+[Event(name="collectionChange", type="mx.events.CollectionEvent")]
+
+[DefaultProperty("source")]
+
+/**
+ * The ArrayList class is a simple implementation of IList
+ * that uses a backing Array as the source of the data.
+ *
+ * Items in the backing Array can be accessed and manipulated
+ * using the methods and properties of the <code>IList</code>
+ * interface. Operations on an ArrayList instance modify the
+ * data source; for example, if you use the <code>removeItemAt()</code>
+ * method on an ArrayList, you remove the item from the underlying
+ * Array.
+ *
+ * This base class will not throw ItemPendingErrors but it
+ * is possible that a subclass might.
+ *
+ * <pre>
+ * <mx:ArrayList
+ * <b>Properties</b>
+ * source="null"
+ * />
+ * </pre>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Flex 4
+ */
+public class ArrayList extends EventDispatcher
+ implements IList//, IExternalizable, IPropertyChangeNotifier
+{
+
//--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+
//--------------------------------------------------------------------------
+
+ /**
+ * Construct a new ArrayList using the specified array as its source.
+ * If no source is specified an empty array will be used.
+ *
+ * @param source The Array to use as a source for the ArrayList.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function ArrayList(source:Array = null)
+ {
+ super();
+
+ disableEvents();
+ this.source = source;
+ enableEvents();
+ }
+
+
//--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+
//--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Used for accessing localized Error messages.
+ */
+// private var resourceManager:IResourceManager =
+// ResourceManager.getInstance();
+
+ /**
+ * @private
+ * Indicates if events should be dispatched.
+ * calls to enableEvents() and disableEvents() effect the value when == 0
+ * events should be dispatched.
+ */
+ private var _dispatchEvents:int = 0;
+
+
//--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+
//--------------------------------------------------------------------------
+
+ //----------------------------------
+ // length
+ //----------------------------------
+
+ [Bindable("collectionChange")]
+
+ /**
+ * Get the number of items in the list. An ArrayList should always
+ * know its length so it shouldn't return -1, though a subclass may
+ * override that behavior.
+ *
+ * @return int representing the length of the source.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get length():int
+ {
+ if (source)
+ return source.length;
+ else
+ return 0;
+ }
+
+ //----------------------------------
+ // source
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the source Array.
+ */
+ private var _source:Array;
+
+ /**
+ * The source array for this ArrayList.
+ * Any changes done through the IList interface will be reflected in the
+ * source array.
+ * If no source array was supplied the ArrayList will create one
internally.
+ * Changes made directly to the underlying Array (e.g., calling
+ * <code>theList.source.pop()</code> will not cause
<code>CollectionEvents</code>
+ * to be dispatched.
+ *
+ * @return An Array that represents the underlying source.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get source():Array
+ {
+ return _source;
+ }
+
+ public function set source(s:Array):void
+ {
+ var i:int;
+ var len:int;
+ if (_source && _source.length)
+ {
+ len = _source.length;
+ for (i = 0; i < len; i++)
+ {
+ stopTrackUpdates(_source[i]);
+ }
+ }
+ _source = s ? s : [];
+ len = _source.length;
+ for (i = 0; i < len; i++)
+ {
+ startTrackUpdates(_source[i]);
+ }
+
+ if (_dispatchEvents == 0)
+ {
+ var event:CollectionEvent =
+ new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ event.kind = CollectionEventKind.RESET;
+ dispatchEvent(event);
+ }
+ }
+
+ //----------------------------------
+ // uid -- mx.core.IPropertyChangeNotifier
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the UID String.
+ */
+ private var _uid:String;
+
+ /**
+ * Provides access to the unique id for this list.
+ *
+ * @return String representing the internal uid.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get uid():String
+ {
+ if (!_uid) {
+ //_uid = UIDUtil.createUID();
+ if (GOOG::DEBUG)
+ trace("get_uid not implemented");
+ }
+ return _uid;
+ }
+
+ public function set uid(value:String):void
+ {
+ _uid = value;
+ }
+
+
//--------------------------------------------------------------------------
+ //
+ // Methods
+ //
+
//--------------------------------------------------------------------------
+
+ /**
+ * Converts an Array List to JavaScript Object Notation (JSON) format.
+ * Called by the JSON.stringify() method and should not be called
directly.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Apache Flex 4.12
+ */
+// public function toJSON(s:String):*
+// {
+// return toArray();
+// }
+
+ /**
+ * Get the item at the specified index.
+ *
+ * @param index the index in the list from which to retrieve the item
+ * @param prefetch int indicating both the direction and amount of items
+ * to fetch during the request should the item not be local.
+ * @return the item at that index, null if there is none
+ * @throws ItemPendingError if the data for that index needs to be
+ * loaded from a remote location
+ * @throws RangeError if the index < 0 or index >= length
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function getItemAt(index:int, prefetch:int = 0):Object
+ {
+ if (index < 0 || index >= length)
+ {
+// var message:String = resourceManager.getString(
+// "collections", "outOfBounds", [ index ]);
+// throw new RangeError(message);
+ if( GOOG::DEBUG)
+ trace("getItemAt throwing RangeError - not
implemented");
+ return null;
+ }
+
+ return source[index];
+ }
+
+ /**
+ * Place the item at the specified index.
+ * If an item was already at that index the new item will replace it and
it
+ * will be returned.
+ *
+ * @param item the new value for the index
+ * @param index the index at which to place the item
+ * @return the item that was replaced, null if none
+ * @throws RangeError if index is less than 0 or greater than or equal to
length
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function setItemAt(item:Object, index:int):Object
+ {
+ if (index < 0 || index >= length)
+ {
+// var message:String = resourceManager.getString(
+// "collections", "outOfBounds", [ index ]);
+// throw new RangeError(message);
+ if (GOOG::DEBUG)
+ trace("setItemAt throwing RangeError - not
implemented");
+ return null;
+ }
+
+ var oldItem:Object = source[index];
+ source[index] = item;
+ stopTrackUpdates(oldItem);
+ startTrackUpdates(item);
+
+ //dispatch the appropriate events
+ if (_dispatchEvents == 0)
+ {
+ var hasCollectionListener:Boolean =
+ hasEventListener(CollectionEvent.COLLECTION_CHANGE);
+ var hasPropertyListener:Boolean =
+ hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE);
+ var updateInfo:PropertyChangeEvent;
+
+ if (hasCollectionListener || hasPropertyListener)
+ {
+ updateInfo = new
PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
+ updateInfo.kind = PropertyChangeEventKind.UPDATE;
+ updateInfo.oldValue = oldItem;
+ updateInfo.newValue = item;
+ updateInfo.property = index;
+ }
+
+ if (hasCollectionListener)
+ {
+ var event:CollectionEvent =
+ new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ event.kind = CollectionEventKind.REPLACE;
+ event.location = index;
+ event.items.push(updateInfo);
+ dispatchEvent(event);
+ }
+
+ if (hasPropertyListener)
+ {
+ dispatchEvent(updateInfo);
+ }
+ }
+ return oldItem;
+ }
+
+ /**
+ * Add the specified item to the end of the list.
+ * Equivalent to addItemAt(item, length);
+ *
+ * @param item the item to add
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function addItem(item:Object):void
+ {
+ addItemAt(item, length);
+ }
+
+ /**
+ * Add the item at the specified index.
+ * Any item that was after this index is moved out by one.
+ *
+ * @param item the item to place at the index
+ * @param index the index at which to place the item
+ * @throws RangeError if index is less than 0 or greater than the length
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function addItemAt(item:Object, index:int):void
+ {
+ const spliceUpperBound:int = length;
+
+ if (index < spliceUpperBound && index > 0)
+ {
+ source.splice(index, 0, item);
+ }
+ else if (index == spliceUpperBound)
+ {
+ source.push(item);
+ }
+ else if (index == 0)
+ {
+ source.unshift(item);
+ }
+ else
+ {
+// var message:String = resourceManager.getString(
+// "collections", "outOfBounds", [ index ]);
+// throw new RangeError(message);
+ if (GOOG::DEBUG)
+ trace("addItemAt throwing RangeError - not
implemented");
+ return;
+ }
+
+ startTrackUpdates(item);
+ internalDispatchEvent(CollectionEventKind.ADD, item, index);
+ }
+
+ /**
+ * @copy mx.collections.ListCollectionView#addAll()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function addAll(addList:IList):void
+ {
+ addAllAt(addList, length);
+ }
+
+ /**
+ * @copy mx.collections.ListCollectionView#addAllAt()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function addAllAt(addList:IList, index:int):void
+ {
+ const addListLength:int = addList.length;
+ if (addListLength == 0)
+ return;
+
+ const addedItems:Array = [];
+
+ disableEvents();
+ for (var i:int = 0; i < addListLength; i++)
+ {
+ var item:Object = addList.getItemAt(i);
+ this.addItemAt(item, i + index);
+ addedItems.push(item);
+ }
+ enableEvents();
+
+ if (_dispatchEvents == 0)
+ {
+ const event:CollectionEvent = new
CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ event.kind = CollectionEventKind.ADD;
+ event.location = index;
+ event.items = addedItems;
+ dispatchEvent(event);
+ }
+ }
+
+ /**
+ * Return the index of the item if it is in the list such that
+ * getItemAt(index) == item.
+ * Note that in this implementation the search is linear and is therefore
+ * O(n).
+ *
+ * @param item the item to find
+ * @return the index of the item, -1 if the item is not in the list.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function getItemIndex(item:Object):int
+ {
+ return ArrayUtil.getItemIndex(item, source);
+ }
+
+ /**
+ * Removes the specified item from this list, should it exist.
+ *
+ * @param item Object reference to the item that should be removed.
+ * @return Boolean indicating if the item was removed.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function removeItem(item:Object):Boolean
+ {
+ var index:int = getItemIndex(item);
+ var result:Boolean = index >= 0;
+ if (result)
+ removeItemAt(index);
+
+ return result;
+ }
+
+ /**
+ * Remove the item at the specified index and return it.
+ * Any items that were after this index are now one index earlier.
+ *
+ * @param index The index from which to remove the item.
+ * @return The item that was removed.
+ * @throws RangeError if index < 0 or index >= length.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function removeItemAt(index:int):Object
+ {
+ const spliceUpperBound:int = length - 1;
+ var removed:Object;
+
+ if (index > 0 && index < spliceUpperBound)
+ {
+ removed = source.splice(index, 1)[0];
+ }
+ else if (index == spliceUpperBound)
+ {
+ removed = source.pop();
+ }
+ else if (index == 0)
+ {
+ removed = source.shift();
+ }
+ else
+ {
+// var message:String = resourceManager.getString(
+// "collections", "outOfBounds", [ index ]);
+// throw new RangeError(message);
+ if (GOOG::DEBUG)
+ trace("removeItemAt throwing RangeError - not
implemented");
+ return null;
+ }
+
+ stopTrackUpdates(removed);
+ internalDispatchEvent(CollectionEventKind.REMOVE, removed, index);
+ return removed;
+ }
+
+ /**
+ * Remove all items from the list.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function removeAll():void
+ {
+ if (length > 0)
+ {
+ var len:int = length;
+ for (var i:int = 0; i < len; i++)
+ {
+ stopTrackUpdates(source[i]);
+ }
+
+ source.splice(0, length);
+ internalDispatchEvent(CollectionEventKind.RESET);
+ }
+ }
+
+ /**
+ * Notify the view that an item has been updated.
+ * This is useful if the contents of the view do not implement
+ * <code>IEventDispatcher</code>.
+ * If a property is specified the view may be able to optimize its
+ * notification mechanism.
+ * Otherwise it may choose to simply refresh the whole view.
+ *
+ * @param item The item within the view that was updated.
+ *
+ * @param property A String, QName, or int
+ * specifying the property that was updated.
+ *
+ * @param oldValue The old value of that property.
+ * (If property was null, this can be the old value of the item.)
+ *
+ * @param newValue The new value of that property.
+ * (If property was null, there's no need to specify this
+ * as the item is assumed to be the new value.)
+ *
+ * @see mx.events.CollectionEvent
+ * @see mx.core.IPropertyChangeNotifier
+ * @see mx.events.PropertyChangeEvent
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function itemUpdated(item:Object, property:Object = null,
+ oldValue:Object = null,
+ newValue:Object = null):void
+ {
+ var event:PropertyChangeEvent = new
PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
+
+ event.kind = PropertyChangeEventKind.UPDATE;
+ event.source = item;
+ event.property = property;
+ event.oldValue = oldValue;
+ event.newValue = newValue;
+
+ if(!property)
+ {
+ stopTrackUpdates(oldValue);
+ startTrackUpdates(newValue);
+ }
+
+ itemUpdateHandler(event);
+ }
+
+ /**
+ * Return an Array that is populated in the same order as the IList
+ * implementation.
+ *
+ * @return An Array populated in the same order as the IList
+ * implementation.
+ *
+ * @throws ItemPendingError if the data is not yet completely loaded
+ * from a remote location
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function toArray():Array
+ {
+ return source.concat();
+ }
+
+ /**
+ * Ensures that only the source property is serialized.
+ * @private
+ */
+// public function readExternal(input:IDataInput):void
+// {
+// source = input.readObject();
+// }
+
+ /**
+ * Ensures that only the source property is serialized.
+ * @private
+ */
+// public function writeExternal(output:IDataOutput):void
+// {
+// output.writeObject(_source);
+// }
+
+ /**
+ * Pretty prints the contents of this ArrayList to a string and returns
it.
+ *
+ * @return A String containing the contents of the ArrayList.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ override public function toString():String
+ {
+ if (source)
+ return source.toString();
+// else
+// return getQualifiedClassName(this);
+ if (GOOG::DEBUG)
+ trace("toString using getQualifiedClassName not
implemented");
+ return "<ArrayList>";
+ }
+
+
//--------------------------------------------------------------------------
+ //
+ // Internal Methods
+ //
+
//--------------------------------------------------------------------------
+
+ /**
+ * Enables event dispatch for this list.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function enableEvents():void
+ {
+ _dispatchEvents++;
+ if (_dispatchEvents > 0)
+ _dispatchEvents = 0;
+ }
+
+ /**
+ * Disables event dispatch for this list.
+ * To re-enable events call enableEvents(), enableEvents() must be called
+ * a matching number of times as disableEvents().
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function disableEvents():void
+ {
+ _dispatchEvents--;
+ }
+
+ /**
+ * Dispatches a collection event with the specified information.
+ *
+ * @param kind String indicates what the kind property of the event
should be
+ * @param item Object reference to the item that was added or removed
+ * @param location int indicating where in the source the item was added.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private function internalDispatchEvent(kind:String, item:Object = null,
location:int = -1):void
+ {
+ if (_dispatchEvents == 0)
+ {
+ if (hasEventListener(CollectionEvent.COLLECTION_CHANGE))
+ {
+ var event:CollectionEvent = new
CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
+ event.kind = kind;
+ if(kind != CollectionEventKind.RESET && kind !=
CollectionEventKind.REFRESH)
+ event.items.push(item);
+ event.location = location;
+ dispatchEvent(event);
+ }
+
+ // now dispatch a complementary PropertyChangeEvent
+ if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE) &&
+ (kind == CollectionEventKind.ADD || kind ==
CollectionEventKind.REMOVE))
+ {
+ var objEvent:PropertyChangeEvent = new
PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
+ objEvent.property = location;
+ if (kind == CollectionEventKind.ADD)
+ objEvent.newValue = item;
+ else
+ objEvent.oldValue = item;
+ dispatchEvent(objEvent);
+ }
+ }
+ }
+
+ /**
+ * Called when any of the contained items in the list dispatches a
+ * <code>PropertyChangeEvent</code>.
+ * Wraps it in a <code>CollectionEventKind.UPDATE</code> object.
+ *
+ * @param event The event object for the <code>PropertyChangeEvent</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected function itemUpdateHandler(event:PropertyChangeEvent):void
+ {
+ internalDispatchEvent(CollectionEventKind.UPDATE, event);
+ // need to dispatch object event now
+ if (_dispatchEvents == 0 &&
hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
+ {
+ var objEvent:PropertyChangeEvent =
PropertyChangeEvent(event.cloneEvent());
+ var index:uint = getItemIndex(event.target);
+ objEvent.property = index.toString() + "." + event.property;
+ dispatchEvent(objEvent);
+ }
+ }
+
+ /**
+ * If the item is an IEventDispatcher, watch it for updates.
+ * This method is called by the <code>addItemAt()</code> method,
+ * and when the source is initially assigned.
+ *
+ * @param item The item passed to the <code>addItemAt()</code> method.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected function startTrackUpdates(item:Object):void
+ {
+ if (item && (item is IEventDispatcher))
+ {
+
//IEventDispatcher(item).addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,
itemUpdateHandler, false, 0, true);
+
IEventDispatcher(item).addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,
itemUpdateHandler, false);
+ }
+ }
+
+ /**
+ * If the item is an IEventDispatcher, stop watching it for updates.
+ * This method is called by the <code>removeItemAt()</code> and
+ * <code>removeAll()</code> methods, and before a new
+ * source is assigned.
+ *
+ * @param item The item passed to the <code>removeItemAt()</code> method.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected function stopTrackUpdates(item:Object):void
+ {
+ if (item && item is IEventDispatcher)
+ {
+
IEventDispatcher(item).removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,
itemUpdateHandler);
+ }
+ }
+}
+}
diff --git
a/frameworks/projects/MXRoyale/src/main/royale/mx/collections/IList.as
b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/IList.as
new file mode 100644
index 0000000..399f7a0
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/collections/IList.as
@@ -0,0 +1,271 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.collections
+{
+
+import org.apache.royale.events.IEventDispatcher;
+import mx.events.CollectionEvent;
+
+/**
+ * Dispatched when the IList has been updated in some way.
+ *
+ * @eventType mx.events.CollectionEvent.COLLECTION_CHANGE
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+[Event(name="collectionChange", type="mx.events.CollectionEvent")]
+
+/**
+ * A collection of items organized in an ordinal fashion.
+ * Provides access and manipulation methods based on index.
+ *
+ * <p>An <code>IList</code> may be a view onto data
+ * that has been retrieved from a remote location.
+ * When writing for a collection that may be remote,
+ * it is important to handle the case where data
+ * may not yet be available, which is indicated
+ * by the <code>ItemPendingError</code>.</p>
+ *
+ * <p>The <code>ICollectionView</code> is an alternative
+ * to the <code>IList</code>.</p>
+ *
+ * @see mx.collections.errors.ItemPendingError
+ * @see mx.collections.ICollectionView
+ * @see mx.collections.ListCollectionView
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public interface IList extends IEventDispatcher
+{
+
//--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+
//--------------------------------------------------------------------------
+
+ //----------------------------------
+ // length
+ //----------------------------------
+
+ /**
+ * The number of items in this collection.
+ * 0 means no items while -1 means the length is unknown.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function get length():int;
+
+
//--------------------------------------------------------------------------
+ //
+ // Methods
+ //
+
//--------------------------------------------------------------------------
+
+ /**
+ * Adds the specified item to the end of the list.
+ * Equivalent to <code>addItemAt(item, length)</code>.
+ *
+ * @param item The item to add.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function addItem(item:Object):void;
+
+ /**
+ * Adds the item at the specified index.
+ * The index of any item greater than the index of the added item is
increased by one.
+ * If the the specified index is less than zero or greater than the length
+ * of the list, a RangeError is thrown.
+ *
+ * @param item The item to place at the index.
+ *
+ * @param index The index at which to place the item.
+ *
+ * @throws RangeError if index is less than 0 or greater than the length
of the list.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function addItemAt(item:Object, index:int):void;
+
+ /**
+ * Gets the item at the specified index.
+ *
+ * @param index The index in the list from which to retrieve the item.
+ *
+ * @param prefetch An <code>int</code> indicating both the direction
+ * and number of items to fetch during the request if the item is
+ * not local.
+ *
+ * @return The item at that index, or <code>null</code> if there is none.
+ *
+ * @throws mx.collections.errors.ItemPendingError if the data for that
index needs to be
+ * loaded from a remote location.
+ *
+ * @throws RangeError if <code>index < 0</code>
+ * or <code>index >= length</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function getItemAt(index:int, prefetch:int = 0):Object;
+
+ /**
+ * Returns the index of the item if it is in the list such that
+ * getItemAt(index) == item.
+ *
+ * <p>Note: unlike <code>IViewCursor.find<i>xxx</i>()</code> methods,
+ * The <code>getItemIndex()</code> method cannot take a parameter with
+ * only a subset of the fields in the item being serched for;
+ * this method always searches for an item that exactly matches
+ * the input parameter.</p>
+ *
+ * @param item The item to find.
+ *
+ * @return The index of the item, or -1 if the item is not in the list.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function getItemIndex(item:Object):int;
+
+ /**
+ * Notifies the view that an item has been updated.
+ * This is useful if the contents of the view do not implement
+ * <code>IEventDispatcher</code> and dispatches a
+ * <code>PropertyChangeEvent</code>.
+ * If a property is specified the view may be able to optimize its
+ * notification mechanism.
+ * Otherwise it may choose to simply refresh the whole view.
+ *
+ * @param item The item within the view that was updated.
+ *
+ * @param property The name of the property that was updated.
+ *
+ * @param oldValue The old value of that property. (If property was null,
+ * this can be the old value of the item.)
+ *
+ * @param newValue The new value of that property. (If property was null,
+ * there's no need to specify this as the item is assumed to be
+ * the new value.)
+ *
+ * @see mx.events.CollectionEvent
+ * @see mx.events.PropertyChangeEvent
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function itemUpdated(item:Object, property:Object = null,
+ oldValue:Object = null,
+ newValue:Object = null):void;
+
+ /**
+ * Removes all items from the list.
+ *
+ * <p>If any item is not local and an asynchronous operation must be
+ * performed, an <code>ItemPendingError</code> will be thrown.</p>
+ *
+ * <p>See the ItemPendingError documentation as well as
+ * the collections documentation for more information
+ * on using the <code>ItemPendingError</code>.</p>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function removeAll():void;
+
+ /**
+ * Removes the item at the specified index and returns it.
+ * Any items that were after this index are now one index earlier.
+ *
+ * @param index The index from which to remove the item.
+ *
+ * @return The item that was removed.
+ *
+ * @throws RangeError is index is less than 0 or greater than length.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function removeItemAt(index:int):Object;
+
+ /**
+ * Places the item at the specified index.
+ * If an item was already at that index the new item will replace it
+ * and it will be returned.
+ *
+ * @param item The new item to be placed at the specified index.
+ *
+ * @param index The index at which to place the item.
+ *
+ * @return The item that was replaced, or <code>null</code> if none.
+ *
+ * @throws RangeError if index is less than 0 or greater than length.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function setItemAt(item:Object, index:int):Object;
+
+ /**
+ * Returns an Array that is populated in the same order as the IList
+ * implementation.
+ * This method can throw an ItemPendingError.
+ *
+ * @return The array.
+ *
+ * @throws mx.collections.errors.ItemPendingError If the data is not yet
completely loaded
+ * from a remote location.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function toArray():Array;
+}
+
+}
diff --git
a/frameworks/projects/MXRoyale/src/main/royale/mx/events/CollectionEvent.as
b/frameworks/projects/MXRoyale/src/main/royale/mx/events/CollectionEvent.as
new file mode 100644
index 0000000..370057a
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/events/CollectionEvent.as
@@ -0,0 +1,281 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.events
+{
+COMPILE::JS {
+ import goog.DEBUG;
+}
+
+import org.apache.royale.events.Event;
+import org.apache.royale.events.IRoyaleEvent;
+
+/**
+ * The mx.events.CollectionEvent class represents an event that is
+ * dispatched when the associated collection changes.
+ *
+ * @see FlexEvent#CURSOR_UPDATE
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public class CollectionEvent extends Event
+{
+
//--------------------------------------------------------------------------
+ //
+ // Class constants
+ //
+
//--------------------------------------------------------------------------
+
+ /**
+ * The CollectionEvent.COLLECTION_CHANGE constant defines the value of the
+ * <code>type</code> property of the event object for an event that is
+ * dispatched when a collection has changed.
+ *
+ * <p>The properties of the event object have the following values.
+ * Not all properties are meaningful for all kinds of events.
+ * See the detailed property descriptions for more information.</p>
+ * <table class="innertable">
+ * <tr><th>Property</th><th>Value</th></tr>
+ * <tr><td><code>bubbles</code></td><td>false</td></tr>
+ * <tr><td><code>cancelable</code></td><td>false</td></tr>
+ * <tr><td><code>currentTarget</code></td><td>The Object that defines
the
+ * event listener that handles the event. For example, if you use
+ * <code>myButton.addEventListener()</code> to register an event
listener,
+ * myButton is the value of the <code>currentTarget</code>.
</td></tr>
+ * <tr><td><code>items</code></td><td>An Array of objects with
+ * information about the items affected by the event.
+ * The contents of this field depend on the event kind;
+ * for details see the <code>items</code> property</td></tr>
+ * <tr><td><code>kind</code></td><td>The kind of event.
+ * The valid values are defined in the CollectionEventKind
+ * class as constants.</td></tr>
+ * <tr><td><code>location</code></td><td>Location within the target
collection
+ * of the item(s) specified in the <code>items</code>
property.</td></tr>
+ * <tr><td><code>oldLocation</code></td><td>the previous location in
the collection
+ * of the item specified in the <code>items</code>
property.</td></tr>
+ * <tr><td><code>target</code></td><td>The Object that dispatched the
event;
+ * it is not always the Object listening for the event.
+ * Use the <code>currentTarget</code> property to always access the
+ * Object listening for the event.</td></tr>
+ *
<tr><td><code>type</code></td><td>CollectionEvent.COLLECTION_CHANGE</td></tr>
+ * </table>
+ *
+ * @eventType collectionChange
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const COLLECTION_CHANGE:String = "collectionChange";
+
+
//--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+
//--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * @param type The event type; indicates the action that triggered the
event.
+ *
+ * @param bubbles Specifies whether the event can bubble
+ * up the display list hierarchy.
+ *
+ * @param cancelable Specifies whether the behavior
+ * associated with the event can be prevented.
+ *
+ * @param kind Indicates the kind of event that occured.
+ * The parameter value can be one of the values in the
CollectionEventKind
+ * class, or <code>null</code>, which indicates that the kind is
unknown.
+ *
+ * @param location When the <code>kind</code> is
+ * <code>CollectionEventKind.ADD</code>,
+ * <code>CollectionEventKind.MOVE</code>,
+ * <code>CollectionEventKind.REMOVE</code>, or
+ * <code>CollectionEventKind.REPLACE</code>,
+ * this value indicates at what location the item(s) specified
+ * in the <code>items property</code> can be found
+ * within the target collection.
+ *
+ * @param oldLocation When the <code>kind</code> is
+ * <code>CollectionEventKind.MOVE</code>, this value indicates
+ * the old location within the target collection
+ * of the item(s) specified in the <code>items</code> property.
+ *
+ * @param items Array of objects with information about the items
+ * affected by the event, as described in the <code>items</code>
property.
+ * When the <code>kind</code> is <code>CollectionEventKind.REFRESH</code>
+ * or <code>CollectionEventKind.RESET</code>, this Array has zero length.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function CollectionEvent(type:String, bubbles:Boolean = false,
+ cancelable:Boolean = false,
+ kind:String = null, location:int = -1,
+ oldLocation:int = -1, items:Array = null)
+ {
+ super(type, bubbles, cancelable);
+
+ this.kind = kind;
+ this.location = location;
+ this.oldLocation = oldLocation;
+ this.items = items ? items : [];
+ }
+
+
//--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+
//--------------------------------------------------------------------------
+
+ //----------------------------------
+ // kind
+ //----------------------------------
+
+ /**
+ * Indicates the kind of event that occurred.
+ * The property value can be one of the values in the
+ * CollectionEventKind class,
+ * or <code>null</code>, which indicates that the kind is unknown.
+ *
+ * @default null
+ *
+ * @see CollectionEventKind
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public var kind:String;
+
+ //----------------------------------
+ // items
+ //----------------------------------
+
+ /**
+ * When the <code>kind</code> is <code>CollectionEventKind.ADD</code>
+ * or <code>CollectionEventKind.REMOVE</code> the <code>items</code>
property
+ * is an Array of added/removed items.
+ * When the <code>kind</code> is
<code>CollectionEventKind.REPLACE</code>
+ * or <code>CollectionEventKind.UPDATE</code> the <code>items</code>
property
+ * is an Array of PropertyChangeEvent objects with information about the
items
+ * affected by the event.
+ * When a value changes, query the <code>newValue</code> and
+ * <code>oldValue</code> fields of the PropertyChangeEvent objects
+ * to find out what the old and new values were.
+ * When the <code>kind</code> is <code>CollectionEventKind.REFRESH</code>
+ * or <code>CollectionEventKind.RESET</code>, this array has zero length.
+ *
+ * @default [ ]
+ *
+ * @see PropertyChangeEvent
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public var items:Array;
+
+ //----------------------------------
+ // location
+ //----------------------------------
+
+ /**
+ * When the <code>kind</code> value is
<code>CollectionEventKind.ADD</code>,
+ * <code>CollectionEventKind.MOVE</code>,
+ * <code>CollectionEventKind.REMOVE</code>, or
+ * <code>CollectionEventKind.REPLACE</code>, this property is the
+ * zero-base index in the collection of the item(s) specified in the
+ * <code>items</code> property.
+ *
+ * @see CollectionEventKind
+ *
+ * @default -1
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public var location:int;
+
+ //----------------------------------
+ // oldLocation
+ //----------------------------------
+
+ /**
+ * When the <code>kind</code> value is
<code>CollectionEventKind.MOVE</code>,
+ * this property is the zero-based index in the target collection of the
+ * previous location of the item(s) specified by the <code>items</code>
property.
+ *
+ * @default -1
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public var oldLocation:int;
+
+
//--------------------------------------------------------------------------
+ //
+ // Overridden methods: Object
+ //
+
//--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ COMPILE::SWF
+ override public function toString():String
+ {
+// return formatToString("CollectionEvent", "kind", "location",
+// "oldLocation",
"type", "bubbles",
+// "cancelable",
"eventPhase");
+ if (GOOG::DEBUG)
+ trace("toString not implemented");
+ return "<CollectionEvent>";
+ }
+
+
//--------------------------------------------------------------------------
+ //
+ // Overridden methods: Event
+ //
+
//--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ override public function cloneEvent():IRoyaleEvent
+ {
+ return new CollectionEvent(type, bubbles, cancelable, kind, location,
oldLocation, items);
+ }
+}
+
+}
diff --git
a/frameworks/projects/MXRoyale/src/main/royale/mx/events/CollectionEventKind.as
b/frameworks/projects/MXRoyale/src/main/royale/mx/events/CollectionEventKind.as
new file mode 100644
index 0000000..8cdcdb1
--- /dev/null
+++
b/frameworks/projects/MXRoyale/src/main/royale/mx/events/CollectionEventKind.as
@@ -0,0 +1,133 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.events
+{
+
+/**
+ * The CollectionEventKind class contains constants for the valid values
+ * of the mx.events.CollectionEvent class <code>kind</code> property.
+ * These constants indicate the kind of change that was made to the
collection.
+ *
+ * @see mx.events.CollectionEvent
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public final class CollectionEventKind
+{
+
//--------------------------------------------------------------------------
+ //
+ // Class constants
+ //
+
//--------------------------------------------------------------------------
+
+ /**
+ * Indicates that the collection added an item or items.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const ADD:String = "add";
+
+ /**
+ * Indicates that the item has moved from the position identified
+ * by the CollectionEvent <code>oldLocation</code> property to the
+ * position identified by the <code>location</code> property.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const MOVE:String = "move";
+
+ /**
+ * Indicates that the collection applied a sort, a filter, or both.
+ * This change can potentially be easier to handle than a RESET.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const REFRESH:String = "refresh";
+
+ /**
+ * Indicates that the collection removed an item or items.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const REMOVE:String = "remove";
+
+ /**
+ * Indicates that the item at the position identified by the
+ * CollectionEvent <code>location</code> property has been replaced.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const REPLACE:String = "replace";
+
+ /**
+ * Indicates that the collection has internally expanded.
+ * This event kind occurs when a branch opens in a
+ * hierarchical collection, for example when a Tree control branch
opens.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const EXPAND:String = "expand";
+
+ /**
+ * Indicates that the collection has changed so drastically that
+ * a reset is required.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const RESET:String = "reset";
+
+ /**
+ * Indicates that one or more items were updated within the collection.
+ * The affected item(s)
+ * are stored in the <code>items</code> property.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const UPDATE:String = "update";
+}
+
+}
diff --git
a/frameworks/projects/MXRoyale/src/main/royale/mx/events/PropertyChangeEvent.as
b/frameworks/projects/MXRoyale/src/main/royale/mx/events/PropertyChangeEvent.as
new file mode 100644
index 0000000..6735819
--- /dev/null
+++
b/frameworks/projects/MXRoyale/src/main/royale/mx/events/PropertyChangeEvent.as
@@ -0,0 +1,282 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.events
+{
+
+import mx.events.PropertyChangeEventKind;
+
+import org.apache.royale.events.Event;
+import org.apache.royale.events.IRoyaleEvent;
+
+/**
+ * The PropertyChangeEvent class represents the event object
+ * passed to the event listener when one of the properties of
+ * an object has changed, and provides information about the change.
+ * This event is used by collection classes, and is the only way for
+ * collections to know that the data they represent has changed.
+ * This event is also used by the Flex data binding mechanism.
+ *
+ * @see PropertyChangeEventKind
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public class PropertyChangeEvent extends Event
+{
+
//--------------------------------------------------------------------------
+ //
+ // Class constants
+ //
+
//--------------------------------------------------------------------------
+
+ // Note: If the value for CHANGE changes,
+ // update mx.utils.ObjectProxy's Bindable metadata.
+
+ /**
+ * The <code>PropertyChangeEvent.PROPERTY_CHANGE</code> constant defines
the value of the
+ * <code>type</code> property of the event object for a
<code>PropertyChange</code> event.
+ *
+ * <p>The properties of the event object have the following values:</p>
+ * <table class="innertable">
+ * <tr><th>Property</th><th>Value</th></tr>
+ * <tr><td><code>bubbles</code></td><td>Determined by the constructor;
defaults to false.</td></tr>
+ * <tr><td><code>cancelable</code></td><td>Determined by the
constructor; defaults to false.</td></tr>
+ * <tr><td><code>kind</code></td><td>The kind of change;
PropertyChangeEventKind.UPDATE
+ * or PropertyChangeEventKind.DELETE.</td></tr>
+ * <tr><td><code>oldValue</code></td><td>The original property
value.</td></tr>
+ * <tr><td><code>newValue</code></td><td>The new property value, if
any.</td></tr>
+ * <tr><td><code>property</code></td><td>The property that
changed.</td></tr>
+ * <tr><td><code>source</code></td><td>The object that contains the
property that changed.</td></tr>
+ * <tr><td><code>currentTarget</code></td><td>The Object that defines
the
+ * event listener that handles the event. For example, if you use
+ * <code>myButton.addEventListener()</code> to register an event
listener,
+ * myButton is the value of the <code>currentTarget</code>.
</td></tr>
+ * <tr><td><code>target</code></td><td>The Object that dispatched the
event;
+ * it is not always the Object listening for the event.
+ * Use the <code>currentTarget</code> property to always access the
+ * Object listening for the event.</td></tr>
+ * </table>
+ *
+ * @eventType propertyChange
+ *
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const PROPERTY_CHANGE:String = "propertyChange";
+
+
//--------------------------------------------------------------------------
+ //
+ // Class methods
+ //
+
//--------------------------------------------------------------------------
+
+ /**
+ * Returns a new PropertyChangeEvent of kind
+ * <code>PropertyChangeEventKind.UPDATE</code>
+ * with the specified properties.
+ * This is a convenience method.
+ *
+ * @param source The object where the change occured.
+ *
+ * @param property A String, QName, or int
+ * specifying the property that changed,
+ *
+ * @param oldValue The value of the property before the change.
+ *
+ * @param newValue The value of the property after the change.
+ *
+ * @return A newly constructed PropertyChangeEvent
+ * with the specified properties.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function createUpdateEvent(
+ source:Object,
+ property:Object,
+ oldValue:Object,
+ newValue:Object):PropertyChangeEvent
+ {
+ var event:PropertyChangeEvent =
+ new PropertyChangeEvent(PROPERTY_CHANGE);
+
+ event.kind = PropertyChangeEventKind.UPDATE;
+ event.oldValue = oldValue;
+ event.newValue = newValue;
+ event.source = source;
+ event.property = property;
+
+ return event;
+ }
+
+
//--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+
//--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * @param type The event type; indicates the action that triggered the
event.
+ *
+ * @param bubbles Specifies whether the event can bubble
+ * up the display list hierarchy.
+ *
+ * @param cancelable Specifies whether the behavior
+ * associated with the event can be prevented.
+ *
+ * @param kind Specifies the kind of change.
+ * The possible values are <code>PropertyChangeEventKind.UPDATE</code>,
+ * <code>PropertyChangeEventKind.DELETE</code>, and <code>null</code>.
+ *
+ * @param property A String, QName, or int
+ * specifying the property that changed.
+ *
+ * @param oldValue The value of the property before the change.
+ *
+ * @param newValue The value of the property after the change.
+ *
+ * @param source The object that the change occured on.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function PropertyChangeEvent(type:String, bubbles:Boolean = false,
+ cancelable:Boolean = false,
+ kind:String = null,
+ property:Object = null,
+ oldValue:Object = null,
+ newValue:Object = null,
+ source:Object = null)
+ {
+ super(type, bubbles, cancelable);
+
+ this.kind = kind;
+ this.property = property;
+ this.oldValue = oldValue;
+ this.newValue = newValue;
+ this.source = source;
+ }
+
+
//--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+
//--------------------------------------------------------------------------
+
+ //----------------------------------
+ // 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;
+
+
//--------------------------------------------------------------------------
+ //
+ // Class methods: Event
+ //
+
//--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ override public function cloneEvent():IRoyaleEvent
+ {
+ return new PropertyChangeEvent(type, bubbles, cancelable, kind,
+ property, oldValue, newValue, source);
+ }
+}
+
+}
diff --git
a/frameworks/projects/MXRoyale/src/main/royale/mx/events/PropertyChangeEventKind.as
b/frameworks/projects/MXRoyale/src/main/royale/mx/events/PropertyChangeEventKind.as
new file mode 100644
index 0000000..a2e82be
--- /dev/null
+++
b/frameworks/projects/MXRoyale/src/main/royale/mx/events/PropertyChangeEventKind.as
@@ -0,0 +1,63 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.events
+{
+
+/**
+ * The PropertyChangeEventKind class defines the constant values
+ * for the <code>kind</code> property of the PropertyChangeEvent class.
+ *
+ * @see mx.events.PropertyChangeEvent
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public final class PropertyChangeEventKind
+{
+
//--------------------------------------------------------------------------
+ //
+ // Class constants
+ //
+
//--------------------------------------------------------------------------
+
+ /**
+ * Indicates that the value of the property changed.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const UPDATE:String = "update";
+
+ /**
+ * Indicates that the property was deleted from the object.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const DELETE:String = "delete";
+}
+
+}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/utils/ArrayUtil.as
b/frameworks/projects/MXRoyale/src/main/royale/mx/utils/ArrayUtil.as
new file mode 100644
index 0000000..5c16cb7
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/utils/ArrayUtil.as
@@ -0,0 +1,215 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 mx.utils.ObjectUtil;
+
+/**
+ * The ArrayUtil utility class is an all-static class
+ * with methods for working with arrays within Flex.
+ * You do not create instances of ArrayUtil;
+ * instead you call static methods such as the
+ * <code>ArrayUtil.toArray()</code> method.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public class ArrayUtil
+{
+ import mx.collections.IList;
+
+
//--------------------------------------------------------------------------
+ //
+ // Class methods
+ //
+
//--------------------------------------------------------------------------
+
+ /**
+ * Ensures that an Object can be used as an Array.
+ *
+ * <p>If the Object is already an Array, it returns the object.
+ * If the object is not an Array, it returns an Array
+ * in which the only element is the Object.
+ * If the Object implements IList it returns the IList's array.
+ * As a special case, if the Object is null,
+ * it returns an empty Array.</p>
+ *
+ * @param obj Object that you want to ensure is an array.
+ *
+ * @return An Array. If the original Object is already an Array,
+ * the original Array is returned. If the original Object is an
+ * IList then it's array is returned. Otherwise, a new Array whose
+ * only element is the Object is returned or an empty Array if
+ * the Object was null.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function toArray(obj:Object):Array
+ {
+ if (obj == null)
+ return [];
+
+ else if (obj is Array)
+ return obj as Array;
+
+ else if (obj is IList)
+ return (obj as IList).toArray();
+
+ else
+ return [ obj ];
+ }
+
+ /**
+ * Returns the index of the item in the Array.
+ *
+ * @param item The item to find in the Array.
+ *
+ * @param source The Array to search for the item.
+ *
+ * @return The index of the item, and -1 if the item is not in the list.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function getItemIndex(item:Object, source:Array):int
+ {
+ var n:int = source.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ if (source[i] === item)
+ return i;
+ }
+
+ return -1;
+ }
+
+ /**
+ * Checks if the Array instances contain the same values
+ * against the same indexes, even if in different orders.
+ *
+ * @param a The first Array instance.
+ * @param b The second Array instance.
+ * @param strictEqualityCheck true if we should compare the
+ * values of the two Arrays using the strict equality
+ * operator (===) or not (==).
+ * @return true if the two Arrays contain the same values
+ * (determined using the strict equality operator) associated
+ * with the same indexes.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function arraysMatch(a:Array, b:Array,
strictEqualityCheck:Boolean = true):Boolean
+ {
+ if(!a || !b)
+ return false;
+
+ if(a.length != b.length)
+ return false;
+
+ var indexesA:Array = ObjectUtil.getEnumerableProperties(a);
+
+ for (var i:int = 0; i < indexesA.length; i++)
+ {
+ var index:String = indexesA[i];
+
+ if(!b.hasOwnProperty(index))
+ return false;
+
+ if(strictEqualityCheck && a[index] !== b[index])
+ return false;
+
+ if(!strictEqualityCheck && a[index] != b[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Checks if the Array instances contain the same values,
+ * even if in different orders.
+ *
+ * @param a The first Array instance.
+ * @param b The second Array instance.
+ * @param strictEqualityCheck true if we should compare the
+ * values of the two Arrays using the strict equality
+ * operator (===) or not (==).
+ * @return true if the two Arrays contain the same values.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function arrayValuesMatch(a:Array, b:Array,
strictEqualityCheck:Boolean = true):Boolean
+ {
+ if(!a || !b)
+ return false;
+
+ var valuesOfA:Array = getArrayValues(a);
+ valuesOfA.sort();
+
+ var valuesOfB:Array = getArrayValues(b);
+ valuesOfB.sort();
+
+ return arraysMatch(valuesOfA, valuesOfB, strictEqualityCheck);
+ }
+
+ /**
+ * Used to obtain the values in an Array, whether indexed
+ * or associative.
+ *
+ * @param value The Array instance.
+ * @return an indexed Array with the values found in <code>value</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function getArrayValues(value:Array):Array
+ {
+ var result:Array = [];
+
+ if(!value)
+ return result;
+
+ var indexes:Array = ObjectUtil.getEnumerableProperties(value);
+
+ for each(var index:String in indexes)
+ {
+ result.push(value[index]);
+ }
+
+ return result;
+ }
+}
+
+}
diff --git
a/frameworks/projects/MXRoyale/src/main/royale/mx/utils/ObjectProxy.as
b/frameworks/projects/MXRoyale/src/main/royale/mx/utils/ObjectProxy.as
new file mode 100644
index 0000000..117b350
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/utils/ObjectProxy.as
@@ -0,0 +1,831 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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
+{
+COMPILE::JS {
+ import goog.DEBUG;
+}
+/*
+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)
+ {
+ if (GOOG::DEBUG)
+ trace("ObjectProxy not implemented");
+// 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;
+// }
+// }
+}
+
+}
diff --git
a/frameworks/projects/MXRoyale/src/main/royale/mx/utils/ObjectUtil.as
b/frameworks/projects/MXRoyale/src/main/royale/mx/utils/ObjectUtil.as
new file mode 100644
index 0000000..c46249f
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/utils/ObjectUtil.as
@@ -0,0 +1,1130 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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
+{
+COMPILE::JS {
+ import goog.DEBUG;
+}
+/*
+import flash.utils.ByteArray;
+import flash.utils.Dictionary;
+import flash.utils.getQualifiedClassName;
+import flash.xml.XMLNode;
+*/
+import mx.collections.IList;
+
+/**
+ * The ObjectUtil class is an all-static class with methods for
+ * working with Objects within Flex.
+ * You do not create instances of ObjectUtil;
+ * instead you simply call static methods such as the
+ * <code>ObjectUtil.isSimple()</code> method.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public class ObjectUtil
+{
+ /**
+ * Array of properties to exclude from debugging output.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private static var defaultToStringExcludes:Array = ["password",
"credentials"];
+
+
//--------------------------------------------------------------------------
+ //
+ // Class methods
+ //
+
//--------------------------------------------------------------------------
+
+ /**
+ * Compares the Objects and returns an integer value
+ * indicating if the first item is less than, greater than, or equal to
+ * the second item.
+ * This method will recursively compare properties on nested objects and
+ * will return as soon as a non-zero result is found.
+ * By default this method will recurse to the deepest level of any
property.
+ * To change the depth for comparison specify a non-negative value for
+ * the <code>depth</code> parameter.
+ *
+ * @param a Object.
+ *
+ * @param b Object.
+ *
+ * @param depth Indicates how many levels should be
+ * recursed when performing the comparison.
+ * Set this value to 0 for a shallow comparison of only the primitive
+ * representation of each property.
+ * For example:<pre>
+ * var a:Object = {name:"Bob", info:[1,2,3]};
+ * var b:Object = {name:"Alice", info:[5,6,7]};
+ * var c:int = ObjectUtil.compare(a, b, 0);</pre>
+ *
+ * <p>In the above example the complex properties of <code>a</code> and
+ * <code>b</code> will be flattened by a call to <code>toString()</code>
+ * when doing the comparison.
+ * In this case the <code>info</code> property will be turned into a
string
+ * when performing the comparison.</p>
+ *
+ * @return Return 0 if a and b are equal, or both null or NaN.
+ * Return 1 if a is null or greater than b.
+ * Return -1 if b is null or greater than a.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function compare(a:Object, b:Object, depth:int = -1):int
+ {
+ if (GOOG::DEBUG)
+ trace("compare not implemented");
+ return 0;
+ //return internalCompare(a, b, 0, depth, new Dictionary(true));
+ }
+
+ /**
+ * Copies the specified Object and returns a reference to the copy.
+ * The copy is made using a native serialization technique.
+ * This means that custom serialization will be respected during the copy.
+ *
+ * <p>This method is designed for copying data objects,
+ * such as elements of a collection. It is not intended for copying
+ * a UIComponent object, such as a TextInput control. If you want to
create copies
+ * of specific UIComponent objects, you can create a subclass of the
component and implement
+ * a <code>clone()</code> method, or other method to perform the copy.</p>
+ *
+ * @param value Object that should be copied.
+ *
+ * @return Copy of the specified Object.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function copy(value:Object):Object
+ {
+ if (GOOG::DEBUG)
+ trace("copy not implemented");
+ return null;
+// var buffer:ByteArray = new ByteArray();
+// buffer.writeObject(value);
+// buffer.position = 0;
+// var result:Object = buffer.readObject();
+// return result;
+ }
+
+ /**
+ * Clones the specified Object and returns a reference to the clone.
+ * The clone is made using a native serialization technique.
+ * This means that custom serialization will be respected during the
+ * cloning. clone() differs from copy() in that the uid property of
+ * each object instance is retained.
+ *
+ * <p>This method is designed for cloning data objects,
+ * such as elements of a collection. It is not intended for cloning
+ * a UIComponent object, such as a TextInput control. If you want to clone
+ * specific UIComponent objects, you can create a subclass of the
component
+ * and implement a <code>clone()</code> method.</p>
+ *
+ * @param value Object that should be cloned.
+ *
+ * @return Clone of the specified Object.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 4
+ */
+ public static function clone(value:Object):Object
+ {
+ if (GOOG::DEBUG)
+ trace("clone not implemented");
+ return null;
+// var result:Object = copy(value);
+// cloneInternal(result, value);
+// return result;
+ }
+
+ /**
+ * Recursive helper used by the public clone method.
+ * @private
+ */
+ private static function cloneInternal(result:Object, value:Object):void
+ {
+ if (GOOG::DEBUG)
+ trace("cloneInternal not implemented");
+// if (value && value.hasOwnProperty("uid"))
+// result.uid = value.uid;
+//
+// var classInfo:Object = getClassInfo(value);
+// var v:Object;
+// for each (var p:* in classInfo.properties)
+// {
+// v = value[p];
+// if (v && v.hasOwnProperty("uid"))
+// cloneInternal(result[p], v);
+// }
+ }
+
+ /**
+ * Returns <code>true</code> if the object reference specified
+ * is a simple data type. The simple data types include the following:
+ * <ul>
+ * <li><code>String</code></li>
+ * <li><code>Number</code></li>
+ * <li><code>uint</code></li>
+ * <li><code>int</code></li>
+ * <li><code>Boolean</code></li>
+ * <li><code>Date</code></li>
+ * <li><code>Array</code></li>
+ * </ul>
+ *
+ * @param value Object inspected.
+ *
+ * @return <code>true</code> if the object specified
+ * is one of the types above; <code>false</code> otherwise.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function isSimple(value:Object):Boolean
+ {
+ var objectType:String = typeof(value);
+ switch (objectType)
+ {
+ case "number":
+ case "string":
+ case "boolean":
+ {
+ return true;
+ }
+
+ case "object":
+ {
+ return (value is Date) || (value is Array);
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Compares two numeric values.
+ *
+ * @param a First number.
+ *
+ * @param b Second number.
+ *
+ * @return 0 is both numbers are NaN.
+ * 1 if only <code>a</code> is a NaN.
+ * -1 if only <code>b</code> is a NaN.
+ * -1 if <code>a</code> is less than <code>b</code>.
+ * 1 if <code>a</code> is greater than <code>b</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function numericCompare(a:Number, b:Number):int
+ {
+ if (isNaN(a) && isNaN(b))
+ return 0;
+
+ if (isNaN(a))
+ return 1;
+
+ if (isNaN(b))
+ return -1;
+
+ if (a < b)
+ return -1;
+
+ if (a > b)
+ return 1;
+
+ return 0;
+ }
+
+ /**
+ * Compares two String values.
+ *
+ * @param a First String value.
+ *
+ * @param b Second String value.
+ *
+ * @param caseInsensitive Specifies to perform a case insensitive
compare,
+ * <code>true</code>, or not, <code>false</code>.
+ *
+ * @return 0 is both Strings are null.
+ * 1 if only <code>a</code> is null.
+ * -1 if only <code>b</code> is null.
+ * -1 if <code>a</code> precedes <code>b</code>.
+ * 1 if <code>b</code> precedes <code>a</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function stringCompare(a:String, b:String,
+ caseInsensitive:Boolean = false):int
+ {
+ if (a == null && b == null)
+ return 0;
+
+ if (a == null)
+ return 1;
+
+ if (b == null)
+ return -1;
+
+ // Convert to lowercase if we are case insensitive.
+ if (caseInsensitive)
+ {
+ a = a.toLocaleLowerCase();
+ b = b.toLocaleLowerCase();
+ }
+
+ var result:int = a.localeCompare(b);
+
+ if (result < -1)
+ result = -1;
+ else if (result > 1)
+ result = 1;
+
+ return result;
+ }
+
+ /**
+ * Compares the two Date objects and returns an integer value
+ * indicating if the first Date object is before, equal to,
+ * or after the second item.
+ *
+ * @param a Date object.
+ *
+ * @param b Date object.
+ *
+ * @return 0 if <code>a</code> and <code>b</code> are equal
+ * (or both are <code>null</code>);
+ * -1 if <code>a</code> is before <code>b</code>
+ * (or <code>b</code> is <code>null</code>);
+ * 1 if <code>a</code> is after <code>b</code>
+ * (or <code>a</code> is <code>null</code>);
+ * 0 is both dates getTime's are NaN;
+ * 1 if only <code>a</code> getTime is a NaN;
+ * -1 if only <code>b</code> getTime is a NaN.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function dateCompare(a:Date, b:Date):int
+ {
+ if (a == null && b == null)
+ return 0;
+
+ if (a == null)
+ return 1;
+
+ if (b == null)
+ return -1;
+
+ var na:Number = a.getTime();
+ var nb:Number = b.getTime();
+
+ if (na < nb)
+ return -1;
+
+ if (na > nb)
+ return 1;
+
+ if (isNaN(na) && isNaN(nb))
+ return 0;
+
+ if (isNaN(na))
+ return 1;
+
+ if (isNaN(nb))
+ return -1;
+
+ return 0;
+ }
+
+ /**
+ * Pretty-prints the specified Object into a String.
+ * All properties will be in alpha ordering.
+ * Each object will be assigned an id during printing;
+ * this value will be displayed next to the object type token
+ * preceded by a '#', for example:
+ *
+ * <pre>
+ * (mx.messaging.messages::AsyncMessage)#2.</pre>
+ *
+ * <p>This id is used to indicate when a circular reference occurs.
+ * Properties of an object that are of the <code>Class</code> type will
+ * appear only as the assigned type.
+ * For example a custom definition like the following:</p>
+ *
+ * <pre>
+ * public class MyCustomClass {
+ * public var clazz:Class;
+ * }</pre>
+ *
+ * <p>With the <code>clazz</code> property assigned to <code>Date</code>
+ * will display as shown below:</p>
+ *
+ * <pre>
+ * (somepackage::MyCustomClass)#0
+ * clazz = (Date)</pre>
+ *
+ * @param value Object to be pretty printed.
+ *
+ * @param namespaceURIs Array of namespace URIs for properties
+ * that should be included in the output.
+ * By default only properties in the public namespace will be included in
+ * the output.
+ * To get all properties regardless of namespace pass an array with a
+ * single element of "*".
+ *
+ * @param exclude Array of the property names that should be
+ * excluded from the output.
+ * Use this to remove data from the formatted string.
+ *
+ * @return String containing the formatted version
+ * of the specified object.
+ *
+ * @example
+ * <pre>
+ * // example 1
+ * var obj:AsyncMessage = new AsyncMessage();
+ * obj.body = [];
+ * obj.body.push(new AsyncMessage());
+ * obj.headers["1"] = { name: "myName", num: 15.3};
+ * obj.headers["2"] = { name: "myName", num: 15.3};
+ * obj.headers["10"] = { name: "myName", num: 15.3};
+ * obj.headers["11"] = { name: "myName", num: 15.3};
+ * trace(ObjectUtil.toString(obj));
+ *
+ * // will output to flashlog.txt
+ * (mx.messaging.messages::AsyncMessage)#0
+ * body = (Array)#1
+ * [0] (mx.messaging.messages::AsyncMessage)#2
+ * body = (Object)#3
+ * clientId = (Null)
+ * correlationId = ""
+ * destination = ""
+ * headers = (Object)#4
+ * messageId = "378CE96A-68DB-BC1B-BCF7FFFFFFFFB525"
+ * sequenceId = (Null)
+ * sequencePosition = 0
+ * sequenceSize = 0
+ * timeToLive = 0
+ * timestamp = 0
+ * clientId = (Null)
+ * correlationId = ""
+ * destination = ""
+ * headers = (Object)#5
+ * 1 = (Object)#6
+ * name = "myName"
+ * num = 15.3
+ * 10 = (Object)#7
+ * name = "myName"
+ * num = 15.3
+ * 11 = (Object)#8
+ * name = "myName"
+ * num = 15.3
+ * 2 = (Object)#9
+ * name = "myName"
+ * num = 15.3
+ * messageId = "1D3E6E96-AC2D-BD11-6A39FFFFFFFF517E"
+ * sequenceId = (Null)
+ * sequencePosition = 0
+ * sequenceSize = 0
+ * timeToLive = 0
+ * timestamp = 0
+ *
+ * // example 2 with circular references
+ * obj = {};
+ * obj.prop1 = new Date();
+ * obj.prop2 = [];
+ * obj.prop2.push(15.2);
+ * obj.prop2.push("testing");
+ * obj.prop2.push(true);
+ * obj.prop3 = {};
+ * obj.prop3.circular = obj;
+ * obj.prop3.deeper = new ErrorMessage();
+ * obj.prop3.deeper.rootCause = obj.prop3.deeper;
+ * obj.prop3.deeper2 = {};
+ * obj.prop3.deeper2.deeperStill = {};
+ * obj.prop3.deeper2.deeperStill.yetDeeper = obj;
+ * trace(ObjectUtil.toString(obj));
+ *
+ * // will output to flashlog.txt
+ * (Object)#0
+ * prop1 = Tue Apr 26 13:59:17 GMT-0700 2005
+ * prop2 = (Array)#1
+ * [0] 15.2
+ * [1] "testing"
+ * [2] true
+ * prop3 = (Object)#2
+ * circular = (Object)#0
+ * deeper = (mx.messaging.messages::ErrorMessage)#3
+ * body = (Object)#4
+ * clientId = (Null)
+ * code = (Null)
+ * correlationId = ""
+ * destination = ""
+ * details = (Null)
+ * headers = (Object)#5
+ * level = (Null)
+ * message = (Null)
+ * messageId = "14039376-2BBA-0D0E-22A3FFFFFFFF140A"
+ * rootCause = (mx.messaging.messages::ErrorMessage)#3
+ * sequenceId = (Null)
+ * sequencePosition = 0
+ * sequenceSize = 0
+ * timeToLive = 0
+ * timestamp = 0
+ * deeper2 = (Object)#6
+ * deeperStill = (Object)#7
+ * yetDeeper = (Object)#0
+ *
+ * // example 3 with Dictionary
+ * var point:Point = new Point(100, 100);
+ * var point2:Point = new Point(100, 100);
+ * var obj:Dictionary = new Dictionary();
+ * obj[point] = "point";
+ * obj[point2] = "point2";
+ * obj["1"] = { name: "one", num: 1};
+ * obj["two"] = { name: "2", num: 2};
+ * obj[3] = 3;
+ * trace(ObjectUtil.toString(obj));
+ *
+ * // will output to flashlog.txt
+ * (flash.utils::Dictionary)#0
+ * {(flash.geom::Point)#1
+ * length = 141.4213562373095
+ * x = 100
+ * y = 100} = "point2"
+ * {(flash.geom::Point)#2
+ * length = 141.4213562373095
+ * x = 100
+ * y = 100} = "point"
+ * {1} = (Object)#3
+ * name = "one"
+ * num = 1
+ * {3} = 3
+ * {"two"} = (Object)#4
+ * name = "2"
+ * num = 2
+ *
+ * </pre>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function toString(value:Object,
+ namespaceURIs:Array = null,
+ exclude:Array = null):String
+ {
+ if (exclude == null)
+ {
+ exclude = defaultToStringExcludes;
+ }
+
+ refCount = 0;
+ return internalToString(value, 0, null, namespaceURIs, exclude);
+ }
+
+ /**
+ * This method cleans up all of the additional parameters that show up in
AsDoc
+ * code hinting tools that developers shouldn't ever see.
+ * @private
+ */
+ private static function internalToString(value:Object,
+ indent:int = 0,
+
refs:Object = null,
+ namespaceURIs:Array = null,
+ exclude:Array = null):String
+ {
+ if (GOOG::DEBUG)
+ trace("internalToString not implemented");
+
+ return "(unknown)";
+ }
+
+ /**
+ * @private
+ * This method will append a newline and the specified number of spaces
+ * to the given string.
+ */
+ private static function newline(str:String, n:int = 0):String
+ {
+ var result:String = str;
+ result += "\n";
+
+ for (var i:int = 0; i < n; i++)
+ {
+ result += " ";
+ }
+ return result;
+ }
+
+ private static function internalCompare(a:Object, b:Object,
+ currentDepth:int, desiredDepth:int,
+ /*refs:Dictionary*/
refs:Object):int
+ {
+ if (a == null && b == null)
+ return 0;
+
+ if (a == null)
+ return 1;
+
+ if (b == null)
+ return -1;
+
+// if (a is ObjectProxy)
+// a = ObjectProxy(a).object_proxy::object;
+//
+// if (b is ObjectProxy)
+// b = ObjectProxy(b).object_proxy::object;
+
+ var typeOfA:String = typeof(a);
+ var typeOfB:String = typeof(b);
+
+ var result:int = 0;
+
+ if (typeOfA == typeOfB)
+ {
+ switch(typeOfA)
+ {
+ case "boolean":
+ result = numericCompare(Number(a), Number(b));
+ break;
+
+ case "number":
+ result = numericCompare(a as Number, b as Number);
+ break;
+
+ case "string":
+ result = stringCompare(a as String, b as String);
+ break;
+
+ case "object":
+ var newDepth:int = desiredDepth > 0 ? desiredDepth -1 :
desiredDepth;
+
+ // refs help us avoid circular reference infinite
recursion.
+ var aRef:Object = getRef(a,refs);
+ var bRef:Object = getRef(b,refs);
+
+ if (aRef == bRef)
+ return 0;
+ // the cool thing about our dictionary is that if
+ // we've seen objects and determined that they are
unequal, then
+ // we would've already exited out of this compare() call.
So the
+ // only info in the dictionary are sets of equal items
+
+ // let's first define them as equal
+ // this stops an "infinite loop" problem where A.i = B and
B.i = A
+ // if we later find that an object (one of the subobjects)
is in fact unequal,
+ // then we will return false and quit out of everything.
These refs are thrown away
+ // so it doesn't matter if it's correct.
+ refs[bRef] = aRef;
+
+ if (desiredDepth != -1 && (currentDepth > desiredDepth))
+ {
+ // once we try to go beyond the desired depth we
should
+ // toString() our way out
+ result = stringCompare(a.toString(), b.toString());
+ }
+ else if ((a is Array) && (b is Array))
+ {
+ result = arrayCompare(a as Array, b as Array,
currentDepth, desiredDepth, refs);
+ }
+ else if ((a is Date) && (b is Date))
+ {
+ result = dateCompare(a as Date, b as Date);
+ }
+ else if ((a is IList) && (b is IList))
+ {
+ result = listCompare(a as IList, b as IList,
currentDepth, desiredDepth, refs);
+ }
+ else
+ {
+ // We must be unequal, so return 1
+ return 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else // be consistent with the order we return here
+ {
+ return stringCompare(typeOfA, typeOfB);
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns information about the class, and properties of the class, for
+ * the specified Object.
+ *
+ * @param obj The Object to inspect.
+ *
+ * @param excludes Array of Strings specifying the property names that
should be
+ * excluded from the returned result. For example, you could specify
+ * <code>["currentTarget", "target"]</code> for an Event object since
these properties
+ * can cause the returned result to become large.
+ *
+ * @param options An Object containing one or more properties
+ * that control the information returned by this method.
+ * The properties include the following:
+ *
+ * <ul>
+ * <li><code>includeReadOnly</code>: If <code>false</code>,
+ * exclude Object properties that are read-only.
+ * The default value is <code>true</code>.</li>
+ * <li><code>includeTransient</code>: If <code>false</code>,
+ * exclude Object properties and variables that have
<code>[Transient]</code> metadata.
+ * The default value is <code>true</code>.</li>
+ * <li><code>uris</code>: Array of Strings of all namespaces that should
be included in the output.
+ * It does allow for a wildcard of "~~".
+ * By default, it is null, meaning no namespaces should be included.
+ * For example, you could specify <code>["mx_internal",
"mx_object"]</code>
+ * or <code>["~~"]</code>.</li>
+ * </ul>
+ *
+ * @return An Object containing the following properties:
+ * <ul>
+ * <li><code>name</code>: String containing the name of the class.</li>
+ * <li><code>properties</code>: Sorted list of the property names of
the specified object,
+ * or references to the original key if the specified object is a
Dictionary. The individual
+ * array elements are QName instances, which contain both the local
name of the property as well as the URI.</li>
+ * </ul>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function getClassInfo(obj:Object,
+ excludes:Array = null,
+ options:Object = null):Object
+ {
+ if (GOOG::DEBUG)
+ trace("getClassInfo not implemented");
+ return null;
+ }
+
+ /**
+ * Uses <code>getClassInfo</code> and examines the metadata information to
+ * determine whether a property on a given object has the specified
+ * metadata.
+ *
+ * @param obj The object holding the property.
+ * @param propName The property to check for metadata.
+ * @param metadataName The name of the metadata to check on the property.
+ * @param excludes If any properties need to be excluded when generating
class info. (Optional)
+ * @param options If any options flags need to changed when generating
class info. (Optional)
+ * @return true if the property has the specified metadata.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function hasMetadata(obj:Object,
+ propName:String,
+ metadataName:String,
+ excludes:Array = null,
+ options:Object = null):Boolean
+ {
+ if (GOOG::DEBUG)
+ trace("hasMetadata not implemented");
+ return false;
+// var classInfo:Object = getClassInfo(obj, excludes, options);
+// var metadataInfo:Object = classInfo["metadata"];
+// return internalHasMetadata(metadataInfo, propName, metadataName);
+ }
+
+ /**
+ * Returns <code>true</code> if the object is an instance of a dynamic
class.
+ *
+ * @param object The object.
+ *
+ * @return <code>true</code> if the object is an instance of a dynamic
class.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function isDynamicObject(object:Object):Boolean
+ {
+ try
+ {
+ // this test for checking whether an object is dynamic or not is
+ // pretty hacky, but it assumes that no-one actually has a
+ // property defined called "wootHackwoot"
+ object["wootHackwoot"];
+ }
+ catch (e:Error)
+ {
+ // our object isn't an instance of a dynamic class
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns all the properties defined dynamically on an object.
+ *
+ * @param object The object to inspect.
+ *
+ * @return an <code>Array</code> of the enumerable properties of the
object.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function getEnumerableProperties(object:Object):Array
+ {
+ var result:Array = [];
+
+ if(!isDynamicObject(object))
+ return result;
+
+ for (var property:Object in object)
+ result.push(property);
+
+ return result;
+ }
+
+
+ /**
+ * Verifies if the first object is dynamic and is a subset of the second
object.
+ *
+ * @param values The values which need to be shared by <code>object</code>
+ * @param object The object to verify against.
+ *
+ * @return true if and only if the objects are the same, or if
<code>values</code>
+ * is dynamic and <code>object</code> shares all its properties and
values.
+ * (Even if <code>object</code> contains other properties and values, we
still
+ * consider it a match).
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function valuesAreSubsetOfObject(values:Object,
object:Object):Boolean
+ {
+ if (GOOG::DEBUG)
+ trace("valuesAresubsetOfObject not implemented");
+ return false;
+// if(!object && !values)
+// return true;
+//
+// if(!object || !values)
+// return false;
+//
+// if(object === values)
+// return true;
+//
+// var enumerableProperties:Array =
ObjectUtil.getEnumerableProperties(values);
+// var matches:Boolean = enumerableProperties.length > 0 ||
ObjectUtil.isDynamicObject(values);
+//
+// for each(var property:String in enumerableProperties)
+// {
+// if (!object.hasOwnProperty(property) || object[property] !=
values[property])
+// {
+// matches = false;
+// break;
+// }
+// }
+//
+// return matches;
+ }
+
+ /**
+ * Returns the value at the end of the property chain <code>path</code>.
+ * If the value cannot be reached due to null links on the chain,
+ * <code>undefined</code> is returned.
+ *
+ * @param obj The object at the beginning of the property chain
+ * @param path The path to inspect (e.g. "address.street")
+ *
+ * @return the value at the end of the property chain,
<code>undefined</code>
+ * if it cannot be reached, or the object itself when <code>path</code>
is empty.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function getValue(obj:Object, path:Array):*
+ {
+ if(!obj)
+ return undefined;
+
+ if(!path || !path.length)
+ return obj;
+
+ var result:* = obj;
+ var i:int = -1;
+ while(++i < path.length && result)
+ result = result.hasOwnProperty(path[i]) ? result[path[i]] :
undefined;
+
+ return result;
+ }
+
+
+ /**
+ * Sets a new value at the end of the property chain <code>path</code>.
+ * If the value cannot be reached due to null links on the chain,
+ * <code>false</code> is returned.
+ *
+ * @param obj The object at the beginning of the property chain
+ * @param path The path to traverse (e.g. "address.street")
+ * @param newValue The value to set (e.g. "Fleet Street")
+ *
+ * @return <code>true</code> if the value is successfully set,
+ * <code>false</code> otherwise. Note that the function does not
+ * use a try/catch block. You can implement one in the calling
+ * function if there's a risk of type mismatch or other errors during
+ * the assignment.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function setValue(obj:Object, path:Array, newValue:*):Boolean
+ {
+ if(!obj || !path || !path.length)
+ return false;
+
+ var secondToLastLink:* = getValue(obj, path.slice(0, -1));
+ if(secondToLastLink &&
secondToLastLink.hasOwnProperty(path[path.length - 1]))
+ {
+ secondToLastLink[path[path.length - 1]] = newValue;
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @private
+ */
+ private static function internalHasMetadata(metadataInfo:Object,
propName:String, metadataName:String):Boolean
+ {
+ if (metadataInfo != null)
+ {
+ var metadata:Object = metadataInfo[propName];
+ if (metadata != null)
+ {
+ if (metadata[metadataName] != null)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @private
+ */
+// private static function recordMetadata(properties:XMLList):Object
+// {
+// if (GOOG::DEBUG)
+// trace("recordMetadata not implemented");
+// return null;
+// }
+
+
+ /**
+ * @private
+ */
+ private static function getCacheKey(o:Object, excludes:Array = null,
options:Object = null):String
+ {
+ if (GOOG::DEBUG)
+ trace("getCacheKey not implemented");
+ return null;
+ }
+
+ /**
+ * @private
+ */
+ private static function arrayCompare(a:Array, b:Array,
+ currentDepth:int, desiredDepth:int,
+ /*refs:Dictionary*/ refs:Object):int
+ {
+ var result:int = 0;
+
+ if (a.length != b.length)
+ {
+ if (a.length < b.length)
+ result = -1;
+ else
+ result = 1;
+ }
+ else
+ {
+ var key:Object;
+ for (key in a)
+ {
+ if (b.hasOwnProperty(key))
+ {
+ result = internalCompare(a[key], b[key], currentDepth,
+ desiredDepth, refs);
+
+ if (result != 0)
+ return result;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ for (key in b)
+ {
+ if (!a.hasOwnProperty(key))
+ {
+ return 1;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * @private
+ */
+// private static function byteArrayCompare(a:ByteArray, b:ByteArray):int
+// {
+// var result:int = 0;
+//
+// if (a == b)
+// return result;
+//
+// if (a.length != b.length)
+// {
+// if (a.length < b.length)
+// result = -1;
+// else
+// result = 1;
+// }
+// else
+// {
+// for (var i:int = 0; i < a.length; i++)
+// {
+// result = numericCompare(a[i], b[i]);
+// if (result != 0)
+// {
+// i = a.length;
+// }
+// }
+// }
+// return result;
+// }
+
+ /**
+ * @private
+ */
+ private static function listCompare(a:IList, b:IList, currentDepth:int,
+ desiredDepth:int, /*refs:Dictionary*/
refs:Object):int
+ {
+ var result:int = 0;
+
+ if (a.length != b.length)
+ {
+ if (a.length < b.length)
+ result = -1;
+ else
+ result = 1;
+ }
+ else
+ {
+ for (var i:int = 0; i < a.length; i++)
+ {
+ result = internalCompare(a.getItemAt(i), b.getItemAt(i),
+ currentDepth+1, desiredDepth, refs);
+ if (result != 0)
+ {
+ i = a.length;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * @private
+ * This is the "find" for our union-find algorithm when doing object
searches.
+ * The dictionary keeps track of sets of equal objects
+ */
+ private static function getRef(o:Object, /*refs:Dictionary*/
refs:Object):Object
+ {
+ var oRef:Object = refs[o];
+ while (oRef && oRef != refs[oRef])
+ {
+ oRef = refs[oRef];
+ }
+ if (!oRef)
+ oRef = o;
+ if (oRef != refs[o])
+ refs[o] = oRef;
+
+ return oRef;
+ }
+
+ /**
+ * @private
+ */
+ private static var refCount:int = 0;
+
+ /**
+ * @private
+ */
+ private static var CLASS_INFO_CACHE:Object = {};
+}
+
+}
--
To stop receiving notification emails like this one, please contact
[email protected].