diff --git a/test20/src/main/java/org/apache/myfaces/test/mock/MockApplication20.java b/test20/src/main/java/org/apache/myfaces/test/mock/MockApplication20.java
index e3fe3f8..c2e1417 100644
--- a/test20/src/main/java/org/apache/myfaces/test/mock/MockApplication20.java
+++ b/test20/src/main/java/org/apache/myfaces/test/mock/MockApplication20.java
@@ -17,21 +17,11 @@
 
 package org.apache.myfaces.test.mock;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.myfaces.test.mock.resource.MockResourceHandler;
-
-import javax.faces.FacesException;
-import javax.faces.application.ProjectStage;
-import javax.faces.application.ResourceHandler;
-import javax.faces.component.UIViewRoot;
-import javax.faces.component.behavior.Behavior;
-import javax.faces.context.FacesContext;
-import javax.faces.event.AbortProcessingException;
-import javax.faces.event.SystemEvent;
-import javax.faces.event.SystemEventListener;
-import javax.faces.event.SystemEventListenerHolder;
+import java.beans.BeanDescriptor;
+import java.beans.BeanInfo;
 import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -40,6 +30,38 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 
+import javax.el.ELContext;
+import javax.el.ValueExpression;
+import javax.faces.FacesException;
+import javax.faces.application.Application;
+import javax.faces.application.ProjectStage;
+import javax.faces.application.Resource;
+import javax.faces.application.ResourceDependencies;
+import javax.faces.application.ResourceDependency;
+import javax.faces.application.ResourceHandler;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UINamingContainer;
+import javax.faces.component.UIOutput;
+import javax.faces.component.UIViewRoot;
+import javax.faces.component.behavior.Behavior;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+import javax.faces.el.ValueBinding;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.ComponentSystemEventListener;
+import javax.faces.event.ListenerFor;
+import javax.faces.event.ListenersFor;
+import javax.faces.event.SystemEvent;
+import javax.faces.event.SystemEventListener;
+import javax.faces.event.SystemEventListenerHolder;
+import javax.faces.render.Renderer;
+import javax.faces.validator.Validator;
+import javax.faces.view.ViewDeclarationLanguage;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.test.mock.resource.MockResourceHandler;
+
 /**
  * <p>Mock implementation of <code>Application</code> that includes the semantics
  * added by JavaServer Faces 2.0.</p>
@@ -211,6 +233,242 @@
         return Collections.unmodifiableMap(_defaultValidatorsIds);
     }
 
+    private void _handleAnnotations(FacesContext context, Object inspected, UIComponent component)
+    {   
+        // determine the ProjectStage setting via the given FacesContext
+        // note that a local getProjectStage() could cause problems in wrapped environments
+        boolean isProduction = context.isProjectStage(ProjectStage.Production);
+        
+        Class<?> inspectedClass = inspected.getClass();
+        _handleListenerForAnnotations(context, inspected, inspectedClass, component, isProduction);
+
+        _handleResourceDependencyAnnotations(context, inspectedClass, component, isProduction);
+    }
+    
+    private void _handleListenerForAnnotations(FacesContext context, Object inspected, Class<?> inspectedClass, UIComponent component, boolean isProduction)
+    {
+        List<ListenerFor> listenerForList = null;
+        
+        if(listenerForList == null) //not in production or the class hasn't been inspected yet
+        {
+            ListenerFor listener = inspectedClass.getAnnotation(ListenerFor.class);
+            ListenersFor listeners = inspectedClass.getAnnotation(ListenersFor.class);
+            if(listener != null || listeners != null)
+            {
+                //listeners were found using one or both annotations, create and build a new list
+                listenerForList = new ArrayList<ListenerFor>();
+                
+                if(listener != null)
+                    listenerForList.add(listener);
+                
+                if(listeners != null)
+                    listenerForList.addAll(Arrays.asList(listeners.value()));
+            }
+        }        
+ 
+        if (listenerForList != null) //listeners were found through inspection or from cache, handle them
+        {
+            for (ListenerFor listenerFor : listenerForList)
+            {
+                _handleListenerFor(context, inspected, component, listenerFor);
+            }
+        }
+    }
+
+    private void _handleListenerFor(FacesContext context, Object inspected, UIComponent component,
+                                    ListenerFor annotation)
+    {
+        // If this annotation is not present on the class in question, no action must be taken.
+        if (annotation != null)
+        {
+            // Determine the "target" on which to call subscribeToEvent.
+            // If the class to which this annotation is attached implements ComponentSystemEventListener
+            if (inspected instanceof ComponentSystemEventListener)
+            {
+                // If the class to which this annotation is attached is a UIComponent instance, "target" is the
+                // UIComponent instance.
+
+                // If the class to which this annotation is attached is a Renderer instance, "target" is the
+                // UIComponent instance.
+
+                /*
+                 * If "target" is a UIComponent call UIComponent.subscribeToEvent(Class, ComponentSystemEventListener)
+                 * passing the systemEventClass() of the annotation as the first argument and the instance of the class
+                 * to which this annotation is attached (which must implement ComponentSystemEventListener) as the
+                 * second argument.
+                 */
+                component.subscribeToEvent(annotation.systemEventClass(), (ComponentSystemEventListener) inspected);
+            }
+            // If the class to which this annotation is attached implements SystemEventListener and does not implement
+            // ComponentSystemEventListener, "target" is the Application instance.
+            else if (component instanceof SystemEventListener)
+            {
+                // use the Application object from the FacesContext (note that a
+                // direct use of subscribeToEvent() could cause problems if the
+                // Application is wrapped)
+                Application application = context.getApplication();
+                
+                // If "target" is the Application instance, inspect the value of the sourceClass() annotation attribute
+                // value.
+                if (Void.class.equals(annotation.sourceClass()))
+                {
+                    /*
+                     * If the value is Void.class, call Application.subscribeToEvent(Class, SystemEventListener),
+                     * passing the value of systemEventClass() as the first argument and the instance of the class to
+                     * which this annotation is attached (which must implement SystemEventListener) as the second
+                     * argument.
+                     */
+                    application.subscribeToEvent(annotation.systemEventClass(), (SystemEventListener) inspected);
+                }
+                else
+                {
+                    /*
+                     * Otherwise, call Application.subscribeToEvent(Class, Class, SystemEventListener), passing the
+                     * value of systemEventClass() as the first argument, the value of sourceClass() as the second
+                     * argument, and the instance of the class to which this annotation is attached (which must
+                     * implement SystemEventListener) as the third argument.
+                     */
+                    application.subscribeToEvent(annotation.systemEventClass(), annotation.sourceClass(),
+                                     (SystemEventListener) inspected);
+                }
+            }
+
+            /*
+             * If the class to which this annotation is attached implements ComponentSystemEventListener and is neither
+             * an instance of Renderer nor UIComponent, the action taken is unspecified. This case must not trigger any
+             * kind of error.
+             */
+        }
+    }
+
+    private void _handleResourceDependencyAnnotations(FacesContext context, Class<?> inspectedClass, UIComponent component, boolean isProduction)
+    {
+        List<ResourceDependency> dependencyList = null;
+        
+        if(dependencyList == null)  //not in production or the class hasn't been inspected yet
+        {   
+            ResourceDependency dependency = inspectedClass.getAnnotation(ResourceDependency.class);
+            ResourceDependencies dependencies = inspectedClass.getAnnotation(ResourceDependencies.class);
+            if(dependency != null || dependencies != null)
+            {
+                //resource dependencies were found using one or both annotations, create and build a new list
+                dependencyList = new ArrayList<ResourceDependency>();
+                
+                if(dependency != null)
+                    dependencyList.add(dependency);
+                
+                if(dependencies != null)
+                    dependencyList.addAll(Arrays.asList(dependencies.value()));
+            }
+        }        
+ 
+        if (dependencyList != null) //resource dependencies were found through inspection or from cache, handle them
+        {
+            for (ResourceDependency dependency : dependencyList)
+            {
+                _handleResourceDependency(context, component, dependency);
+            }
+        }
+    }
+    
+    private void _handleResourceDependency(FacesContext context, UIComponent component, ResourceDependency annotation)
+    {
+        // If this annotation is not present on the class in question, no action must be taken.
+        if (annotation != null)
+        {
+            // Create a UIOutput instance by passing javax.faces.Output. to
+            // Application.createComponent(java.lang.String).
+            UIOutput output = (UIOutput) createComponent(UIOutput.COMPONENT_TYPE);
+
+            // Get the annotation instance from the class and obtain the values of the name, library, and
+            // target attributes.
+            String name = annotation.name();
+            if (name != null && name.length() > 0)
+            {
+                name = _ELText.parse(getExpressionFactory(), context.getELContext(), name).toString(context.getELContext());
+            }
+
+            // Obtain the renderer-type for the resource name by passing name to
+            // ResourceHandler.getRendererTypeForResourceName(java.lang.String).
+            // (note that we can not use this.getResourceHandler(), because the Application might be wrapped)
+            String rendererType = context.getApplication().getResourceHandler().getRendererTypeForResourceName(name);
+
+            // Call setRendererType on the UIOutput instance, passing the renderer-type.
+            output.setRendererType(rendererType);
+
+            // Obtain the Map of attributes from the UIOutput component by calling UIComponent.getAttributes().
+            Map<String, Object> attributes = output.getAttributes();
+
+            // Store the name into the attributes Map under the key "name".
+            attributes.put("name", name);
+
+            // If library is the empty string, let library be null.
+            String library = annotation.library();
+            if (library != null && library.length() > 0)
+            {
+                library = _ELText.parse(getExpressionFactory(), context.getELContext(), library).toString(context.getELContext());
+                // If library is non-null, store it under the key "library".
+                if ("this".equals(library))
+                {
+                    // Special "this" behavior
+                    Resource resource = (Resource)component.getAttributes().get(Resource.COMPONENT_RESOURCE_KEY);
+                    if (resource != null)
+                    {
+                        attributes.put("library", resource.getLibraryName());
+                    }
+                }
+                else
+                {
+                    attributes.put("library", library);
+                }
+            }
+
+            // If target is the empty string, let target be null.
+            String target = annotation.target();
+            if (target != null && target.length() > 0)
+            {
+                target = _ELText.parse(getExpressionFactory(), context.getELContext(), target).toString(context.getELContext());
+                // If target is non-null, store it under the key "target".
+                attributes.put("target", target);
+                context.getViewRoot().addComponentResource(context, output, target);
+            }
+            else
+            {
+                // Otherwise, if target is null, call UIViewRoot.addComponentResource(javax.faces.context.FacesContext,
+                // javax.faces.component.UIComponent), passing the UIOutput instance as the second argument.
+                context.getViewRoot().addComponentResource(context, output);
+            }
+        }
+    }
+    
+    private void _inspectRenderer(FacesContext context, UIComponent component, String componentType, String rendererType)
+    {
+        /*
+         * The Renderer instance to inspect must be obtained by calling FacesContext.getRenderKit() and calling
+         * RenderKit.getRenderer(java.lang.String, java.lang.String) on the result, passing the argument componentFamily
+         * of the newly created component as the first argument and the argument rendererType as the second argument.
+         */
+        Renderer renderer = context.getRenderKit().getRenderer(component.getFamily(), rendererType);
+        if (renderer == null)
+        {
+            // If no such Renderer can be found, a message must be logged with a helpful error message.
+            log.error("renderer cannot be found for component type " + componentType + " and renderer type "
+                    + rendererType);
+        }
+        else
+        {
+            // Otherwise, UIComponent.setRendererType(java.lang.String) must be called on the newly created
+            // UIComponent instance, passing the argument rendererType as the argument.
+            component.setRendererType(rendererType);
+
+            /*
+             * except the Renderer for the component to be returned must be inspected for the annotations mentioned in
+             * createComponent(ValueExpression, FacesContext, String) as specified in the documentation for that method.
+             */
+            _handleAnnotations(context, renderer, component);
+        }
+    }
+    
     private static SystemEvent _traverseListenerList(
             List<? extends SystemEventListener> listeners,
             Class<? extends SystemEvent> systemEventClass, Object source,
@@ -417,6 +675,7 @@
         try
         {
             final Behavior behavior = (Behavior) behaviorClass.newInstance();
+            _handleAttachedResourceDependencyAnnotations(FacesContext.getCurrentInstance(), behaviorClass);            
             return behavior;
         }
         catch (Exception e)
@@ -512,4 +771,408 @@
             systemListenerEntry.removeListener(listener, sourceClass);
         }
     }
