You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ah...@apache.org on 2016/06/16 22:59:43 UTC

[26/50] [abbrv] git commit: [flex-asjs] [refs/heads/spark] - Merge branch 'develop' into spark

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/77148f4a/frameworks/projects/MX/src/main/flex/mx/utils/LoaderUtil.as
----------------------------------------------------------------------
diff --cc frameworks/projects/MX/src/main/flex/mx/utils/LoaderUtil.as
index 26f2e4e,0000000..94166ac
mode 100644,000000..100644
--- a/frameworks/projects/MX/src/main/flex/mx/utils/LoaderUtil.as
+++ b/frameworks/projects/MX/src/main/flex/mx/utils/LoaderUtil.as
@@@ -1,679 -1,0 +1,679 @@@
 +////////////////////////////////////////////////////////////////////////////////
 +//
 +//  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::AS3
++COMPILE::SWF
 +{
 +import flash.display.DisplayObject;
 +import flash.display.Loader;
 +import flash.display.LoaderInfo;
 +import flash.events.IEventDispatcher;
 +import flash.system.Capabilities;
 +import flash.utils.Dictionary;
 +}
 +COMPILE::JS
 +{
 +}
 +COMPILE::LATER
 +{
 +import mx.core.ApplicationDomainTarget;
 +import mx.core.RSLData;
 +}
 +import mx.core.IFlexModuleFactory;
 +import mx.core.mx_internal;
 +import mx.events.Request;
 +import mx.managers.SystemManagerGlobals;
 +import mx.utils.Platform;
 +
 +use namespace mx_internal;
 +
 +  /**
 +   *  The LoaderUtil class defines utility methods for use with Flex RSLs and
 +   *  generic Loader instances.
 +   *  
 +   *  @langversion 3.0
 +   *  @playerversion Flash 9
 +   *  @playerversion AIR 1.1
 +   *  @productversion Flex 3
 +   */
 +    public class LoaderUtil
 +    {
 +        
 +    include "../core/Version.as";
 +
 +    //--------------------------------------------------------------------------
 +    //
 +    //  Class variables
 +    //
 +    //--------------------------------------------------------------------------
 +
 +    /**
 +     *   @private
 +     * 
 +     *   An array of search strings and filters. These are used in the normalizeURL
 +     *   method. normalizeURL is used to remove special Flash Player markup from 
 +     *   urls, but the array could be appended to by the user to modify urls in other
 +     *   ways.
 +     *  
 +     *   Each object in the array has two fields:
 +     * 
 +     *   1. searchString - the string to search the url
 +     *   2. filterFunction - a function that accepts an url and an index to the first
 +     *   occurrence of the search string in the url. The function may modify the url
 +     *   and return a new url. A filterFunction is only called once, for the first
 +     *   occurrence of where the searchString was found. If there
 +     *   are multiple strings in the url that need to be processed the filterFunction
 +     *   should handle all of them on the call. A filter function should 
 +     *   be defined as follows:
 +     * 
 +     *   @param url the url to process.
 +     *   @param index the index of the first occurrence of the seachString in the url.
 +     *   @return the new url.
 +     * 
 +     *   function filterFunction(url:String, index:int):String
 +     * 
 +     */
 +    mx_internal static var urlFilters:Array = 
 +            [
 +                { searchString: "/[[DYNAMIC]]/", filterFunction: dynamicURLFilter}, 
 +                { searchString: "/[[IMPORT]]/",  filterFunction: importURLFilter}
 +            ];
 +    
 +    //--------------------------------------------------------------------------
 +    //
 +    //  Class methods
 +    //
 +    //--------------------------------------------------------------------------
 +        
 +    /**
 +     *  The root URL of a cross-domain RSL contains special text 
 +     *  appended to the end of the URL. 
 +     *  This method normalizes the URL specified in the specified LoaderInfo instance 
 +     *  to remove the appended text, if present. 
 +     *  Classes accessing <code>LoaderInfo.url</code> should call this method 
 +     *  to normalize the URL before using it.
 +     *  This method also encodes the url by calling the encodeURI() method
 +     *  on it. If you want the unencoded url, you must call unencodeURI() on
 +     *  the results.
 +     *
 +     *  @param loaderInfo A LoaderInfo instance or url string.
 +     *
 +     *  @return A normalized <code>LoaderInfo.url</code> property.
 +     *  
 +     *  @langversion 3.0
 +     *  @playerversion Flash 9
 +     *  @playerversion AIR 1.1
 +     *  @productversion Flex 3
 +     */
 +    public static function normalizeURL(loaderInfo:Object):String
 +    {
 +        var url:String;
- 		COMPILE::AS3
++		COMPILE::SWF
 +		{
 +			if (loaderInfo is LoaderInfo)
 +			  url = loaderInfo.url;
 +			else
 +			  url = loaderInfo.toString();
 +		}
 +		COMPILE::JS
 +		{
 +			url = loaderInfo.toString();
 +		}
 +        var index:int;
 +        var searchString:String;
 +        var urlFilter:Function;
 +        var n:uint = LoaderUtil.urlFilters.length;
 +        
 +        for (var i:uint = 0; i < n; i++)
 +        {
 +            searchString = LoaderUtil.urlFilters[i].searchString;
 +            if ((index = url.indexOf(searchString)) != -1)
 +            {
 +                urlFilter = LoaderUtil.urlFilters[i].filterFunction;
 +                url = urlFilter(url, index);
 +            }
 +        }
 +        
 +        // On the mac, the player doesn't like filenames with high-ascii
 +        // characters. Calling encodeURI fixes this problem. We restrict
 +        // this call to mac-only since it causes problems on Windows.
 +        if (Platform.isMac)
 +            return encodeURI(url);
 +        
 +        return url;
 +    }
 +
 +    /**
 +     *  @private 
 +     * 
 +     *  Use this method when you want to load resources with relative URLs.
 +     * 
 +     *  Combine a root url with a possibly relative url to get a absolute url.
 +     *  Use this method to convert a relative url to an absolute URL that is 
 +     *  relative to a root URL.
 +     * 
 +     *  @param rootURL An url that will form the root of the absolute url.
 +     *  If the <code>rootURL</code> does not specify a file name it must be 
 +     *  terminated with a slash. For example, "http://a.com" is incorrect, it
 +     *  should be terminated with a slash, "http://a.com/". If the rootURL is
 +     *  taken from loaderInfo, it must be passed thru <code>normalizeURL</code>
 +     *  before being passed to this function.
 +     * 
 +     *  When loading resources relative to an application, the rootURL is 
 +     *  typically the loaderInfo.url of the application.
 +     * 
 +     *  @param url The url of the resource to load (may be relative).
 +     * 
 +     *  @return If <code>url</code> is already an absolute URL, then it is 
 +     *  returned as is. If <code>url</code> is relative, then an absolute URL is
 +     *  returned where <code>url</code> is relative to <code>rootURL</code>. 
 +     */ 
 +    public static function createAbsoluteURL(rootURL:String, url:String):String
 +    {
 +        var absoluteURL:String = url;
 +
 +        // make relative paths relative to the SWF loading it, not the top-level SWF
 +        if (rootURL &&
 +            !(url.indexOf(":") > -1 || url.indexOf("/") == 0 || url.indexOf("\\") == 0))
 +        {
 +            // First strip off the search string and then any url fragments.
 +            var index:int;
 +            
 +            if ((index = rootURL.indexOf("?")) != -1 )
 +                rootURL = rootURL.substring(0, index);
 +
 +            if ((index = rootURL.indexOf("#")) != -1 )
 +                rootURL = rootURL.substring(0, index);
 +            
 +            // If the url starts from the current directory, then just skip
 +            // over the "./".
 +            // If the url start from the parent directory, the we need to
 +            // modify the rootURL.
 +            var lastIndex:int = Math.max(rootURL.lastIndexOf("\\"), rootURL.lastIndexOf("/"));
 +            if (url.indexOf("./") == 0)
 +            {
 +                url = url.substring(2);
 +            }
 +            else
 +            {
 +                while (url.indexOf("../") == 0)
 +                {
 +                    url = url.substring(3);
 +                    lastIndex = Math.max(rootURL.lastIndexOf("\\", lastIndex - 1), 
 +                                                   rootURL.lastIndexOf("/", lastIndex - 1));
 +                }
 +            }
 +                                        
 +            if (lastIndex != -1)
 +                absoluteURL = rootURL.substr(0, lastIndex + 1) + url;
 +        }
 +
 +        return absoluteURL;
 +    }
 +    
 +    /**
 +     *  @private
 +     * 
 +     *  Takes a list of required rsls and determines:
 +     *       - which RSLs have not been loaded
 +     *       - the application domain and IModuleFactory where the
 +     *         RSL should be loaded
 +     * 
 +     *  @param moduleFactory The module factory of the application or module 
 +     *  to get load information for. If the moduleFactory has not loaded the 
 +     *  module, then its parent is asked for load information. Each successive
 +     *  parent is asked until the load information is found or there are no
 +     *  more parents to ask. Only parents in parent ApplicationDomains are 
 +     *  searched. Applications in different security domains or sibling
 +     *  ApplicationDomains do not share RSLs.
 +     *  
 +     *  @param rsls An array of RSLs that are required for 
 +     *  <code>moduleFactory</code>. Each RSL is in an array of RSLData where
 +     *  the first element is the primary RSL and the remaining elements are 
 +     *  failover RSLs.
 +     *  @return Array of RSLData that represents the RSLs to load. RSLs that are
 +     *  already loaded are not in the listed. 
 +     */
 +	COMPILE::LATER
 +    mx_internal static function processRequiredRSLs(moduleFactory:IFlexModuleFactory, 
 +                                                    rsls:Array):Array
 +    {
 +        var rslsToLoad:Array = [];  // of Array, where each element is an array 
 +                                    // of RSLData (primary and failover), return value
 +        var topLevelModuleFactory:IFlexModuleFactory = SystemManagerGlobals.topLevelSystemManagers[0];
 +        var currentModuleFactory:IFlexModuleFactory = topLevelModuleFactory;
 +        var parentModuleFactory:IFlexModuleFactory = null;
 +        var loaded:Dictionary = new Dictionary();   // contains rsls that are loaded
 +        var loadedLength:int = 0;
 +        var resolved:Dictionary = new Dictionary(); // contains rsls that have the app domain resolved
 +        var resolvedLength:int = 0;
 +        var moduleFactories:Array = null;
 +        
 +        // Start at the top level module factory and work our way down the 
 +        // module factory chain checking if the any of the rsls are loaded 
 +        // and resolving application domain targets.
 +        // We start at the top level module factory because the default rsls
 +        // will all be loaded here and we won't often have to check other 
 +        // module factories.
 +        while (currentModuleFactory != moduleFactory)
 +        {
 +            // Need to loop over all the rsls, to see which one are loaded
 +            // and resolve application domains.
 +            var n:int = rsls.length;
 +            for (var i:int = 0; i < n; i++)
 +            {
 +                var rsl:Array = rsls[i];
 +
 +                // Check if the RSL has already been loaded.
 +                if (!loaded[rsl])
 +                {
 +                    if (isRSLLoaded(currentModuleFactory, rsl[0].digest))
 +                    {
 +                        loaded[rsl] = 1;
 +                        loadedLength++;
 +                        
 +                        // We may find an rsl loaded in a module factory as we work
 +                        // our way down the module factory list. If we find one then 
 +                        // remove it.
 +                        if (currentModuleFactory != topLevelModuleFactory)
 +                        {
 +                            var index:int = rslsToLoad.indexOf(rsl); 
 +                            if (index != -1)
 +                                rslsToLoad.splice(index, 1);                        
 +                        }
 +                    }
 +                    else if (rslsToLoad.indexOf(rsl) == -1)
 +                    {
 +                        rslsToLoad.push(rsl);   // assume we have to load it
 +                    }
 +                } 
 +
 +                // If the rsl is already loaded or already resolved then
 +                // skip resolving it.
 +                if (!loaded[rsl] && resolved[rsl] == null)
 +                {
 +                    // Get the parent module factory if we are going to need to 
 +                    // resolve the application domain target.
 +                    if (!parentModuleFactory && 
 +                        RSLData(rsl[0]).applicationDomainTarget == ApplicationDomainTarget.PARENT)
 +                    {
 +                        parentModuleFactory = getParentModuleFactory(moduleFactory);           
 +                    }
 +                    
 +                    // Resolve the application domain target.
 +                    if (resolveApplicationDomainTarget(rsl,
 +                            moduleFactory,
 +                            currentModuleFactory,
 +                            parentModuleFactory,
 +                            topLevelModuleFactory))
 +                    {
 +                        resolved[rsl] = 1;
 +                        resolvedLength++;                        
 +                    }
 +                }
 +            }
 +            
 +            // If process all rsls then get out.
 +            if (loadedLength + resolvedLength >= rsls.length)
 +                break;
 +                
 +             // If we didn't find everything in the top level module factory then work
 +            // down towards the rsl's owning module factory. 
 +            // Build up the module factory parent chain so we can traverse it.
 +            if (!moduleFactories)
 +            {
 +                moduleFactories = [moduleFactory];
 +                currentModuleFactory = moduleFactory;
 +                while (currentModuleFactory != topLevelModuleFactory)
 +                {
 +
 +                    currentModuleFactory = getParentModuleFactory(currentModuleFactory);
 +                    
 +                    // If we couldn't get the parent module factory, then we 
 +                    // will have to load into the highest application domain
 +                    // that is available. We won't be able to get a parent 
 +                    // if a module was loaded without specifying a parent 
 +                    // module factory.
 +                    if (!currentModuleFactory)
 +                        break;
 +                    
 +                    if (currentModuleFactory != topLevelModuleFactory)
 +                        moduleFactories.push(currentModuleFactory);
 +                    
 +                    if (!parentModuleFactory)
 +                        parentModuleFactory = currentModuleFactory;
 +                }
 +            }
 +
 +            currentModuleFactory = moduleFactories.pop();
 +        }
 +        
 +        return rslsToLoad;
 +    }
 +    
 +    /**
 +     * @private
 +     * Test whether a url is on the local filesystem. We can only
 +     * really tell this with URLs that begin with "file:" or a
 +     * Windows-style drive notation such as "C:". This fails some
 +     * cases like the "/" notation on Mac/Unix.
 +     * 
 +     * @param url
 +     * the url to check against
 +     * 
 +     * @return
 +     * true if url is local, false if not or unable to determine
 +     **/
 +    mx_internal static function isLocal(url:String):Boolean 
 +    {
 +        return (url.indexOf("file:") == 0 || url.indexOf(":") == 1);
 +    }
 +    
 +    /**
 +     * @private
 +     * Currently (FP 10.x) the ActiveX player (Explorer on Windows) does not
 +     * handle encoded URIs containing UTF-8 on the local filesystem, but
 +     * it does handle those same URIs unencoded. The plug-in requires
 +     * encoded URIs.
 +     * 
 +     * @param url
 +     * url to properly encode, may be fully or partially encoded with encodeURI
 +     * 
 +     * @param local
 +     * true indicates the url is on the local filesystem
 +     * 
 +     * @return
 +     * encoded url that may be loaded with a URLRequest
 +     **/
- 	COMPILE::AS3
++	COMPILE::SWF
 +    mx_internal static function OSToPlayerURI(url:String, local:Boolean):String 
 +    {
 +        
 +        // First strip off the search string and any url fragments so
 +        // they will not be decoded/encoded.
 +        // Next decode the url.
 +        // Before returning the decoded or encoded string add the search
 +        // string and url fragment back.
 +        var searchStringIndex:int;
 +        var fragmentUrlIndex:int;
 +        var decoded:String = url;
 +        
 +        if ((searchStringIndex = decoded.indexOf("?")) != -1 )
 +        {
 +            decoded = decoded.substring(0, searchStringIndex);
 +        }
 +        
 +        if ((fragmentUrlIndex = decoded.indexOf("#")) != -1 )
 +            decoded = decoded.substring(0, fragmentUrlIndex);
 +        
 +        try
 +        {
 +            // decode the url
 +            decoded = decodeURI(decoded);
 +        }
 +        catch (e:Error)
 +        {
 +            // malformed url, but some are legal on the file system
 +        }
 +        
 +        // create the string to hold the the search string url fragments.
 +        var extraString:String = null;
 +        if (searchStringIndex != -1 || fragmentUrlIndex != -1)
 +        {
 +            var index:int = searchStringIndex;
 +            
 +            if (searchStringIndex == -1 || 
 +                (fragmentUrlIndex != -1 && fragmentUrlIndex < searchStringIndex))
 +            {
 +                index = fragmentUrlIndex;
 +            }
 +            
 +            extraString = url.substr(index);
 +        }
 +        
 +        if (local && flash.system.Capabilities.playerType == "ActiveX")
 +        {
 +            if (extraString)
 +                return decoded + extraString;
 +            else 
 +                return decoded;
 +        }
 +        
 +        if (extraString)
 +            return encodeURI(decoded) + extraString;
 +        else
 +            return encodeURI(decoded);            
 +    }
 +
 +    /**
 +     *  @private
 +     *  Get the parent module factory. 
 +     * 
 +     *  @param moduleFactory The module factory to get the parent of.
 +     * 
 +     *  @return the parent module factory if available, null otherwise. 
 +     */
- 	COMPILE::AS3
++	COMPILE::SWF
 +    private static function getParentModuleFactory(moduleFactory:IFlexModuleFactory):IFlexModuleFactory    
 +    {
 +        var request:Request = new Request(Request.GET_PARENT_FLEX_MODULE_FACTORY_REQUEST);
 +        DisplayObject(moduleFactory).dispatchEvent(request); 
 +        return request.value as IFlexModuleFactory;
 +    }
 +    
 +    /**
 +     *  @private
 +     *  Resolve the application domain target. 
 +     * 
 +     *  @param rsl to resolve.
 +     *  @param moduleFactory The module factory loading the RSLs.
 +     *  @param currentModuleFactory The module factory to search for placeholders.
 +     *  @param parentModuleFactory The rsl's parent module factory.
 +     *  @param topLevelModuleFactory The top-level module factory.
 +     * 
 +     *  @return true if the application domain target was resolved, 
 +     *  false otherwise.
 +     */
 +	COMPILE::LATER
 +    private static function resolveApplicationDomainTarget(rsl:Array, 
 +                                    moduleFactory:IFlexModuleFactory, 
 +                                    currentModuleFactory:IFlexModuleFactory, 
 +                                    parentModuleFactory:IFlexModuleFactory, 
 +                                    topLevelModuleFactory:IFlexModuleFactory):Boolean 
 +    {
 +        var resolvedRSL:Boolean = false;
 +        var targetModuleFactory:IFlexModuleFactory = null;
 +        
 +        var applicationDomainTarget:String = rsl[0].applicationDomainTarget;
 +        if (isLoadedIntoTopLevelApplicationDomain(moduleFactory))
 +        {
 +            targetModuleFactory = topLevelModuleFactory;
 +        }
 +        else if (applicationDomainTarget == ApplicationDomainTarget.DEFAULT)
 +        {
 +            if (hasPlaceholderRSL(currentModuleFactory, rsl[0].digest))
 +            {
 +                targetModuleFactory = currentModuleFactory;
 +            }
 +        }
 +        else if (applicationDomainTarget == ApplicationDomainTarget.TOP_LEVEL)
 +        {
 +            targetModuleFactory = topLevelModuleFactory;
 +        }
 +        else if (applicationDomainTarget == ApplicationDomainTarget.CURRENT)
 +        {
 +            resolvedRSL = true;
 +        }
 +        else if (applicationDomainTarget == ApplicationDomainTarget.PARENT)
 +        {
 +            // If there is no parent, ignore the target and load into the current
 +            // app domain. 
 +            targetModuleFactory = parentModuleFactory;
 +        }
 +        else
 +        {
 +            resolvedRSL = true; // bogus target, load into current application domain
 +        }
 +        
 +        if (resolvedRSL || targetModuleFactory)
 +        {
 +            if (targetModuleFactory)
 +                updateRSLModuleFactory(rsl, targetModuleFactory);
 +            return true;
 +        }
 +        
 +        return false;
 +    }
 +    
 +    /**
 +     *  @private
 +     *  Determine if the moduleFactory has loaded an rsl that matches the 
 +     *  specified digest.
 +     * 
 +     *  @param moduleFactory The module factory to search.
 +     *  @param digest The digest to search for.
 +     *  @return true if a loaded rsl matching the digest was found.
 +     */
 +	COMPILE::LATER
 +    private static function isRSLLoaded(moduleFactory:IFlexModuleFactory, digest:String):Boolean
 +    {
 +        var preloadedRSLs:Dictionary = moduleFactory.preloadedRSLs;
 +        
 +        if (preloadedRSLs)
 +        {
 +            // loop over the rsls to find a matching digest
 +            for each (var rsl:Vector.<RSLData> in preloadedRSLs)
 +            {
 +                var n:int = rsl.length;
 +                for (var i:int = 0; i < n; i++)
 +                {
 +                    if (rsl[i].digest == digest)
 +                    {
 +                        return true;
 +                    }
 +                }
 +            }
 +        }
 +        
 +        return false;
 +    }
 +    
 +    /**
 +     *  @private
 +     * 
 +     *  Determine if the moduleFactory has a placeholder rsl that matches the 
 +     *  specified digest.
 +     * 
 +     *  @param moduleFactory The module factory to search.
 +     *  @param digest The digest to search for.
 +     *  @return true if a placeholder rsl matching the digest was found.
 +     */
 +    private static function hasPlaceholderRSL(moduleFactory:IFlexModuleFactory, digest:String):Boolean
 +    {
 +        var phRSLs:Array = moduleFactory.info()["placeholderRsls"];
 +        
 +        if (phRSLs)
 +        {
 +            // loop over the rsls to find a matching digest
 +            var n:int = phRSLs.length;
 +            for (var i:int = 0; i < n; i++)
 +            {
 +                var rsl:Object = phRSLs[i];
 +                var m:int = rsl.length;
 +                for (var j:int = 0; j < m; j++)
 +                {
 +                    if (rsl[j].digest == digest)
 +                    {
 +                        return true;
 +                    }
 +                }
 +            }
 +        }
 +        
 +        return false;
 +    }
 + 
 +    /**
 +     *  @private
 +     *  Test if a module factory has been loaded into the top-level application domain.
 +     * 
 +     *  @return true if loaded into the top-level application domain, false otherwise.
 +     */ 
 +	COMPILE::LATER
 +    private static function isLoadedIntoTopLevelApplicationDomain(moduleFactory:IFlexModuleFactory):Boolean
 +    {
 +        if (moduleFactory is DisplayObject)
 +        {
 +            var displayObject:DisplayObject = DisplayObject(moduleFactory);
 +            var loaderInfo:LoaderInfo = displayObject.loaderInfo;
 +            if (loaderInfo && loaderInfo.applicationDomain &&
 +                loaderInfo.applicationDomain.parentDomain == null)
 +            {
 +                return true;
 +            }
 +        }
 +        
 +        return false;        
 +    }
 +    
 +    /**
 +     *  @private
 +     * 
 +     *  Update the module factory of an rsl, both the primary rsl and all 
 +     *  failover rsls.
 +     * 
 +     *  @param rsl One RSL represented by an array of RSLData. The 
 +     *  first element in the array is the primary rsl, the others are failovers.
 +     *  @param moduleFactory  The moduleFactory to set in the primary and 
 +     *  failover rsls.
 +     */
 +	COMPILE::LATER
 +    private static function updateRSLModuleFactory(rsl:Array, moduleFactory:IFlexModuleFactory):void
 +    {
 +        var n:int = rsl.length;
 +        for (var i:int = 0; i < n; i++)
 +        {
 +            rsl[i].moduleFactory = moduleFactory;
 +        }
 +    }
 +    
 +    /**
 +     *  @private
 +     * 
 +     *  Strip off the DYNAMIC string(s) appended to the url.
 +     */
 +    private static function dynamicURLFilter(url:String, index:int):String
 +    {
 +        return url.substring(0, index);
 +    }
 +
 +    /**
 +     *  @private
 +     * 
 +     *  Add together the protocol plus everything after "/[[IMPORT]]/".
 +     */
 +    private static function importURLFilter(url:String, index:int):String
 +    {
 +        var protocolIndex:int = url.indexOf("://");
 +        return url.substring(0,protocolIndex + 3) + url.substring(index + 12);
 +    }
 +    
 +    }
