     /**
      *  @private  
      *  Find all matching style declarations for an IAdvancedStyleClient
+     *  component. The result is sorted in terms of specificity, but the
+     *  declaration order is preserved.
+     *
+     *  @param object - an IAdvancedStyleClient instance of the component to
+     *  match.
+     *  @param styleDeclarations - an optional Array of additional
+     *  CSSStyleDeclarations to be included in the sorted matches.
+     *
+     *  @return An Array of matching style declarations sorted by specificity.
+     */
+    public static function getMatchingStyleDeclarations(object:IAdvancedStyleClient,
+            styleDeclarations:Array=null):Array // of CSSStyleDeclaration
+    {
+        if (styleDeclarations == null)
+            styleDeclarations = [];
+
+        // First, look for universal selectors
+        var universalDecls:Object = StyleManager.getStyleDeclarations("*");
+        styleDeclarations = matchStyleDeclarations(universalDecls, object).concat(styleDeclarations);
+
+        // Next, look for type selectors (includes ActionScript supertype matches)
+        // If we also had universal selectors, concatenate them with our type
+        // selectors and then resort by specificity...
+        if (styleDeclarations.length > 0)
+        {
+            styleDeclarations = object.getClassStyleDeclarations().concat(styleDeclarations);
+            styleDeclarations = sortOnSpecificity(styleDeclarations);
+        }
+        else
+        {
+            // Otherwise, we only have type selectors (which are already sorted)
+            styleDeclarations = object.getClassStyleDeclarations();
+        }
+        return styleDeclarations;
+    }
+
+    /**
+     *  @private
+     *  Returns an ordered map of unqualified class names, starting with the
+     *  object's class name and then each super class name until we hit a stop
+     *  class, such as mx.core::UIComponent.
+     */
+    private static function getUnqualifiedTypeHierarchy(object:IStyleClient):OrderedObject
+    {
+        var className:String = getQualifiedClassName(object);
+        var hierarchy:OrderedObject = StyleManager.typeHierarchyCache[className];
+        if (hierarchy == null)
+        {
+            hierarchy = new OrderedObject();
+
+            var myApplicationDomain:ApplicationDomain;
+            var factory:IFlexModuleFactory = ModuleManager.getAssociatedFactory(object);
+            if (factory != null)
+            {
+                myApplicationDomain = ApplicationDomain(factory.info()["currentDomain"]);
+            }
+            else
+            {
+                var myRoot:DisplayObject = SystemManager.getSWFRoot(object);
+                if (!myRoot)
+                    return hierarchy;
+                myApplicationDomain = myRoot.loaderInfo.applicationDomain;
+            }
+
+            StyleManager.typeHierarchyCache[className] = hierarchy;
+            while (!isStopClass(className))
+            {
+                try
+                {
+                    var type:String = NameUtil.getUnqualifiedClassName(className);
+                    hierarchy[type] = true;
+                    className = getQualifiedSuperclassName(
+                        myApplicationDomain.getDefinition(className));
+                }
+                catch(e:ReferenceError)
+                {
+                    className = null;
+                }
+            }
+        }
+        return hierarchy;
+    }
+
+    /**
+     *  @private
+     *  Our style type hierarhcy stops at UIComponent, UITextField or
+     *  GraphicElement, not Object.
+     */  
+    private static function isStopClass(value:String):Boolean
+    {
+        return value == null ||
+               value == "mx.core::UIComponent" ||
+               value == "mx.core::UITextField" ||
+               value == "mx.graphics.graphicsClasses::GraphicElement";
+    }
+
+    /**
+     *  @private  
+     *  Find all matching style declarations for an IAdvancedStyleClient
      *  component. The result is unsorted in terms of specificity, but the
      *  declaration order is preserved.
      *
-     *  @param declarations - an Array of declarations to be searched for
-     *  matches.
+     *  @param declarations - a map of declarations to be searched for matches.
      *  @param object - an instance of the component to match.
      *
      *  @return An unsorted Array of matching style declarations for the given
      *  subject.
      */
-    private static function getMatchingStyleDeclarations(declarations:Object,
+    private static function matchStyleDeclarations(declarations:Object,
             object:IAdvancedStyleClient):Array // of CSSStyleDeclaration
     {
         var matchingDecls:Array = [];

        // because of the considerably more complex selector matches...
        if (StyleManager.hasAdvancedSelectors() && advancedObject != null)
        {
            // Find matching universal selectors
            var decls:Object = StyleManager.getStyleDeclarations("*");
            universalSelectors = getMatchingStyleDeclarations(decls, advancedObject).concat(universalSelectors);

            // If we had universal selectors, concatenate them with our type
            // selectors and resort by specificity...
            if (universalSelectors.length > 0)
            {
                styleDeclarations = advancedObject.getClassStyleDeclarations().concat(universalSelectors);
                styleDeclarations = sortOnSpecificity(styleDeclarations);
            }
            else
            {
                // We only have type selectors
                styleDeclarations = advancedObject.getClassStyleDeclarations();
            }

            n = styleDeclarations != null ? styleDeclarations.length : 0;
            for (i = 0; i < n; i++)
            {
                styleDeclaration = styleDeclarations[i];
                
                inheritChain =
                    styleDeclaration.addStyleToProtoChain(inheritChain, uicObject);
    
                nonInheritChain =
                    styleDeclaration.addStyleToProtoChain(nonInheritChain, uicObject);

                if (styleDeclaration.effects)
                    object.registerEffects(styleDeclaration.effects);
            }
        }
        // Otherwise we use the legacy Flex 3 logic for simple selectors.

                var decls:Object = StyleManager.getStyleDeclarations(type);
                if (decls)
                {
                    var matchingDecls:Array = matchStyleDeclarations(decls, advancedObject);
                    classDecls = classDecls.concat(matchingDecls);
                }
            }