+
+    @Override
+    public UIComponent createComponent(String componentType)
+    {
+        UIComponent component = super.createComponent(componentType);
+        _handleAnnotations(FacesContext.getCurrentInstance(), component, component);
+        return component;
+    }
+    
+    
+    
+    @Override
+    public UIComponent createComponent(ValueBinding componentBinding,
+            FacesContext context, String componentType) throws FacesException
+    {
+        UIComponent component = null;
+        try
+        {
+            component = (UIComponent) componentBinding.getValue(context);
+            if (component == null)
+            {
+                component = createComponent(componentType);
+                componentBinding.setValue(context, component);
+            }
+            else
+            {
+                _handleAnnotations(context, component, component);
+            }
+
+        }
+        catch (Exception e)
+        {
+            throw new FacesException(e);
+        }
+        return component;
+    }
+
+    @Override
+    public UIComponent createComponent(ValueExpression componentExpression,
+                                       FacesContext facesContext, String componentType)
+            throws FacesException, NullPointerException
+    {
+
+        /*
+         * Before the component instance is returned, it must be inspected for the presence of a ListenerFor (or
+         * ListenersFor) or ResourceDependency (or ResourceDependencies) annotation. If any of these annotations are
+         * present, the action listed in ListenerFor or ResourceDependency must be taken on the component, before it is
+         * returned from this method. This variant of createComponent must not inspect the Renderer for the component to
+         * be returned for any of the afore mentioned annotations. Such inspection is the province of
+         */
+
+        checkNull(componentExpression, "componentExpression");
+        checkNull(facesContext, "facesContext");
+        checkNull(componentType, "componentType");
+
+        ELContext elContext = facesContext.getELContext();
+
+        try
+        {
+            Object retVal = componentExpression.getValue(elContext);
+
+            UIComponent createdComponent;
+
+            if (retVal instanceof UIComponent)
+            {
+                createdComponent = (UIComponent) retVal;
+                _handleAnnotations(facesContext, createdComponent, createdComponent);
+            }
+            else
+            {
+                createdComponent = createComponent(componentType);
+                componentExpression.setValue(elContext, createdComponent);
+            }
+
+            return createdComponent;
+        }
+        catch (FacesException e)
+        {
+            throw e;
+        }
+        catch (Exception e)
+        {
+            throw new FacesException(e);
+        }
+    }
+
+    @Override
+    public UIComponent createComponent(ValueExpression componentExpression, FacesContext context, String componentType,
+                                       String rendererType)
+    {
+        // Like createComponent(ValueExpression, FacesContext, String)
+        UIComponent component = createComponent(componentExpression, context, componentType);
+
+        _inspectRenderer(context, component, componentType, rendererType);
+
+        return component;
+    }
+    
+
+    @Override
+    public UIComponent createComponent(FacesContext context, String componentType, String rendererType)
+    {
+        checkNull(context, "context");
+        checkNull(componentType, "componentType");
+
+        // Like createComponent(String)
+        UIComponent component = createComponent(componentType);
+
+        _inspectRenderer(context, component, componentType, rendererType);
+
+        return component;
+    }
+
+    @Override
+    public UIComponent createComponent(FacesContext context, Resource componentResource)
+    {
+        checkNull(context, "context");
+        checkNull(componentResource, "componentResource");
+        
+        UIComponent component = null;
+        Resource resource;
+        String fqcn;
+        Class<? extends UIComponent> componentClass = null;
+
+        /*
+         * Obtain a reference to the ViewDeclarationLanguage for this Application instance by calling
+         * ViewHandler.getViewDeclarationLanguage(javax.faces.context.FacesContext, java.lang.String), passing the
+         * viewId found by calling UIViewRoot.getViewId() on the UIViewRoot in the argument FacesContext.
+         */
+        UIViewRoot view = context.getViewRoot();
+        Application application = context.getApplication();
+        ViewDeclarationLanguage vdl = application.getViewHandler().getViewDeclarationLanguage(context, view.getViewId());
+
+        /*
+         * Obtain a reference to the composite component metadata for this composite component by calling
+         * ViewDeclarationLanguage.getComponentMetadata(javax.faces.context.FacesContext,
+         * javax.faces.application.Resource), passing the facesContext and componentResource arguments to this method.
+         * This version of JSF specification uses JavaBeans as the API to the component metadata.
+         */
+        BeanInfo metadata = vdl.getComponentMetadata(context, componentResource);
+        if (metadata == null)
+        {
+            throw new FacesException("Could not get component metadata for " 
+                    + componentResource.getResourceName()
+                    + ". Did you forget to specify <composite:interface>?");
+        }
+
+        /*
+         * Determine if the component author declared a component-type for this component instance by obtaining the
+         * BeanDescriptor from the component metadata and calling its getValue() method, passing
+         * UIComponent.COMPOSITE_COMPONENT_TYPE_KEY as the argument. If non-null, the result must be a ValueExpression
+         * whose value is the component-type of the UIComponent to be created for this Resource component. Call through
+         * to createComponent(java.lang.String) to create the component.
+         */
+        BeanDescriptor descriptor = metadata.getBeanDescriptor();
+        ValueExpression componentType = (ValueExpression) descriptor.getValue(UIComponent.COMPOSITE_COMPONENT_TYPE_KEY);
+        boolean annotationsApplied = false;
+        if (componentType != null)
+        {
+            component = application.createComponent((String) componentType.getValue(context.getELContext()));
+            annotationsApplied = true;
+        }
+        else
+        {
+            /*
+             * Otherwise, determine if a script based component for this Resource can be found by calling
+             * ViewDeclarationLanguage.getScriptComponentResource(javax.faces.context.FacesContext,
+             * javax.faces.application.Resource). If the result is non-null, and is a script written in one of the
+             * languages listed in JSF 4.3 of the specification prose document, create a UIComponent instance from the
+             * script resource.
+             */
+            resource = vdl.getScriptComponentResource(context, componentResource);
+            if (resource != null)
+            {
+                String name = resource.getResourceName();
+                String className = name.substring(0, name.lastIndexOf('.'));
+                
+                Class clazz;
+                try
+                {
+                    clazz = Class.forName(className);
+                    component = (UIComponent)clazz.newInstance();
+                }
+                catch (Exception e)
+                {
+                    throw new FacesException(e);
+                }
+            }
+            else
+            {
+                /*
+                 * Otherwise, let library-name be the return from calling Resource.getLibraryName() on the argument
+                 * componentResource and resource-name be the return from calling Resource.getResourceName() on the
+                 * argument componentResource. Create a fully qualified Java class name by removing any file extension
+                 * from resource-name and let fqcn be library-name + "." + resource-name. If a class with the name of
+                 * fqcn cannot be found, take no action and continue to the next step. If any of InstantiationException,
+                 * IllegalAccessException, or ClassCastException are thrown, wrap the exception in a FacesException and
+                 * re-throw it. If any other exception is thrown, log the exception and continue to the next step.
+                 */
+
+                String name = componentResource.getResourceName();
+                String className = name.substring(0, name.lastIndexOf('.'));
+                fqcn = componentResource.getLibraryName() + "." + className;
+                
+                try
+                {
+                    componentClass = classForName(fqcn);
+                }
+                catch (ClassNotFoundException e)
+                {
+                }
+
+                if (componentClass != null)
+                {
+                    try
+                    {
+                        component = componentClass.newInstance();
+                    }
+                    catch (InstantiationException e)
+                    {
+                        log.error("Could not instantiate component class name = " + fqcn, e);
+                        throw new FacesException("Could not instantiate component class name = " + fqcn, e);
+                    }
+                    catch (IllegalAccessException e)
+                    {
+                        log.error("Could not instantiate component class name = " + fqcn, e);
+                        throw new FacesException("Could not instantiate component class name = " + fqcn, e);
+                    }
+                    catch (Exception e)
+                    {
+                        log.error("Could not instantiate component class name = " + fqcn, e);
+                    }
+                }
+
+                /*
+                 * If none of the previous steps have yielded a UIComponent instance, call
+                 * createComponent(java.lang.String) passing "javax.faces.NamingContainer" as the argument.
+                 */
+                if (component == null)
+                {
+                    component = application.createComponent(UINamingContainer.COMPONENT_TYPE);
+                    annotationsApplied = true;
+                }
+            }
+        }
+
+        /*
+         * Call UIComponent.setRendererType(java.lang.String) on the UIComponent instance, passing
+         * "javax.faces.Composite" as the argument.
+         */
+        component.setRendererType("javax.faces.Composite");
+
+        /*
+         * Store the argument Resource in the attributes Map of the UIComponent under the key,
+         * Resource.COMPONENT_RESOURCE_KEY.
+         */
+        component.getAttributes().put(Resource.COMPONENT_RESOURCE_KEY, componentResource);
+
+        /*
+         * Store composite component metadata in the attributes Map of the UIComponent under the key,
+         * UIComponent.BEANINFO_KEY.
+         */
+        component.getAttributes().put(UIComponent.BEANINFO_KEY, metadata);
+
+        /*
+         * Before the component instance is returned, it must be inspected for the presence of a ListenerFor annotation.
+         * If this annotation is present, the action listed in ListenerFor must be taken on the component, before it is
+         * returned from this method.
+         */
+        if (!annotationsApplied)
+        {
+            _handleAnnotations(context, component, component);
+        }
+
+        return component;
+    }
+    
+    private static Class classForName(String type)
+        throws ClassNotFoundException
+    {
+        if (type == null) throw new NullPointerException("type");
+        try
+        {
+            // Try WebApp ClassLoader first
+            return Class.forName(type,
+                                 false, // do not initialize for faster startup
+                                 Thread.currentThread().getContextClassLoader());
+        }
+        catch (ClassNotFoundException ignore)
+        {
+            // fallback: Try ClassLoader for ClassUtils (i.e. the myfaces.jar lib)
+            return Class.forName(type,
+                                 false, // do not initialize for faster startup
+                                 MockApplication20.class.getClassLoader());
+        }
+    }
+    
+    private void _handleAttachedResourceDependencyAnnotations(FacesContext context, Object inspected)
+    {
+        if (inspected == null) {
+            return;
+        }
+        
+        ResourceDependency annotation = inspected.getClass().getAnnotation(ResourceDependency.class);
+        
+        if (annotation == null)
+        {
+            // If the ResourceDependency annotation is not present, the argument must be inspected for the presence 
+            // of the ResourceDependencies annotation. 
+            ResourceDependencies dependencies = inspected.getClass().getAnnotation(ResourceDependencies.class);
+            if (dependencies != null)
+            {
+                // If the ResourceDependencies annotation is present, the action described in ResourceDependencies 
+                // must be taken.
+                for (ResourceDependency dependency : dependencies.value())
+                {
+                    _handleAttachedResourceDependency(context, dependency);
+                }
+            }
+        }
+        else
+        {
+            // If the ResourceDependency annotation is present, the action described in ResourceDependency must be 
+            // taken. 
+            _handleAttachedResourceDependency(context, annotation);
+        }
+    }
+    
+    private void _handleAttachedResourceDependency(FacesContext context, ResourceDependency annotation)
+    {
+        // If this annotation is not present on the class in question, no action must be taken. 
+        if (annotation != null)
+        {
+            Application application = context.getApplication();
+            
+            // Create a UIOutput instance by passing javax.faces.Output. to 
+            // Application.createComponent(java.lang.String).
+            UIOutput output = (UIOutput) application.createComponent(UIOutput.COMPONENT_TYPE);
+            
+            // Get the annotation instance from the class and obtain the values of the name, library, and 
+            // target attributes.
+            String name = annotation.name();
+            if (name != null && name.length() > 0)
+            {
+                name = _ELText.parse(getExpressionFactory(), context.getELContext(), name).toString(context.getELContext());
+            }
+            
+            // Obtain the renderer-type for the resource name by passing name to 
+            // ResourceHandler.getRendererTypeForResourceName(java.lang.String).
+            String rendererType = application.getResourceHandler().getRendererTypeForResourceName(name);
+            
+            // Call setRendererType on the UIOutput instance, passing the renderer-type.
+            output.setRendererType(rendererType);
+            
+            // Obtain the Map of attributes from the UIOutput component by calling UIComponent.getAttributes().
+            Map<String, Object> attributes = output.getAttributes();
+            
+            // Store the name into the attributes Map under the key "name".
+            attributes.put("name", name);
+            
+            // If library is the empty string, let library be null.
+            String library = annotation.library();
+            if (library != null && library.length() > 0)
+            {
+                library = _ELText.parse(getExpressionFactory(), context.getELContext(), library).toString(context.getELContext());
+                // If library is non-null, store it under the key "library".
+                attributes.put("library", library);
+            }
+            
+            // If target is the empty string, let target be null.
+            String target = annotation.target();
+            if (target != null && target.length() > 0)
+            {
+                target = _ELText.parse(getExpressionFactory(), context.getELContext(), target).toString(context.getELContext());
+                // If target is non-null, store it under the key "target".
+                attributes.put("target", target);
+                context.getViewRoot().addComponentResource(context, output, target);
+            }
+            else
+            {
+                // Otherwise, if target is null, call UIViewRoot.addComponentResource(javax.faces.context.FacesContext, 
+                // javax.faces.component.UIComponent), passing the UIOutput instance as the second argument.
+                context.getViewRoot().addComponentResource(context, output);
+            }
+        }
+    }
+
+    @Override
+    public Converter createConverter(String converterId)
+    {
+        Converter converter = super.createConverter(converterId);
+        _handleAttachedResourceDependencyAnnotations(FacesContext.getCurrentInstance(), converter);
+        return converter;
+    }
+
+    @Override
+    public Validator createValidator(String validatorId)
+    {
+        Validator validator = super.createValidator(validatorId);
+        _handleAttachedResourceDependencyAnnotations(FacesContext.getCurrentInstance(), validator);
+        return validator;
+    }
+    
+    
 }