- }
++}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/77148f4a/frameworks/projects/MX/src/main/flex/mx/utils/NameUtil.as
----------------------------------------------------------------------
diff --cc frameworks/projects/MX/src/main/flex/mx/utils/NameUtil.as
index 4f8f53d,0000000..7782458
mode 100644,000000..100644
--- a/frameworks/projects/MX/src/main/flex/mx/utils/NameUtil.as
+++ b/frameworks/projects/MX/src/main/flex/mx/utils/NameUtil.as
@@@ -1,195 -1,0 +1,195 @@@
 +////////////////////////////////////////////////////////////////////////////////
 +//
 +//  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 org.apache.flex.reflection.getQualifiedClassName;
 +
 +import mx.core.IRepeaterClient;
 +import mx.core.IUIComponent;
 +
 +/**
 + *  The NameUtil utility class defines static methods for
 + *  creating names for Flex objects.
 + *  You do not create instances of NameUtil;
 + *  instead you call static methods of the class, such as 
 + *  the <code>NameUtil.createName()</code> method.
 + *  
 + *  @langversion 3.0
 + *  @playerversion Flash 9
 + *  @playerversion AIR 1.1
 + *  @productversion Flex 3
 + */
 +public class NameUtil
 +{
 +    include "../core/Version.as";
 +
 +    //--------------------------------------------------------------------------
 +    //
 +    //  Class variables
 +    //
 +    //--------------------------------------------------------------------------
 +
 +    /**
 +     *  @private
 +     */
 +    private static var counter:int = 0;
 +
 +    //--------------------------------------------------------------------------
 +    //
 +    //  Class methods
 +    //
 +    //--------------------------------------------------------------------------
 +
 +    /**
 +     *  Creates a unique name for any Object instance, such as "Button12", by
 +     *  combining the unqualified class name with an incrementing counter.
 +     *
 +     *  @param object Object requiring a name.
 +     *
 +     *  @return String containing the unique name.
 +     *  
 +     *  @langversion 3.0
 +     *  @playerversion Flash 9
 +     *  @playerversion AIR 1.1
 +     *  @productversion Flex 3
 +     */
 +    public static function createUniqueName(object:Object):String
 +    {
 +        if (!object)
 +            return null;
 +
 +        var name:String = getQualifiedClassName(object);
 +        
 +        // If there is a package name, strip it off.
 +        var index:int = name.indexOf("::");
 +        if (index != -1)
 +            name = name.substr(index + 2);
 +                        
 +        // If the class name ends with a digit (which some autogenerated
 +        // classes do), then append an underscore before appending
 +        // the counter.
 +        var charCode:int = name.charCodeAt(name.length - 1);
 +        if (charCode >= 48 && charCode <= 57)
 +            name += "_";
 +        
 +        return name + counter++;
 +    }
 +
 +    /**
 +     *  Returns a string, such as
 +     *  "MyApplication0.addressForm.lastName.TextField17",
 +     *  for a DisplayObject object that indicates its position in the
 +     *  hierarchy of DisplayObject objects in an application.
 +     *
 +     *  @param displayObject A DisplayObject object whose hierarchy in the application
 +     *  is desired. 
 +     *
 +     *  @return String containing the position of <code>displayObject</code> 
 +     *  in the hierarchy of DisplayObject objects in an application.
 +     *  
 +     *  @langversion 3.0
 +     *  @playerversion Flash 9
 +     *  @playerversion AIR 1.1
 +     *  @productversion Flex 3
 +	 * 
 +	 *  @flexjsignorecoercion mx.core.IUIComponent
 +     */
 +    public static function displayObjectToString(
 +                                displayObject:IUIComponent):String
 +    {
 +        var result:String;
 +
 +        // Start at the specified object and walk up the parent chain
 +        // to build up the string to return.
 +        try
 +        {
 +            for (var o:IUIComponent = displayObject;
 +                 o != null;
 +                 o = o.parent as IUIComponent)
 +            {
 +                // If this object is in the display tree,
 +                // stop after we've prepended the topmost Application instance.
 +                if (o.parent && o.topOfDisplayList && o.parent == o.topOfDisplayList)
 +                    break;
 +    
 +                // Prefer id over name if specified.
 +                var s:String = "id" in o && o["id"] ? o["id"] : o.name;
 +                
 +                if (o is IRepeaterClient)
 +                {
 +                    var indices:Array = IRepeaterClient(o).instanceIndices;
 +                    if (indices)
 +                        s += "[" + indices.join("][") + "]";
 +                }
 +    
 +                result = result == null ? s : s + "." + result;
 +            }
 +        }
 +        catch (e:Error)
 +        {
- 			COMPILE::AS3
++			COMPILE::SWF
 +			{
 +				if (!(e is SecurityError))
 +					throw e;
 +			}
 +            // Ignore error and continue with what we have. 
 +            // We may not have access to our parent if we are loaded into a sandbox.
 +        }
 +        
 +        return result;
 +    }
 +
 +    /**
 +     *  Returns the name of the specified object's class,
 +     *  such as <code>"Button"</code>
 +     *
 +     *  <p>This string does not include the package name.
 +     *  If you need the package name as well, call the
 +     *  <code>getQualifiedClassName()</code> method in the flash.utils package.
 +     *  It will return a string such as <code>"mx.controls::Button"</code>.</p>
 +     *
 +     *  @param object The object.
 +     *
 +     *  @return The name of the specified object's class.
 +     *  
 +     *  @langversion 3.0
 +     *  @playerversion Flash 9
 +     *  @playerversion AIR 1.1
 +     *  @productversion Flex 3
 +     */
 +    public static function getUnqualifiedClassName(object:Object):String
 +    {
 +        var name:String;
 +        if (object is String)
 +            name = object as String;
 +        else
 +            name = getQualifiedClassName(object);
 +
 +        // If there is a package name, strip it off.
 +        var index:int = name.indexOf("::");
 +        if (index != -1)
 +            name = name.substr(index + 2);
 +
 +        return name;
 +    }
 +}
 +
 +}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/77148f4a/frameworks/projects/MX/src/main/flex/mx/utils/ObjectProxy.as
