You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ha...@apache.org on 2016/09/27 09:50:08 UTC

[23/28] git commit: [flex-asjs] [refs/heads/refactor-sprite] - Initial sweep through wide set of Reflection functionality. Currently only verified as compatible between platforms within the FlexJS classes. This update requires corresponding Falcon/Falcon

Initial sweep through wide set of Reflection functionality. Currently only verified as compatible between platforms within the FlexJS classes. This update requires corresponding Falcon/FalconJX updates


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

Branch: refs/heads/refactor-sprite
Commit: 92c0a8b46b931764376f198d417cf31ae557c35f
Parents: fd05c96
Author: greg-dove <gr...@gmail.com>
Authored: Mon Sep 26 15:16:27 2016 +1300
Committer: greg-dove <gr...@gmail.com>
Committed: Tue Sep 27 19:52:42 2016 +1300

----------------------------------------------------------------------
 .../flex/reflection/AccessorDefinition.as       |  86 ++
 .../apache/flex/reflection/DefinitionBase.as    |   4 +-
 .../flex/reflection/DefinitionWithMetaData.as   |  46 +-
 .../flex/reflection/MetaDataArgDefinition.as    |  24 +-
 .../flex/reflection/MetaDataDefinition.as       |  66 +-
 .../apache/flex/reflection/MethodDefinition.as  | 105 ++-
 .../flex/reflection/ParameterDefinition.as      |  84 ++
 .../apache/flex/reflection/TypeDefinition.as    | 823 ++++++++++++++++---
 .../flex/reflection/VariableDefinition.as       |  36 +-
 .../org/apache/flex/reflection/describeType.as  |  12 +-
 .../apache/flex/reflection/getAliasByClass.as   |  47 ++
 .../apache/flex/reflection/getClassByAlias.as   |  43 +
 .../flex/reflection/registerClassAlias.as       |  44 +
 13 files changed, 1259 insertions(+), 161 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/AccessorDefinition.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/AccessorDefinition.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/AccessorDefinition.as