diff --git a/test20/src/main/java/org/apache/myfaces/test/mock/_ELText.java b/test20/src/main/java/org/apache/myfaces/test/mock/_ELText.java
new file mode 100644
index 0000000..6371c13
--- /dev/null
+++ b/test20/src/main/java/org/apache/myfaces/test/mock/_ELText.java
@@ -0,0 +1,444 @@
+/*
+ * 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.myfaces.test.mock;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ExpressionFactory;
+import javax.el.ValueExpression;
+import javax.faces.context.ResponseWriter;
+
+/**
+ * Handles parsing EL Strings in accordance with the EL-API Specification. The parser accepts either <code>${..}</code>
+ * or <code>#{..}</code>.
+ * 
+ * @author Jacob Hookom
+ * @version $Id: ELText.java,v 1.8 2008/07/13 19:01:42 rlubke Exp $
+ */
+class _ELText
+{
+
+    private static final class LiteralValueExpression extends ValueExpression
+    {
+
+        /**
+         * 
+         */
+        private static final long serialVersionUID = 1L;
+
+        private final String text;
+
+        public LiteralValueExpression(String text)
+        {
+            this.text = text;
+        }
+
+        public boolean isLiteralText()
+        {
+            return false;
+        }
+
+        public int hashCode()
+        {
+            return 0;
+        }
+
+        public String getExpressionString()
+        {
+            return this.text;
+        }
+
+        public boolean equals(Object obj)
+        {
+            return false;
+        }
+
+        public void setValue(ELContext context, Object value)
+        {
+        }
+
+        public boolean isReadOnly(ELContext context)
+        {
+            return false;
+        }
+
+        public Object getValue(ELContext context)
+        {
+            return null;
+        }
+
+        public Class<?> getType(ELContext context)
+        {
+            return null;
+        }
+
+        public Class<?> getExpectedType()
+        {
+            return null;
+        }
+
+    }
+
+    private static final class ELTextComposite extends _ELText
+    {
+        private final _ELText[] txt;
+
+        public ELTextComposite(_ELText[] txt)
+        {
+            super(null);
+            this.txt = txt;
+        }
+
+        public void write(Writer out, ELContext ctx) throws ELException, IOException
+        {
+            for (int i = 0; i < this.txt.length; i++)
+            {
+                this.txt[i].write(out, ctx);
+            }
+        }
+
+        public void writeText(ResponseWriter out, ELContext ctx) throws ELException, IOException
+        {
+            for (int i = 0; i < this.txt.length; i++)
+            {
+                this.txt[i].writeText(out, ctx);
+            }
+        }
+
+        public String toString(ELContext ctx)
+        {
+            StringBuffer sb = new StringBuffer();
+            for (int i = 0; i < this.txt.length; i++)
+            {
+                sb.append(this.txt[i].toString(ctx));
+            }
+            return sb.toString();
+        }
+
+        /*
+         * public String toString(ELContext ctx) { StringBuffer sb = new StringBuffer(); for (int i = 0; i <
+         * this.txt.length; i++) { sb.append(this.txt[i].toString(ctx)); } return sb.toString(); }
+         */
+
+        public String toString()
+        {
+            StringBuffer sb = new StringBuffer();
+            for (int i = 0; i < this.txt.length; i++)
+            {
+                sb.append(this.txt[i].toString());
+            }
+            return sb.toString();
+        }
+
+        public boolean isLiteral()
+        {
+            return false;
+        }
+
+        public _ELText apply(ExpressionFactory factory, ELContext ctx)
+        {
+            int len = this.txt.length;
+            _ELText[] nt = new _ELText[len];
+            for (int i = 0; i < len; i++)
+            {
+                nt[i] = this.txt[i].apply(factory, ctx);
+            }
+            return new ELTextComposite(nt);
+        }
+    }
+
+    private static final class ELTextVariable extends _ELText
+    {
+        private final ValueExpression ve;
+
+        public ELTextVariable(ValueExpression ve)
+        {
+            super(ve.getExpressionString());
+            this.ve = ve;
+        }
+
+        public boolean isLiteral()
+        {
+            return false;
+        }
+
+        public _ELText apply(ExpressionFactory factory, ELContext ctx)
+        {
+            return new ELTextVariable(factory.createValueExpression(ctx, this.ve.getExpressionString(), String.class));
+        }
+
+        public void write(Writer out, ELContext ctx) throws ELException, IOException
+        {
+            Object v = this.ve.getValue(ctx);
+            if (v != null)
+            {
+                out.write((String) v);
+            }
+        }
+
+        public String toString(ELContext ctx) throws ELException
+        {
+            Object v = this.ve.getValue(ctx);
+            if (v != null)
+            {
+                return v.toString();
+            }
+
+            return null;
+        }
+
+        public void writeText(ResponseWriter out, ELContext ctx) throws ELException, IOException
+        {
+            Object v = this.ve.getValue(ctx);
+            if (v != null)
+            {
+                out.writeText((String) v, null);
+            }
+        }
+    }
+
+    protected final String literal;
+
+    public _ELText(String literal)
+    {
+        this.literal = literal;
+    }
+
+    /**
+     * If it's literal text
+     * 
+     * @return true if the String is literal (doesn't contain <code>#{..}</code> or <code>${..}</code>)
+     */
+    public boolean isLiteral()
+    {
+        return true;
+    }
+
+    /**
+     * Return an instance of <code>this</code> that is applicable given the ELContext and ExpressionFactory state.
+     * 
+     * @param factory
+     *            the ExpressionFactory to use
+     * @param ctx
+     *            the ELContext to use
+     * @return an ELText instance
+     */
+    public _ELText apply(ExpressionFactory factory, ELContext ctx)
+    {
+        return this;
+    }
+
+    /**
+     * Allow this instance to write to the passed Writer, given the ELContext state
+     * 
+     * @param out
+     *            Writer to write to
+     * @param ctx
+     *            current ELContext state
+     * @throws ELException
+     * @throws IOException
+     */
+    public void write(Writer out, ELContext ctx) throws ELException, IOException
+    {
+        out.write(this.literal);
+    }
+
+    public void writeText(ResponseWriter out, ELContext ctx) throws ELException, IOException
+    {
+        out.writeText(this.literal, null);
+    }
+
+    /**
+     * Evaluates the ELText to a String
+     * 
+     * @param ctx
+     *            current ELContext state
+     * @throws ELException
+     * @return the evaluated String
+     */
+    public String toString(ELContext ctx) throws ELException
+    {
+        return this.literal;
+    }
+
+    public String toString()
+    {
+        return this.literal;
+    }
+
+    /**
+     * Parses the passed string to determine if it's literal or not
+     * 
+     * @param in
+     *            input String
+     * @return true if the String is literal (doesn't contain <code>#{..}</code> or <code>${..}</code>)
+     */
+    public static boolean isLiteral(String in)
+    {
+        _ELText txt = parse(in);
+        return txt == null || txt.isLiteral();
+    }
+
+    /**
+     * Factory method for creating an unvalidated ELText instance. NOTE: All expressions in the passed String are
+     * treated as {@link org.apache.myfaces.view.facelets.el.LiteralValueExpression LiteralValueExpressions}.
+     * 
+     * @param in
+     *            String to parse
+     * @return ELText instance that knows if the String was literal or not
+     * @throws javax.el.ELException
+     */
+    public static _ELText parse(String in) throws ELException
+    {
+        return parse(null, null, in);
+    }
+
+    /**
+     * Factory method for creating a validated ELText instance. When an Expression is hit, it will use the
+     * ExpressionFactory to create a ValueExpression instance, resolving any functions at that time. <p/> Variables and
+     * properties will not be evaluated.
+     * 
+     * @param fact
+     *            ExpressionFactory to use
+     * @param ctx
+     *            ELContext to validate against
+     * @param in
+     *            String to parse
+     * @return ELText that can be re-applied later
+     * @throws javax.el.ELException
+     */
+    public static _ELText parse(ExpressionFactory fact, ELContext ctx, String in) throws ELException
+    {
+        char[] ca = in.toCharArray();
+        int i = 0;
+        char c = 0;
+        int len = ca.length;
+        int end = len - 1;
+        boolean esc = false;
+        int vlen = 0;
+
+        StringBuffer buff = new StringBuffer(128);
+        List<_ELText> text = new ArrayList<_ELText>();
+        _ELText t = null;
+        ValueExpression ve = null;
+
+        while (i < len)
+        {
+            c = ca[i];
+            if ('\\' == c)
+            {
+                esc = !esc;
+                if (esc && i < end && (ca[i + 1] == '$' || ca[i + 1] == '#'))
+                {
+                    i++;
+                    continue;
+                }
+            }
+            else if (!esc && ('$' == c || '#' == c))
+            {
+                if (i < end)
+                {
+                    if ('{' == ca[i + 1])
+                    {
+                        if (buff.length() > 0)
+                        {
+                            text.add(new _ELText(buff.toString()));
+                            buff.setLength(0);
+                        }
+                        vlen = findVarLength(ca, i);
+                        if (ctx != null && fact != null)
+                        {
+                            ve = fact.createValueExpression(ctx, new String(ca, i, vlen), String.class);
+                            t = new ELTextVariable(ve);
+                        }
+                        else
+                        {
+                            t = new ELTextVariable(new LiteralValueExpression(new String(ca, i, vlen)));
+                        }
+                        text.add(t);
+                        i += vlen;
+                        continue;
+                    }
+                }
+            }
+            esc = false;
+            buff.append(c);
+            i++;
+        }
+
+        if (buff.length() > 0)
+        {
+            text.add(new _ELText(new String(buff.toString())));
+            buff.setLength(0);
+        }
+
+        if (text.size() == 0)
+        {
+            return null;
+        }
+        else if (text.size() == 1)
+        {
+            return (_ELText) text.get(0);
+        }
+        else
+        {
+            _ELText[] ta = (_ELText[]) text.toArray(new _ELText[text.size()]);
+            return new ELTextComposite(ta);
+        }
+    }
+
+    private static int findVarLength(char[] ca, int s) throws ELException
+    {
+        int i = s;
+        int len = ca.length;
+        char c = 0;
+        int str = 0;
+        while (i < len)
+        {
+            c = ca[i];
+            if ('\\' == c && i < len - 1)
+            {
+                i++;
+            }
+            else if ('\'' == c || '"' == c)
+            {
+                if (str == c)
+                {
+                    str = 0;
+                }
+                else
+                {
+                    str = c;
+                }
+            }
+            else if (str == 0 && ('}' == c))
+            {
+                return i - s + 1;
+            }
+            i++;
+        }
+        throw new ELException("EL Expression Unbalanced: ... " + new String(ca, s, i - s));
+    }
+
+}