----------------------------------------------------------------------
diff --cc frameworks/projects/MX/src/main/flex/mx/utils/ObjectProxy.as
index a6f1591,0000000..2d0e0ee
mode 100644,000000..100644
--- a/frameworks/projects/MX/src/main/flex/mx/utils/ObjectProxy.as
+++ b/frameworks/projects/MX/src/main/flex/mx/utils/ObjectProxy.as
@@@ -1,946 -1,0 +1,946 @@@
 +////////////////////////////////////////////////////////////////////////////////
 +//
 +//  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 org.apache.flex.events.EventDispatcher;
 +import org.apache.flex.reflection.getQualifiedClassName;
- COMPILE::AS3
++COMPILE::SWF
 +{
 +import flash.events.Event;
 +import flash.utils.IDataInput;
 +import flash.utils.IDataOutput;
 +import flash.utils.IExternalizable;
 +import flash.utils.flash_proxy;
 +}
 +COMPILE::JS
 +{
 +	import org.apache.flex.events.Event;	
 +	import flex.utils.IExternalizable;
 +}
 +import org.apache.flex.utils.Proxy;
 +import mx.core.IPropertyChangeNotifier;
 +import mx.events.PropertyChangeEvent;
 +import mx.events.PropertyChangeEventKind;
 +