new file mode 100644
index 0000000..e6cf2b4
--- /dev/null
+++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/AccessorDefinition.as
@@ -0,0 +1,86 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 org.apache.flex.reflection {
+    /**
+     *  The description of a Class or Interface accessor (get and/or set)
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10.2
+     *  @playerversion AIR 2.6
+     *  @productversion FlexJS 0.0
+     */
+    public class AccessorDefinition extends VariableDefinition
+    {
+        public function AccessorDefinition(name:String, rawData:Object) {
+            super(name, rawData);
+        }
+        /**
+         * The type that defined this accessor
+         * This could be an ancestor class of the method's containing TypeDefinition
+         */
+        public function get declaredBy():TypeDefinition
+        {
+            COMPILE::SWF{
+                var declareBy:String = _rawData.@declaredBy;
+            }
+            COMPILE::JS{
+                var declareBy:String = _rawData.declaredBy;
+            }
+            return TypeDefinition.getDefinition(declareBy);
+        }
+
+
+        private var _access:String;
+        /**
+         * The type of access that this accessor has.
+         * One of: 'readonly', 'writeonly', or 'readwrite'
+         * Note, these values are all lower case (not camelCase).
+         */
+        public function get access():String
+        {
+            if (_access) return _access;
+
+            COMPILE::SWF {
+                _access=rawData.@access;
+            }
+            COMPILE::JS {
+                _access = rawData.access;
+            }
+
+            return _access;
+        }
+
+        /**
+         * A string representation of this accessor definition
+         */
+        override public function toString():String{
+            var s:String = "accessor: '"+name+"' access:"+access+", type:"+type.qualifiedName+", declaredBy:"+declaredBy.qualifiedName;
+            var meta:Array = metadata;
+            var i:uint;
+            var l:uint = meta.length;
+            if (l) {
+                s += "\n\tmetadata:";
+                for (i=0;i<l;i++) {
+                    s += "\n\t\t" + meta[i].toString().split("\n").join("\n\t\t");
+                }
+            }
+            return s;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionBase.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionBase.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionBase.as
index f8bdd82..5868eaf 100755
--- a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionBase.as
+++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionBase.as
@@ -20,7 +20,7 @@ package org.apache.flex.reflection
 {
     
     /**
-     *  The description of a Class or Interface
+     *  The base class for all definition types
      * 
      *  @langversion 3.0
      *  @playerversion Flash 10.2
@@ -35,7 +35,7 @@ package org.apache.flex.reflection
             _rawData = rawData;
         }
         
-        private var _name:String;
+        protected var _name:String;
         public function get name():String
         {
             return _name;

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionWithMetaData.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionWithMetaData.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionWithMetaData.as
index b9179fe..e32d597 100755
--- a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionWithMetaData.as
+++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionWithMetaData.as
@@ -20,7 +20,8 @@ package org.apache.flex.reflection
 {
     
     /**
-     *  The description of a Class or Interface
+     *  The base class for definition types that can be decorated with metadata in actionscript
+     *  source code
      * 
      *  @langversion 3.0
      *  @playerversion Flash 10.2
@@ -33,21 +34,29 @@ package org.apache.flex.reflection
         {
             super(name, rawData);
         }
-        
+
+        COMPILE::SWF
+        protected var useFactory:Boolean;
+
+
+        private var _metaData:Array;
+        /**
+         * gets a copy of the metadata collection array
+         */
         public function get metadata():Array
         {
+            if (_metaData) return _metaData.slice();
             var results:Array = [];
-            
             COMPILE::SWF
             {
-                var xml:XML = rawData as XML;
+                var xml:XML = useFactory ? rawData.factory[0] as XML : rawData as XML;
                 var data:XMLList = xml.metadata;
                 var n:int = data.length();
                 for (var i:int = 0; i < n; i++)
                 {
                     var item:XML = data[i] as XML;
-                    var qname:String = item.@name;
-                    results.push(new MetaDataDefinition(qname, item));
+                    var metaName:String = item.@name;
+                    results[i] = new MetaDataDefinition(metaName, item);
                 }
             }
             COMPILE::JS
@@ -67,13 +76,32 @@ package org.apache.flex.reflection
                     var metadatas:Array = rdata.metadata();
                     if (metadatas)
                     {
-                        var n:int = metadatas.length;
-                        for each (var mdDef:Object in metadatas)
-                        results.push(new MetaDataDefinition(mdDef.name, mdDef));
+                        var i:uint = 0;
+                        var l:int = metadatas.length;
+                        for (;i<l;i++) {
+                            var mdDef:Object = metadatas[i];
+                            results[i] = new MetaDataDefinition(mdDef.name, mdDef);
+                        }
                     }
                 }
             }
+            _metaData = results.slice();
             return results;                        
         }
+
+        /**
+         * A convenience method for retrieving metadatas
+         * @param name the name of the metadata item to retrieve.
+         *        It can occur more than once, so an array is returned
+         * @return an array of all MetaDataDefinition items with matching 'name'
+         *
+         */
+        public function retrieveMetaDataByName(name:String):Array {
+            var source:Array = _metaData || metadata;
+            var results:Array = [];
+            var i:uint=0, l:uint = source.length;
+            for(;i<l;i++) if (source[i].name == name) results.push(source[i]);
+            return results;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataArgDefinition.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataArgDefinition.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataArgDefinition.as
index 1f1366f..2224f52 100755
--- a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataArgDefinition.as
+++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataArgDefinition.as
@@ -36,10 +36,30 @@ package org.apache.flex.reflection
         }
         
         private var _value:String;
-        
+        /**
+         * the 'key' value of a metadata argument
+         * in [Event(name="boom")]
+         * the value for the 1st (only) argument
+         * is 'boom'
+         */
         public function get value():String
         {
             return _value;
-        }        
+        }
+
+        /**
+         * the 'key' value of a metadata argument
+         * in [Event(name="boom")]
+         * the key for the 1st (only) argument
+         * is 'name'
+         */
+        public function get key():String{
+            return _name;
+        }
+
+        public function toString():String
+        {
+            return "arg: key:'"+_name+"', value:'"+_value+"'";
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataDefinition.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataDefinition.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataDefinition.as
index 48efac8..8805b69 100755
--- a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataDefinition.as
+++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataDefinition.as
@@ -20,7 +20,7 @@ package org.apache.flex.reflection
 {
     
     /**
-     *  The description of a Class or Interface
+     *  The description of a MetaData tag attached to a class member or a class
      * 
      *  @langversion 3.0
      *  @playerversion Flash 10.2
@@ -33,11 +33,19 @@ package org.apache.flex.reflection
         {
             super(name, rawData);
         }
-        
+
+        private var _args:Array;
+        /**
+         * The argument pairs (if any) associated with a Metadata tag
+         * in [Event(name="boom")]
+         * the args array would be of length 1
+         * the array contains MetaDataArgDefinitions
+         */
         public function get args():Array
         {
+            if (_args) return _args.slice();
             var results:Array = [];
-            
+
             COMPILE::SWF
             {
                 var xml:XML = rawData as XML;
@@ -59,13 +67,57 @@ package org.apache.flex.reflection
                     var args:Array = rdata.args;
                     if (args)
                     {
-                        var n:int = args.length;
-                        for each (var argDef:Object in args)
-                        results.push(new MetaDataArgDefinition(argDef.key, argDef.value));
+                        args = args.slice();
+                        while(args.length) {
+                            var argDef:Object = args.shift();
+                            results.push(new MetaDataArgDefinition(argDef.key, argDef.value));
+                        }
                     }
                 }
             }
-            return results;            
+            //fully populated, so release rawData ref
+            _rawData = null;
+            _args = results.slice();
+            return  results;
+        }
+
+        /**
+         * convenience method for retrieving a set of args with a specific key
+         * Most often this would be of length 1, but it is possible for there to be
+         * multiple MetaDataArgDefinitions with the same key
+         * @param key the key to search for
+         * @return an array of MetaDataArgDefinitions with the matching key.
+         */
+        public function getArgsByKey(key:String):Array{
+            var ret:Array=[];
+            var source:Array = _args || args;
+            var i:uint=0, l:uint=source.length;
+            for (;i<l;i++) {
+                var arg:MetaDataArgDefinition = source[i];
+                if (arg.key == key) ret.push(arg);
+            }
+            return ret;
+        }
+
+        /**
+         * Used primarily for debugging purposes, this provides a string representation of this
+         * MetaDataDefinition
+         * @return a String representation of this MetaDataDefinition
+         */
+        public function toString():String
+        {
+            var s:String="item: '"+_name +"', ";
+            var args:Array = this.args;
+            var i:uint;
+            var l:uint = args.length;
+            if (!l) s+= "args:{none}";
+            else {
+                s+= "args:";
+                for (i=0;i<l;i++) {
+                    s+="\n\t"+args[i].toString();
+                }
+            }
+            return s;
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MethodDefinition.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MethodDefinition.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MethodDefinition.as
index a16c649..b58c7af 100755
--- a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MethodDefinition.as
+++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MethodDefinition.as
@@ -20,7 +20,7 @@ package org.apache.flex.reflection
 {
     
     /**
-     *  The description of a Class or Interface
+     *  The description of a method inside a class or interface
      * 
      *  @langversion 3.0
      *  @playerversion Flash 10.2
@@ -29,21 +29,104 @@ package org.apache.flex.reflection
      */
     public class MethodDefinition extends DefinitionWithMetaData
 	{
-        public function MethodDefinition(name:String, declaredBy:String, rawData:Object = null)
+        public function MethodDefinition(name:String, rawData:Object)
         {
             super(name, rawData);
-            _declaredBy = declaredBy;
         }
-        
-        private var _declaredBy:String;
-        private var declaredByDef:TypeDefinition;
-        
+
+        /**
+         * The type that defined this method
+         * This could be an ancestor class of the method's containing TypeDefinition
+         */
         public function get declaredBy():TypeDefinition
         {
-            if (declaredByDef == null)
-                declaredByDef = new TypeDefinition(_declaredBy);
-            
-            return declaredByDef;
+            COMPILE::SWF{
+                var declareBy:String = _rawData.@declaredBy;
+            }
+            COMPILE::JS{
+                var declareBy:String = _rawData.declaredBy;
+            }
+            return TypeDefinition.getDefinition(declareBy);
+        }
+
+        private var _parameters:Array;
+        /**
+         * The collection of parameters defined for this method
+         * each parameter is represented by a ParameterDefinition instance
+         */
+        public function get parameters():Array {
+            var results:Array;
+            if (_parameters) {
+                results = _parameters.slice();
+               if (!TypeDefinition.useCache) _parameters = null;
+               return results;
+            }
+            results = [];
+            COMPILE::SWF {
+                var xml:XML = rawData as XML;
+                var data:XMLList = xml.parameter;
+                var n:int = data.length();
+                for (var i:int = 0; i < n; i++)
+                {
+                    var item:XML = data[i] as XML;
+                    results.push(new ParameterDefinition(uint(item.@index),item));
+                }
+            }
+            COMPILE::JS {
+                if (rawData.parameters != null) {
+                    var data:Array = rawData.parameters();
+                    var n:int = data.length;
+                    for (var i:int = 0; i < n; i++)
+                    {
+                        var item:Object = data[i];
+                        results.push(new ParameterDefinition(uint(item.index),item));
+                    }
+                }
+            }
+
+            if (TypeDefinition.useCache) _parameters = results;
+            return results;
+        }
+        /**
+         * The return type for this method
+         * note: a return type may be "*" or "void"
+         */
+        public function get returnType():TypeDefinition {
+            COMPILE::SWF{
+                var returnType:String = _rawData.@returnType;
+            }
+
+            COMPILE::JS{
+                var returnType:String = _rawData.type;
+            }
+
+            return TypeDefinition.getDefinition(returnType);
+        }
+
+        /**
+         * A string representation of this method definition
+         */
+        public function toString():String{
+            var retType:String=returnType.qualifiedName;
+            if (retType=="") retType ="''";
+            var s:String="method: '"+name +"', returnType:"+retType+" declaredBy:"+declaredBy.qualifiedName;
+            var params:Array = parameters;
+            var i:uint;
+            var l:uint = params.length;
+            if (!l) s+="\n\t{No parameters}";
+            else
+                for (i=0;i<l;i++) {
+                    s+="\n\t"+params[i].toString();
+                }
+            var meta:Array = metadata;
+            l = meta.length;
+            if (l) {
+                s += "\n\tmetadata:";
+                for (i=0;i<l;i++) {
+                    s += "\n\t\t" + meta[i].toString().split("\n").join("\n\t\t");
+                }
+            }
+            return s;
         }
         
     }

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/ParameterDefinition.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/ParameterDefinition.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/ParameterDefinition.as
new file mode 100644
index 0000000..b552e33
--- /dev/null
+++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/ParameterDefinition.as
@@ -0,0 +1,84 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 org.apache.flex.reflection
+{
+    
+    /**
+     *  The description of a Function parameter
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10.2S
+     *  @playerversion AIR 2.6
+     *  @productversion FlexJS 0.0
+     */
+    public class ParameterDefinition extends DefinitionBase
+	{
+
+        public function ParameterDefinition( index:uint, rawData:Object)
+        {
+            super("parameter "+index, rawData);
+        }
+
+		/**
+		 * The type of this parameter
+		 */
+		public function get type():TypeDefinition{
+			COMPILE::SWF {
+				return TypeDefinition.getDefinition(_rawData.@type);
+			}
+
+			COMPILE::JS {
+				return TypeDefinition.getDefinition(_rawData.type);
+			}
+
+		}
+		/**
+		 * Whether this parameter is optional (has a default value) or not
+		 */
+		public function get optional():Boolean {
+			COMPILE::SWF {
+				return _rawData.@optional == "true";
+			}
+
+			COMPILE::JS {
+				return _rawData.optional;
+			}
+
+		}
+		/**
+		 * The 1-based index of this parameter in its owner function/method
+		 */
+		public function get index():uint{
+			COMPILE::SWF {
+				return uint(_rawData.@index);
+			}
+
+			COMPILE::JS {
+				return _rawData.index;
+			}
+
+		}
+        /**
+         * A string representation of this parameter definition
+         */
+		public function toString():String{
+			return _name+", optional:"+optional+", type:"+type.qualifiedName;
+		}
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/TypeDefinition.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/TypeDefinition.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/TypeDefinition.as
index cf69bd1..7070e5a 100755
--- a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/TypeDefinition.as
+++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/TypeDefinition.as
@@ -18,6 +18,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 package org.apache.flex.reflection
 {
+COMPILE::SWF {
+  import flash.utils.describeType;
+}
     
     /**
      *  The description of a Class or Interface
@@ -29,232 +32,802 @@ package org.apache.flex.reflection
      */
     public class TypeDefinition extends DefinitionWithMetaData
 	{
+
+        COMPILE::JS {
+            //js storage support for class aliases
+            private static var _aliasMappings:Object={};
+
+            /**
+             * @private
+             * @param aliasName
+             * @param classObject
+             */
+            internal static function registerClassAlias(aliasName:String, classObject:Class ) :void{
+                var info:* = classObject.FLEXJS_CLASS_INFO;
+                if (info) {
+                    //a class may have more than one alias point to it, but only the most recently registered
+                    //alias is retained for reflection (applying same approach as swf)
+                    var alias:String = info.alias;
+                    if (alias) {
+                        if (alias == aliasName) {
+                            if (_aliasMappings[aliasName] == classObject) return; //nothing to do
+                        }
+                    }
+                    //check for alternate mapping, remove any alternative mapping
+                    //from the other class's FLEXJS_CLASS_INFO
+                    var altClass:Class = _aliasMappings[aliasName];
+                    if (altClass) {
+                        var altInfo:* = altClass.FLEXJS_CLASS_INFO;
+                        delete altInfo.alias;
+                    }
+                    _aliasMappings[aliasName] = classObject;
+                    info.alias = aliasName;
+                } else throw new Error("registerClassAlias error: classObject is not Reflectable "+classObject);
+            }
+
+            /**
+             * @private
+             * @param aliasName
+             * @return
+             */
+            internal static function getClassByAlias(aliasName:String):Class {
+                return _aliasMappings[aliasName];
+            }
+
+        }
+
+
+
+        //special cases
+        private static const SC:Array=['void','null','*',''];
+
+
+
+        private static var _cache:Object;
+
+        public static function get useCache():Boolean{
+            return _cache != null;
+        }
+
+        public static function set useCache(value:Boolean):void{
+            if (value) {
+                if (!_cache) _cache = {};
+            } else if (_cache) _cache = null;
+        }
+
+
+        /**
+         * The static getDefinition method is the primary access to TypeDefinitions. Although the
+         * constructor does not have a lock to prevent use (for performance reasons), using it directly
+         * is discouraged.
+         * @param name the qualified name of the definition,
+         * @param rawData (optional) the reflection data if already available
+         * @return a TypeDefinition representing the class or interface represented by the parameters
+         */
+        public static function getDefinition(name:String, rawData:Object = null):TypeDefinition {
+            return _cache ? (_cache[name] || new TypeDefinition(name, rawData)) : new TypeDefinition(name, rawData);
+        }
+
+        /**
+         * The static TypeDefinitions.getDefinition method is the primary access to TypeDefinitions. Although the
+         * constructor does not have a lock to prevent use (for performance reasons), using it directly
+         * is discouraged.
+         * Most of the time you should retrieve TypeDefinitions with org.apache.flex.reflection.describeType()
+         */
         public function TypeDefinition(name:String, rawData:Object = null)
         {
-            var c:int = name.indexOf("::");
-            if (c > -1)
-            {
-                _packageName = name.substring(0, c);
-                name = name.substring(c+2);
-            }
-            else
-                _packageName = "";
+            if (_cache) _cache[name] = this;
+
+			var c:int;
+			COMPILE::SWF{
+				c = name.indexOf("::");
+				if (c > -1)
+				{
+					_packageName = name.substr(0, c);
+					name = name.substr(c+2);
+				}
+				else
+					_packageName = "";
+                //this definition sets a flag for where to find the metadata:
+                useFactory = true;
+			}
+			COMPILE::JS{
+				c = name.lastIndexOf(".");
+				if (c > -1)
+				{
+					_packageName = name.substr(0, c);
+					name = name.substr(c+1);
+				}
+				else
+					_packageName = "";
+			}
+            _specialCase = _packageName=="" && SC.indexOf(name) != -1;
             super(name, rawData);
         }
-        
-        private var _packageName:String;
-        
+
+        protected var _kind:String;
+        /**
+         * The type of definition this TypeDefinition describes
+         * values can be "class", "interface", "unknown"
+         * This can sometimes be different between swf and js
+         * targets.
+         */
+        public function get kind():String{
+            if (_kind) return _kind;
+
+            COMPILE::SWF {
+                var xml:XML = rawData as XML;
+                if (xml) {
+                    //double check we have the uppermost definition
+                    if (xml.@isStatic!="true") _kind = "class";
+                    var factory:XML = xml.factory[0];
+                    //all classes have an extends class, except for Object
+                    if (!factory || factory.extendsClass.length() || factory.@type=="Object") _kind="class";
+                    else _kind="interface";
+                }
+            }
+
+            COMPILE::JS {
+                var data:Object = rawData;
+                _kind = data.names[0].kind;
+            }
+
+            return _kind || "unknown";
+        }
+
+        /**
+         * convenience check for whether this definition
+         * represents a Class or instance of a Class
+         */
+        public function get isClass():Boolean{
+            return (_kind || kind) == "class";
+        }
+        /**
+         * convenience check for whether this definition
+         * represents an interface
+         */
+        public function get isInterface():Boolean{
+            return (_kind || kind) == "interface";
+        }
+
+
+        private var _specialCase:Boolean;
+
+        protected var _packageName:String;
+        /**
+         * The package name for this TypeDefinition
+         */
         public function get packageName():String
         {
             return _packageName;
-        }        
-        
+        }
+        /**
+         * The qualified name for this TypeDefinition
+         */
+        public function get qualifiedName():String{
+            if (_packageName.length) return _packageName + "." + _name;
+            else return _name;
+        }
+
+        /**
+         * @private
+         */
         override protected function get rawData():Object
         {
-            if (_rawData == null)
-            {
-                var def:Object = getDefinitionByName(packageName + "::" + name);
-                COMPILE::SWF
+            var def:Object;
+            COMPILE::SWF {
+                if (_rawData == null)
                 {
-                    _rawData = describeType(def);                        
+                    if (_packageName.length)
+                        def = getDefinitionByName(_packageName + "::" + _name);
+                    else def = getDefinitionByName(_name);
+                    _rawData = flash.utils.describeType(def);
+
                 }
-                COMPILE::JS
+            }
+
+            COMPILE::JS{
+                if (_rawData == null)
                 {
+                    if (_packageName.length)
+                        def = getDefinitionByName(_packageName + "." + _name);
+                    else def = getDefinitionByName(_name);
                     _rawData = def.prototype.FLEXJS_CLASS_INFO;
                 }
             }
             return _rawData;
         }
+
+        /** class specific support */
+
+        private var _constructorMethod:MethodDefinition;
+        /**
+         * A MethodDefinition representing the constructor for a "class" kind TypeDefinition
+         * For an interface this returns null.
+         */
+        public function get constructorMethod():MethodDefinition{
+            if ((_kind || kind) != "class") return null;
+            COMPILE::SWF {
+                if (!_constructorMethod) {
+                    var source:XML = rawData.factory.constructor[0];//['constructor'][0];
+                    var declaredBy:String = _packageName.length? _packageName+"::"+_name : _name;
+                    if (source ==null) {
+                        //constructor with no params
+                        _constructorMethod =
+                                new MethodDefinition(_name, XML('<method name="'+_name+'" declaredBy="'+declaredBy+'" returnType="" />'));
+                    } else {
+                        var params:XMLList = source.parameter;
+                        _constructorMethod=new MethodDefinition(_name, XML('<method name="'+_name+'" declaredBy="'+declaredBy+'" returnType="">'+params.toXMLString()+'</method>'))
+                    }
+                }
+            }
+
+            COMPILE::JS {
+                if (!_constructorMethod) {
+                    var temp:Array = getCollection("methods","instance",false);
+                    var i:int=0, l:int=temp.length;
+                    for (;i<l;i++) {
+                        if (temp[i].name == _name) {
+                            //trace('found constructor '+results[i].toString());
+                            _constructorMethod = temp[i];
+                            break;
+                        }
+                    }
+                }
+            }
+
+            return _constructorMethod;
+        }
+        
+        
+        private var _baseClasses:Array;
         /**
+         * For a "class" kind TypeDefinition, this returns the TypeDefinitions
+         * of the base classes (inheritance chain). This may differ between
+         * javascript and flash platform targets for some classes.
          *  @flexjsignorecoercion XML 
          */
         public function get baseClasses():Array
         {
-            var results:Array = [];
+
+            var results:Array;
+            if (_baseClasses) {
+                results =_baseClasses.slice();
+                if (!_cache) _baseClasses = null;
+                return results;
+            }
+            if ((_kind || kind) != "class") return [];
+
+            results = [];
+            //handle special cases
+            if (_specialCase) {
+                if (_cache) {
+                    _baseClasses = results;
+                    results = results.slice();
+                }
+                return results;
+            }
             
             COMPILE::SWF
             {
                 var xml:XML = rawData as XML;
-                var data:XMLList = xml.extendsClass;
+                var data:XMLList = xml.factory.extendsClass;
                 var n:int = data.length();
                 for (var i:int = 0; i < n; i++)
                 {
                     var item:XML = data[i] as XML;
                     var qname:String = item.@type;
-                    results.push(new TypeDefinition(qname));
+                    results.push(TypeDefinition.getDefinition(qname));
                 }
             }
             COMPILE::JS
             {
                 var data:Object = rawData;
-                var name:String = data.names[0].qName;
-                var def:Object = getDefinitionByName(name);
-                var prototype:Object = def.prototype;
-                while (prototype.FLEXJS_CLASS_INFO !== undefined)
+                var qname:String = data.names[0].qName;
+                var def:Object = getDefinitionByName(qname);
+                var superClass:Object = def.superClass_;
+                if (!superClass) {
+                    //todo: support for when superClass is not a flexjs 'class'
+                } else while (superClass)
                 {
-                    name = prototype.FLEXJS_CLASS_INFO.names[0].qName;
-                    results.push(new TypeDefinition(name));
-                    def = getDefinitionByName(name);
-                    prototype = def.prototype;
+                    if (superClass.FLEXJS_CLASS_INFO !== undefined) {
+                        qname = superClass.FLEXJS_CLASS_INFO.names[0].qName;
+                        results.push(TypeDefinition.getDefinition(qname));
+                        def = getDefinitionByName(qname);
+                        superClass = def.superClass_;
+                        //todo: support for when superClass is not a flexjs 'class'
+
+                    } else {
+                        //todo: support for when superClass is not a flexjs 'class'
+                        superClass = null;
+                    }
                 }
             }
+            
+            if (_cache) {
+                _baseClasses = results;
+                results = results.slice();
+            }
             return results;
         }
-        
+
+        private var _interfaces:Array;
+        /**
+         * returns the full set of interfaces that this class implements or that this
+         * interface extends, depending on the 'kind' value ("interface" or "class")
+         */
         public function get interfaces():Array
         {
-            var results:Array = [];
+            var results:Array;
+            if (_interfaces) {
+                results =_interfaces.slice();
+                if (!_cache) _interfaces = null;
+                return results;
+            }
+            results = [];
+            //handle special cases
+            if (_specialCase) {
+                if (_cache) {
+                    _interfaces = results;
+                    results = results.slice();
+                }
+                return results;
+            }
             
             COMPILE::SWF
             {
                 var xml:XML = rawData as XML;
-                var data:XMLList = xml.implementsInterface;
+                var data:XMLList = xml.factory.implementsInterface;
                 var n:int = data.length();
                 for (var i:int = 0; i < n; i++)
                 {
                     var item:XML = data[i] as XML;
                     var qname:String = item.@type;
-                    results.push(new TypeDefinition(qname));
+                    results.push(TypeDefinition.getDefinition(qname));
                 }
             }
             COMPILE::JS
             {
                 var data:* = rawData;
-                var name:String = data.names[0].qName;
-                var def:Object = getDefinitionByName(name);
-                var prototype:Object = def.prototype;
-                while (data !== undefined)
+                var i:uint, n:int;
+                if (data !== undefined)
                 {
-                    var interfaces:Array = data.interfaces;
-                    if (interfaces)
-                    {
-                        var n:int = interfaces.length;
-                        for each (var s:String in interfaces)
-                            results.push(new TypeDefinition(s));
+                    var collect:Array = data.interfaces || [];
+                    var qname:String = data.names[0].qName;
+                    var def:Object = getDefinitionByName(qname);
+                    if ((_kind || kind) == "interface") {
+                        //collect.length can expand during the loop below
+                        for (i = 0; i < collect.length; i++) {
+                            collect.push.apply(collect, (collect[i].prototype.FLEXJS_CLASS_INFO.interfaces || []));
+                        }
+                    } else {
+                        var superClass:Object = def.superClass_;
+                        while (superClass && superClass.FLEXJS_CLASS_INFO !== undefined)
+                        {
+                            data = superClass.FLEXJS_CLASS_INFO;
+                            var latest:Array = data.interfaces;
+                            if (latest) {
+                                n = latest.length;
+                                for (i=0;i<n;i++) if (collect.indexOf(latest[i])==-1) collect.push(latest[i]);
+                            }
+                            qname = data.names[0].qName;
+                            def = getDefinitionByName(qname);
+                            superClass = def.superClass_;
+                        }
+                    }
+                    n = collect.length;
+                    for (i=0;i<n;i++) {
+                        var iface:Object = collect[i];
+                        data = iface.prototype.FLEXJS_CLASS_INFO;
+                        results[i] = TypeDefinition.getDefinition(data.names[0].qName,data);
                     }
-                    name = data.names[0].qName;
-                    results.push(new TypeDefinition(name));
-                    def = getDefinitionByName(name);
-                    prototype = def.prototype;
-                    data = prototype.FLEXJS_CLASS_INFO;
                 }
             }
+
+            if (_cache) {
+                _interfaces = results;
+                results = results.slice();
+            }
             return results;            
         }
-        
+
+
+        private var _staticVars:Array;
+
+        /**
+         * The static variables associated with a "class" kind TypeDefinition
+         * An array of VariableDefinition instances
+         */
+        public function get staticVariables():Array
+        {
+
+            if ((_kind || kind) != "class") return [];
+            var results:Array;
+            if (_staticVars) {
+                results =_staticVars.slice();
+                if (!_cache) _staticVars = null;
+                return results;
+            }
+            COMPILE::SWF {
+                results = getCollection("variable","static");
+            }
+            COMPILE::JS
+            {
+                results = getCollection("variables","static",false);
+            }
+            if (_cache) {
+                _staticVars = results;
+                results = results.slice();
+            }
+            return results;
+        }
+
+        private var _staticAccessors:Array;
+        /**
+         * The static accessors associated with a "class" kind TypeDefinition
+         * An array of AccessorDefinition instances
+         */
+        public function get staticAccessors():Array
+        {
+
+            if ((_kind || kind) != "class") return [];
+            var results:Array;
+            if (_staticAccessors) {
+                results =_staticAccessors.slice();
+                if (!_cache) _staticAccessors = null;
+                return results;
+            }
+            COMPILE::SWF {
+                results = getCollection("accessor","static");
+            }
+            COMPILE::JS
+            {
+                results = getCollection("accessors","static",false);
+            }
+            if (_cache) {
+                _staticAccessors = results;
+                results = results.slice();
+            }
+            return results;
+        }
+
+
+        private var _staticMethods:Array;
+        /**
+         * The static methods associated with a "class" kind TypeDefinition
+         * An array of MethodDefinition instances
+         */
+        public function get staticMethods():Array
+        {
+
+            if ((_kind || kind) != "class") return [];
+            var results:Array;
+            if (_staticMethods) {
+                results =_staticMethods.slice();
+                if (!_cache) _staticMethods = null;
+                return results;
+            }
+            COMPILE::SWF {
+                results = getCollection("method","static");
+            }
+            COMPILE::JS
+            {
+                results = getCollection("methods","static",false);
+            }
+            if (_cache) {
+                _staticMethods = results;
+                results = results.slice();
+            }
+            return results;
+        }
+
+
+
+
+        private var _variables:Array;
+        /**
+         * The instance variables associated with a "class" kind TypeDefinition
+         * An array of VariableDefinition instances
+         */
         public function get variables():Array
         {
-            var results:Array = [];
+
+            var results:Array;
+            if (_variables) {
+                results =_variables.slice();
+                if (!_cache) _variables = null;
+                return results;
+            }
+            if ((_kind || kind) != "class") return [];
+            //handle special cases
+            if (_specialCase) {
+                results = [];
+                if (_cache) {
+                    _variables = results = [];
+                    results = results.slice();
+                }
+                return results;
+            }
             
             COMPILE::SWF
             {
-                var xml:XML = rawData as XML;
-                var data:XMLList = xml.variable;
-                var n:int = data.length();
-                for (var i:int = 0; i < n; i++)
-                {
-                    var item:XML = data[i] as XML;
-                    var qname:String = item.@name;
-                    results.push(new VariableDefinition(qname, item));
-                }
+                results = getCollection("variable");
             }
             COMPILE::JS
             {
-                var data:Object = rawData;
-                var name:String = data.names[0].qName;
-                var def:Object = getDefinitionByName(name);
-                var rdata:* = def.prototype.FLEXJS_REFLECTION_INFO();
-                if (rdata !== undefined)
-                {
-                    var variables:Object = rdata.variables();
-                    if (variables)
-                    {
-                        for (var v:String in variables)
-                        {
-                            var varDef:Object = variables[v];
-                            results.push(new VariableDefinition(v, varDef));
-                        }
-                    }
-                }
+                results = getCollection("variables");
+            }
+            if (_cache) {
+                _variables = results;
+                results = results.slice();
             }
             return results;        
         }
         
+        private var _accessors:Array;
+        /**
+         * The instance accessors associated with a "class" kind TypeDefinition
+         * An array of AccessorDefinition instances
+         */
         public function get accessors():Array
         {
-            var results:Array = [];
+            var results:Array;
+            if (_accessors) {
+                results =_accessors.slice();
+                if (!_cache) _accessors = null;
+                return results;
+            }
+
+
+            //handle special cases
+            if (_packageName=="" && SC.indexOf(name)!=-1) {
+                results = [];
+                if (_cache) {
+                    _accessors = results;
+                    results=results.slice();
+                }
+                return results;
+            }
             
             COMPILE::SWF
             {
-                var xml:XML = rawData as XML;
-                var data:XMLList = xml.accessor;
-                var n:int = data.length();
-                for (var i:int = 0; i < n; i++)
-                {
-                    var item:XML = data[i] as XML;
-                    var qname:String = item.@name;
-                    results.push(new MethodDefinition(qname, item.@declaredBy, item));
-                }
+                results = getCollection("accessor");
             }
             COMPILE::JS
             {
-                var data:Object = rawData;
-                var name:String = data.names[0].qName;
-                var def:Object = getDefinitionByName(name);
-                var rdata:* = def.prototype.FLEXJS_REFLECTION_INFO();
-                if (rdata !== undefined)
-                {
-                    var accessors:Object = rdata.accessors();
-                    if (accessors)
-                    {
-                        for (var prop:String in accessors)
-                        {
-                             var propDef:Object = accessors[prop];
-                             results.push(new MethodDefinition(prop, propDef.declaredBy, propDef));
-                        }
-                    }
-                }
+                results = getCollection("accessors");
+            }
+            if (_cache) {
+                _accessors = results;
+                results = results.slice();
             }
             return results;            
         }
+
         
+        private var _methods:Array;
+        /**
+         * The instance methods associated with a "class" kind TypeDefinition
+         * An array of MethodDefinition instances
+         */
         public function get methods():Array
         {
-            var results:Array = [];
+            var results:Array;
+            if (_methods) {
+                results =_methods.slice();
+                if (!_cache) _methods = null;
+                return results;
+            }
+
+
+            //handle special cases
+            if (_packageName=="" && SC.indexOf(name)!=-1) {
+                results = [];
+                if (_cache) {
+
+                    _methods = results;
+                    results=results.slice();
+                }
+                return results;
+            }
             
             COMPILE::SWF
             {
-                var xml:XML = rawData as XML;
-                var data:XMLList = xml.method;
-                var n:int = data.length();
-                for (var i:int = 0; i < n; i++)
-                {
-                    var item:XML = data[i] as XML;
-                    var qname:String = item.@name;
-                    results.push(new MethodDefinition(qname, item.@declaredBy, item));
-                }
+                results = getCollection("method");
             }
             COMPILE::JS
             {
-                var data:Object = rawData;
-                var name:String = data.names[0].qName;
-                var def:Object = getDefinitionByName(name);
-                var rdata:* = def.prototype.FLEXJS_REFLECTION_INFO();
-                if (rdata !== undefined)
+                results = getCollection("methods");
+                //special case, remove constructor method:
+                var i:int=0, l:int=results.length;
+                for (;i<l;i++) {
+                    if (results[i].name==this.name) {
+                        //trace('found constructor '+results[i].toString());
+                        _constructorMethod = results[i];
+                        results.splice(i,1);
+                        break;
+                    }
+                }
+            }
+            if (_cache) {
+                _methods = results;
+                results = results.slice();
+            }
+            return results;            
+        }
+
+
+
+        COMPILE::SWF
+        protected function getCollection(collection:String, type:String="instance"):Array{
+            var lookups:Object = {
+                variable : VariableDefinition,
+                accessor : AccessorDefinition,
+                method : MethodDefinition
+            };
+            var results:Array =[];
+            var isStatic:Boolean = type=="static";
+            var xml:XML = rawData as XML;
+            var data:XMLList = isStatic? xml[collection] : xml.factory[collection];
+            var n:int = data.length();
+            var itemClass:Class = lookups[collection];
+            for (var i:int = 0; i < n; i++)
+            {
+                var item:XML = data[i] as XML;
+                var qname:String = item.@name;
+                results[i]= new itemClass(qname, item);
+            }
+            return results;
+        }
+
+
+        COMPILE::JS
+        protected function getCollection(collection:String,  type:String="instance", resolve:Boolean = true):Array{
+           var lookups:Object = {
+               variables : VariableDefinition,
+               accessors : AccessorDefinition,
+               methods : MethodDefinition
+           };
+           if (!collection in lookups) throw new Error("ArgumentError: name must be a standard name [variables,accessors,methods]") ;
+           var isStatic:Boolean =  type == "static";
+           var results:Array = [];
+
+           var data:Object = rawData;
+           var qname:String = data.names[0].qName;
+           var def:Object = getDefinitionByName(qname);
+           var rdata:* =  def.prototype.FLEXJS_REFLECTION_INFO();
+
+           var itemClass:Class = lookups[collection];
+
+           var l:int, i:int = 0;
+           if (resolve) {
+               if (isStatic) throw new Error("ArgumentError : resolve and static are not compatible");
+               //get ancestor items, and record the names for overrides
+               var oldNames:Array=[];
+               var superClass:Object = def.superClass_;
+               if (superClass) data = superClass.FLEXJS_CLASS_INFO;
+               else data = null;
+
+               if (data) {
+                   results = TypeDefinition.getDefinition(data.names[0].qName,data)[collection];
+                   l=results.length;
+                   for (i=0;i<l;i++) oldNames[i]=results[i].name;
+               } else results=[];
+           }
+           //get the local definitions
+            if (rdata !== undefined)
+            {
+                var items:Object = rdata[collection]();
+                if (items)
                 {
-                    var methods:Object = rdata.methods();
-                    if (methods)
+                    for (var item:String in items)
                     {
-                        for (var fn:String in methods)
-                        {
-                            var fnDef:Object = methods[fn];
-                            results.push(new MethodDefinition(fn, fnDef.declaredBy, fnDef));
+                        var itemDef:Object = items[item];
+                        if (isStatic) {
+                            //we are looking for static members only
+                            if ( itemDef.isStatic) results[i++] = new itemClass(item, itemDef);
+                        } else {
+                            //ignore statics here, because this is for instance members:
+                            if (itemDef.isStatic) continue;
+                            //instance member:
+                            var itemClassDef:DefinitionWithMetaData = new itemClass(item, itemDef);
+                            if (resolve) {
+                                //resolve against older versions ("overrides")
+                                var oldIdx:uint = oldNames.indexOf(itemClassDef.name);
+                                if (oldIdx != -1) {
+                                    //we have an override of an ancestor's definition, replace it
+                                    results[oldIdx] = itemClassDef;
+                                    continue;
+                                }
+                            }
+                            //add the new definition item to the collection
+                            results[i++] = itemClassDef;
                         }
                     }
                 }
             }
-            return results;            
+           return results;
+        }
+
+        /**
+         * Used primarily for debugging purposes, this provides a string representation of this
+         * TypeDefinition
+         * @param includeDetail whether to output member definitions and other detailed information
+         * @return a stringified representation of this TypeDefinition
+         */
+        public function toString(includeDetail:Boolean=false):String
+        {
+            var kind:String = this.kind;
+            var s:String =  "Typedefinition: " + qualifiedName + ", kind:"+kind;
+            if (includeDetail)
+            {
+                s += "\n";
+                var meta:Array = metadata;
+                var i:uint;
+                var l:uint = meta.length;
+                if (l) {
+                    s += "\tmetadata:";
+                    for (i=0;i<l;i++) {
+                        s += "\n\t\t" + meta[i].toString().split("\n").join("\n\t\t");
+                    }
+                    s += "\n";
+                }
+
+                var collections:Array;
+                if (kind == "class") {
+                    var constructorDef:MethodDefinition = constructorMethod;
+                    var construct:Array = constructorDef ? [constructorDef] :[];
+                    collections = [ "constructor",      construct,
+                                    "interfaces",       interfaces,
+                                    "baseClasses",      baseClasses,
+                                    "variables",        variables,
+                                    "accessors",        accessors,
+                                    "methods",          methods,
+                                    "static variables", staticVariables,
+                                    "static accessors", staticAccessors,
+                                    "static methods",   staticMethods];
+                } else {
+                    if (kind == "interface") {
+                        collections = [ "interfaces", interfaces,
+                                        "accessors",accessors,
+                                        "methods",methods];
+                    }
+                }
+                if (collections) s += stringifyCollections(collections);
+                else s += "\t{no detail available}"
+            }
+            return s;
+        }
+
+        /**
+         * utility method to create friendly output of collections,
+         * primarily for debugging purposes - used via toString(includeDetail=true)
+         * @param collections array of alternating collection names and collections
+         * @return stringified representation of the collections
+         */
+        protected function stringifyCollections(collections:Array):String
+        {
+            var s:String="";
+            while (collections.length) {
+                var collectionType:String = collections.shift();
+                var collection:Array =collections.shift();
+                s += collectionType+" :";
+                if (!collection || !collection.length) {
+                    s+= "\n\t{none}\n"
+                } else {
+                    s+="\n";
+                    var outData:String = "\t";
+                    var l:uint = collection.length;
+                    while (l) {
+                        l--;
+                        outData += collection.shift().toString();
+                        if (l) outData += "\n";
+                    }
+                    outData = outData.replace(/\n/g,"\n\t") + "\n";
+                    s += outData;
+                }
+            }
+            return s;
         }
-           
     }
 }

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/VariableDefinition.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/VariableDefinition.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/VariableDefinition.as
index 3e87566..c83b02f 100755
--- a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/VariableDefinition.as
+++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/VariableDefinition.as
@@ -20,7 +20,7 @@ package org.apache.flex.reflection
 {
     
     /**
-     *  The description of a Class or Interface
+     *  The description of a Class or Interface variable
      * 
      *  @langversion 3.0
      *  @playerversion Flash 10.2
@@ -29,9 +29,39 @@ package org.apache.flex.reflection
      */
     public class VariableDefinition extends DefinitionWithMetaData
 	{
-        public function VariableDefinition(name:String, rawData:Object = null)
+        public function VariableDefinition(name:String, rawData:Object)
         {
-            super(rawData, name);
+            super(name, rawData);
+        }
+
+        /**
+         * A TypeDefinition representing the type of the variable that
+         * this VariableDefinition represents
+         */
+        public function get type():TypeDefinition {
+            COMPILE::SWF {
+                return TypeDefinition.getDefinition(_rawData.@type);
+            }
+
+            COMPILE::JS {
+                return TypeDefinition.getDefinition(_rawData.type);
+            }
+        }
+        /**
+         * A string representation of this variable definition
+         */
+        public function toString():String {
+            var s:String = "variable: '"+name+"', type:"+type.qualifiedName;
+            var meta:Array = metadata;
+            var i:uint;
+            var l:uint = meta.length;
+            if (l) {
+                s+="\n\tmetadata:";
+                for (i=0;i<l;i++) {
+                    s += "\n\t\t" + meta[i].toString().split("\n").join("\n\t\t");
+                }
+            }
+            return s;
         }
         
     }

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/describeType.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/describeType.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/describeType.as
index 89b1821..ceb4963 100755
--- a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/describeType.as
+++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/describeType.as
@@ -35,13 +35,21 @@ COMPILE::SWF
 	{
         COMPILE::SWF
         {
+
+            var untyped:* = value;
+            if (value !== null && untyped !== undefined) {
+                //normalize the query object to the static Class or interface level
+                while (value['constructor'] !== Class) {
+                    value = value['constructor'];
+                }
+            }
             var xml:XML = flash.utils.describeType(value);
-            return new TypeDefinition(xml.@name, xml);
+            return TypeDefinition.getDefinition(xml.@name, xml);
         }
         COMPILE::JS
         {
             var qname:String = getQualifiedClassName(value);
-            return new TypeDefinition(qname, value.FLEXJS_CLASS_INFO);
+            return TypeDefinition.getDefinition(qname, value.FLEXJS_CLASS_INFO || value.prototype.FLEXJS_CLASS_INFO);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/getAliasByClass.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/getAliasByClass.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/getAliasByClass.as
new file mode 100644
index 0000000..aebb4c6
--- /dev/null
+++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/getAliasByClass.as
@@ -0,0 +1,47 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 org.apache.flex.reflection {
+
+
+COMPILE::SWF {
+    import flash.utils.describeType;
+}
+/**
+     * Retrieves a an alias for a class, based on an alias mapping, previously registered with
+     * registerClassAlias, or possibly using [RemoteClass(alias='someAlias')] metadata
+     *
+     * @param classObject the class to retrieve the alias for
+     * @return the most recently mapped alias, if found otherwise "" (empty string)
+     */
+    public function getAliasByClass(classObject:Class):String {
+        var ret:String;
+        if (classObject == null) throw new TypeError("Parameter classObject must be non-null.");
+        COMPILE::SWF {
+            ret= flash.utils.describeType(classObject).@alias;
+        }
+
+        COMPILE::JS {
+            var info:* = classObject.FLEXJS_CLASS_INFO;
+            if (info) {
+                ret = info.alias || "";
+            } else ret="";
+        }
+        return ret;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/getClassByAlias.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/getClassByAlias.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/getClassByAlias.as
new file mode 100644
index 0000000..e59a61b
--- /dev/null
+++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/getClassByAlias.as
@@ -0,0 +1,43 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 org.apache.flex.reflection {
+COMPILE::SWF {
+    import flash.net.getClassByAlias;
+}
+/**
+     * Retrieves a class based on an alias mapping, previously registered with
+     * registerClassAlias, or possibly using [RemoteClass(alias='someAlias')] metadata
+     *
+     * @param aliasName the alias name to use to look up the class definition
+     * @return the class definition that has been mapped to by the registered
+     *         alias, or null if no alias mapping exists.
+     */
+    public function getClassByAlias(aliasName:String):Class {
+        COMPILE::SWF {
+            return flash.net.getClassByAlias(aliasName);
+        }
+
+        COMPILE::JS {
+            if (aliasName == null) throw new TypeError("Parameter aliasName must be non-null.");
+            var klazz:Class = TypeDefinition.getClassByAlias(aliasName);
+            if (!klazz) throw new ReferenceError("Class "+aliasName+" could not be found.");
+            return klazz;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/registerClassAlias.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/registerClassAlias.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/registerClassAlias.as
new file mode 100644
index 0000000..c06bd42
--- /dev/null
+++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/registerClassAlias.as
@@ -0,0 +1,44 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 org.apache.flex.reflection {
+COMPILE::SWF {
+    import flash.net.registerClassAlias;
+}
+    /**
+     * Sets up an alias mapping for serialization/deserialization purposes
+     * This can be auto-generated by the FlexJS compiler
+     * when using class level metadata e.g. [RemoteClass(alias='someAlias')]
+     *
+     * @param aliasName the alias name to use to look up the class definition
+     * @param classObject the class to map to the alias name
+     *
+     */
+    public function registerClassAlias(aliasName:String, classObject:Class):void {
+        COMPILE::SWF {
+
+            flash.net.registerClassAlias(aliasName,classObject);
+        }
+
+        COMPILE::JS {
+            if (classObject == null) throw new TypeError("Parameter classObject must be non-null.");
+            if (aliasName == null) throw new TypeError("Parameter aliasName must be non-null.");
+            TypeDefinition.registerClassAlias(aliasName , classObject);
+        }
+    }
+}