- COMPILE::AS3
++COMPILE::SWF
 +{
 +use namespace flash_proxy;
 +use namespace object_proxy;
 +}
 +
 +[Bindable("propertyChange")]
 +[RemoteClass(alias="flex.messaging.io.ObjectProxy")]
 +
 +/**
 + *  This class provides the ability to track changes to an item
 + *  managed by this proxy.
 + *  Any number of objects can "listen" for changes on this
 + *  object, by using the <code>addEventListener()</code> method.
 + *
 + *  @example
 + *  <pre>
 + *  import mx.events.PropertyChangeEvent;
 + *  import mx.utils.ObjectUtil;
 + *  import mx.utils.ObjectProxy;
 + *  import mx.utils.StringUtil;
 + *
 + *  var a:Object = { name: "Tyler", age: 5, ssnum: "555-55-5555" };
 + *  var p:ObjectProxy = new ObjectProxy(a);
 + *  p.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, updateHandler);
 + *  p.name = "Jacey";
 + *  p.age = 2;
 + *  delete p.ssnum;
 + *
 + *  // handler function
 + *  function updateHandler(event:ChangeEvent):void
 + *  {
 + *      trace(StringUtil.substitute("updateHandler('{0}', {1}, {2}, {3}, '{4}')",
 + *                                     event.kind,
 + *                                     event.property,
 + *                                     event.oldValue,
 + *                                     event.newValue,
 + *                                     event.target.object_proxy::UUID));
 + *  }
 + * 
 + *  // The trace output appears as:
 + *  // updateHandler('opUpdate', name, Tyler, Jacey, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
 + *  // updateHandler('opUpdate', age, 5, 2, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
 + *  // updateHandler('opDelete', ssnum, 555-55-5555, null, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
 + *  </pre>
 + *  
 + *  @langversion 3.0
 + *  @playerversion Flash 9
 + *  @playerversion AIR 1.1
 + *  @productversion Flex 3
 + */
 +public dynamic class ObjectProxy extends Proxy
 +                                 implements IExternalizable,
 +                                 IPropertyChangeNotifier
 +{
 +    //--------------------------------------------------------------------------
 +    //
 +    //  Constructor
 +    //
 +    //--------------------------------------------------------------------------
 +
 +    /**
 +     *  Initializes this proxy with the specified object, id and proxy depth.
 +     * 
 +     *  @param item Object to proxy.
 +     *  If no item is specified, an anonymous object will be constructed
 +     *  and assigned.
 +     *
 +     *  @param uid String containing the unique id
 +     *  for this object instance.
 +     *  Required for IPropertyChangeNotifier compliance as every object must 
 +     *  provide a unique way of identifying it.
 +     *  If no value is specified, a random id will be assigned.
 +     *
 +     *  @param proxyDepth An integer indicating how many levels in a complex
 +     *  object graph should have a proxy created during property access.
 +     *  The default is -1, meaning "proxy to infinite depth".
 +     *  
 +     *  @example
 +     *
 +     *  <pre>
 +     *  import mx.events.PropertyChangeEvent;
 +     *  import mx.utils.ObjectUtil;
 +     *  import mx.utils.ObjectProxy;
 +     *  import mx.utils.StringUtil;
 +     *
 +     *  var a:Object = { name: "Tyler", age: 5, ssnum: "555-55-5555" };
 +     *  var p:ObjectProxy = new ObjectProxy(a);
 +     *  p.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, updateHandler);
 +     *  p.name = "Jacey";
 +     *  p.age = 2;
 +     *  delete p.ssnum;
 +     *
 +     *  // handler function
 +     *  function updateHandler(event:PropertyChangeEvent):void
 +     *  {
 +     *      trace(StringUtil.substitute("updateHandler('{0}', {1}, {2}, {3}, '{4}')",
 +     *                                     event.kind,
 +     *                                     event.property,
 +     *                                     event.oldValue,
 +     *                                     event.newValue,
 +     *                                     event.target.uid));
 +     *  }
 +     *
 +     *  // trace output
 +     *  updateHandler('opUpdate', name, Jacey, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
 +     *  updateHandler('opUpdate', age, 2, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
 +     *  updateHandler('opDelete', ssnum, null, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
 +     *  </pre>
 +     *  
 +     *  @langversion 3.0
 +     *  @playerversion Flash 9
 +     *  @playerversion AIR 1.1
 +     *  @productversion Flex 3
 +     */
 +    public function ObjectProxy(item:Object = null, uid:String = null,
 +                                proxyDepth:int = -1)
 +    {
 +        super();
 +
 +        if (!item)
 +            item = {};
 +        _item = item;
 +
 +        _proxyLevel = proxyDepth;
 +       
 +        notifiers = {};
 +
 +        dispatcher = new EventDispatcher(this);
 +
 +        // If we got an id, use it.  Otherwise the UID is lazily
 +        // created in the getter for UID.
 +        if (uid)
 +            _id = uid;
 +    }
 +
 +    //--------------------------------------------------------------------------
 +    //
 +    //  Variables
 +    //
 +    //--------------------------------------------------------------------------
 +
 +    /**
 +     *  A reference to the EventDispatcher for this proxy.
 +     *  
 +     *  @langversion 3.0
 +     *  @playerversion Flash 9
 +     *  @playerversion AIR 1.1
 +     *  @productversion Flex 3
 +     */
 +    protected var dispatcher:EventDispatcher;
 +
 +    /**
 +     *  A hashmap of property change notifiers that this proxy is 
 +     *  listening for changes from; the key of the map is the property name.
 +     *  
 +     *  @langversion 3.0
 +     *  @playerversion Flash 9
 +     *  @playerversion AIR 1.1
 +     *  @productversion Flex 3
 +     */
 +    protected var notifiers:Object;
 +    
 +    /**
 +     *  Indicates what kind of proxy to create
 +     *  when proxying complex properties.
 +     *  Subclasses should assign this value appropriately.
 +     *  
 +     *  @langversion 3.0
 +     *  @playerversion Flash 9
 +     *  @playerversion AIR 1.1
 +     *  @productversion Flex 3
 +     */
 +    protected var proxyClass:Class = ObjectProxy;
 +    
 +    /**
 +     *  Contains a list of all of the property names for the proxied object.
 +     *  Descendants need to fill this list by overriding the
 +     *  <code>setupPropertyList()</code> method.
 +     *  
 +     *  @langversion 3.0
 +     *  @playerversion Flash 9
 +     *  @playerversion AIR 1.1
 +     *  @productversion Flex 3
 +     */
 +    protected var propertyList:Array;
 +    
 +    /**
 +     *  Indicates how deep proxying should be performed.
 +     *  If -1 (default), always proxy; 
 +     *  if this value is zero, no proxying will be performed.
 +     *  
 +     *  @langversion 3.0
 +     *  @playerversion Flash 9
 +     *  @playerversion AIR 1.1
 +     *  @productversion Flex 3
 +     */
 +    private var _proxyLevel:int;
 +    
 +    //--------------------------------------------------------------------------
 +    //
 +    //  Properties
 +    //
 +    //--------------------------------------------------------------------------
 +
 +    //----------------------------------
 +    //  object
 +    //----------------------------------
 +
 +    /**
 +     *  Storage for the object property.
 +     *  
 +     *  @langversion 3.0
 +     *  @playerversion Flash 9
 +     *  @playerversion AIR 1.1
 +     *  @productversion Flex 3
 +     */
 +    private var _item:Object;
 +
 +    /**
 +     *  The object being proxied.
 +     *  
 +     *  @langversion 3.0
 +     *  @playerversion Flash 9
 +     *  @playerversion AIR 1.1
 +     *  @productversion Flex 3
 +     */
 +	COMPILE::LATER
 +    object_proxy function get object():Object
 +    {
 +        return _item;
 +    }
 +
 +    //----------------------------------
 +    //  type
 +    //----------------------------------
 +
 +    /**
 +     *  @private
 +     *  Storage for the qualified type name.
 +     */
 +	COMPILE::LATER
 +    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
 +     */
 +	COMPILE::LATER
 +    object_proxy function get type():QName
 +    {
 +        return _type;
 +    }
 +
 +    /**
 +     *  @private
 +     */
 +	COMPILE::LATER
 +    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
 +     */
- 	COMPILE::AS3
++	COMPILE::SWF
 +    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;
 +    }
 +	COMPILE::JS
 +	override public function getProperty(name:String):*
 +	{
 +		// 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
 +     */
- 	COMPILE::AS3
++	COMPILE::SWF
 +    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
 +     */
- 	COMPILE::AS3
++	COMPILE::SWF
 +    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;
 +    }
 +	COMPILE::JS
 +	override public function deleteProperty(name:String):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
 +     */
- 	COMPILE::AS3
++	COMPILE::SWF
 +    override flash_proxy function hasProperty(name:*):Boolean
 +    {
 +        return(name in _item);
 +    }
 +	COMPILE::JS
 +	override public function hasProperty(name:String):Boolean
 +	{
 +		return(name in _item);
 +	}
 +    
 +    /**
 +     *  @private
 +     */
- 	COMPILE::AS3
++	COMPILE::SWF
 +    override flash_proxy function nextName(index:int):String
 +    {
 +        return propertyList[index -1];
 +    }
 +    
 +    /**
 +     *  @private
 +     */
- 	COMPILE::AS3
++	COMPILE::SWF
 +    override flash_proxy function nextNameIndex(index:int):int
 +    {
 +        if (index == 0)
 +        {
 +            setupPropertyList();
 +        }
 +        
 +        if (index < propertyList.length)
 +        {
 +            return index + 1;
 +        }
 +        else
 +        {
 +            return 0;
 +        }
 +    }
 +    
 +    /**
 +     *  @private
 +     */
- 	COMPILE::AS3
++	COMPILE::SWF
 +    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
 +     */
- 	COMPILE::AS3
++	COMPILE::SWF
 +    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);
 +            } 
 +        }
 +    }
 +	COMPILE::JS
 +	override public function setProperty(name:String, 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))
 +			{
 +				COMPILE::LATER
 +				{
 +				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
 +     */
- 	COMPILE::AS3
++	COMPILE::SWF
 +    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
 +     */
- 	COMPILE::AS3
++	COMPILE::SWF
 +    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
 +     */
- 	COMPILE::AS3
++	COMPILE::SWF
 +    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
 +     */
- 	COMPILE::AS3
++	COMPILE::SWF
 +    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
 +     */
- 	COMPILE::AS3
++	COMPILE::SWF
 +    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
 +     */
- 	COMPILE::AS3
++	COMPILE::SWF
 +    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
 +     */
- 	COMPILE::AS3
++	COMPILE::SWF
 +    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;
 +        }
 +    }
 +}
 +
 +}