FELIX-924 configuration policy configurable
FELIX-925 activate and deactivate method names are configurable
FELIX-929 name attributes of component and reference elements are optional
FELIX-930 Add support for DS 1.1 XML schema and namespace

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@784693 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/ComponentMetadata.java b/scr/src/main/java/org/apache/felix/scr/impl/ComponentMetadata.java
index ee27ab5..837be55 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/ComponentMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/ComponentMetadata.java
@@ -1,4 +1,4 @@
-/* 
+/*
  * 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
@@ -25,6 +25,8 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
 
 import org.osgi.service.component.ComponentException;
 import org.osgi.service.log.LogService;
@@ -34,6 +36,22 @@
  * This class holds the information associated to a component in the descriptor *  */
 public class ComponentMetadata
 {
+    // Configuration required for component activation (since DS 1.1)
+    public static final String CONFIGURATION_POLICY_REQUIRE = "require";
+
+    // Configuration not provided to component (since DS 1.1)
+    public static final String CONFIGURATION_POLICY_IGNORE = "ignore";
+
+    // Configuration optional (default) (since DS 1.1)
+    public static final String CONFIGURATION_POLICY_OPTIONAL = "optional";
+
+    // set of valid configuration policy settings
+    private static final Set CONFIGURATION_POLICY_VALID;
+
+    // the namespace code of the namespace declaring this component, this is
+    // one of the XmlHandler.DS_VERSION_* constants
+    private final int m_namespaceCode;
+
     // 112.4.3: A Globally unique component name (required)
     private String m_name;
 
@@ -43,7 +61,7 @@
     // 112.4.3: Factory identified. If set to a non empty string, it indicates that the component is a factory component (optional).
     private String m_factory = null;
 
-    // 112.4.3: Controls whether component configurations must be immediately activated after becoming 
+    // 112.4.3: Controls whether component configurations must be immediately activated after becoming
     // satisfied or whether activation should be delayed. (optional, default value depends
     // on whether the component has a service element or not).
     private Boolean m_immediate = null;
@@ -51,6 +69,15 @@
     // 112.4.4 Implementation Element (required)
     private String m_implementationClassName = null;
 
+    // 112.5.8 activate can be specified (since DS 1.1)
+    private String m_activate = null;
+
+    // 112.5.12 deactivate can be specified (since DS 1.1)
+    private String m_deactivate = null;
+
+    // 112.4.3 configuration-policy (since DS 1.1)
+    private String m_configurationPolicy = null;
+
     // Associated properties (0..*)
     private Dictionary m_properties = new Hashtable();
 
@@ -69,11 +96,25 @@
     // Flag that is set once the component is verified (its properties cannot be changed)
     private boolean m_validated = false;
 
+    static
+    {
+        CONFIGURATION_POLICY_VALID = new TreeSet();
+        CONFIGURATION_POLICY_VALID.add( CONFIGURATION_POLICY_IGNORE );
+        CONFIGURATION_POLICY_VALID.add( CONFIGURATION_POLICY_OPTIONAL );
+        CONFIGURATION_POLICY_VALID.add( CONFIGURATION_POLICY_REQUIRE );
+    }
+
+
+    public ComponentMetadata( int namespaceCode )
+    {
+        this.m_namespaceCode = namespaceCode;
+    }
+
     /////////////////////////////////////////// SETTERS //////////////////////////////////////
 
     /**
      * Setter for the name
-     * 
+     *
      * @param name
      */
     public void setName( String name )
@@ -88,7 +129,7 @@
 
     /**
      * Setter for the enabled property
-     * 
+     *
      * @param enabled
      */
     public void setEnabled( boolean enabled )
@@ -102,7 +143,7 @@
 
 
     /**
-     * 
+     *
      * @param factoryIdentifier
      */
     public void setFactoryIdentifier( String factoryIdentifier )
@@ -117,7 +158,7 @@
 
     /**
      * Setter for the immediate property
-     * 
+     *
      * @param immediate
      */
     public void setImmediate( boolean immediate )
@@ -132,7 +173,7 @@
 
     /**
      * Sets the name of the implementation class
-     * 
+     *
      * @param implementationClassName a class name
      */
     public void setImplementationClassName( String implementationClassName )
@@ -146,6 +187,54 @@
 
 
     /**
+     * Sets the configuration policy
+     *
+     * @param configurationPolicy configuration policy
+     * @since 1.2.0 (DS 1.1)
+     */
+    public void setConfigurationPolicy( String configurationPolicy )
+    {
+        if ( m_validated )
+        {
+            return;
+        }
+        m_configurationPolicy = configurationPolicy;
+    }
+
+
+    /**
+     * Sets the name of the activate method
+     *
+     * @param activate a method name
+     * @since 1.2.0 (DS 1.1)
+     */
+    public void setActivate( String activate )
+    {
+        if ( m_validated )
+        {
+            return;
+        }
+        m_activate = activate;
+    }
+
+
+    /**
+     * Sets the name of the deactivate method
+     *
+     * @param deactivate a method name
+     * @since 1.2.0 (DS 1.1)
+     */
+    public void setDeactivate( String deactivate )
+    {
+        if ( m_validated )
+        {
+            return;
+        }
+        m_deactivate = deactivate;
+    }
+
+
+    /**
      * Used to add a property to the instance
      *
      * @param newProperty a property metadata object
@@ -201,9 +290,20 @@
     /////////////////////////////////////////// GETTERS //////////////////////////////////////
 
     /**
+     * Returns the namespace code of the namespace of the component element
+     * declaring this component. This is one of the XmlHandler.DS_VERSION_*
+     * constants.
+     */
+    public int getNamespaceCode()
+    {
+        return m_namespaceCode;
+    }
+
+
+    /**
      * Returns the name of the component
-     * 
-     * @return A string containing the name of the component 
+     *
+     * @return A string containing the name of the component
      */
     public String getName()
     {
@@ -212,8 +312,8 @@
 
 
     /**
-     * Returns the value of the enabled flag 
-     * 
+     * Returns the value of the enabled flag
+     *
      * @return a boolean containing the value of the enabled flag
      */
     public boolean isEnabled()
@@ -224,7 +324,7 @@
 
     /**
      * Returns the factory identifier
-     * 
+     *
      * @return A string containing a factory identifier or null
      */
     public String getFactoryIdentifier()
@@ -242,7 +342,7 @@
      * element or the factory attribute is set or true otherwise. This latter
      * default value deduction may be unsafe while the descriptor has not been
      * completely read.
-     * 
+     *
      * @return a boolean that defines the activation policy
      */
     public boolean isImmediate()
@@ -253,7 +353,7 @@
             return m_immediate.booleanValue();
         }
 
-        // deduce default from service element and factory attribute presence 
+        // deduce default from service element and factory attribute presence
         return m_service == null && m_factory == null;
     }
 
@@ -270,8 +370,44 @@
 
 
     /**
+     * Returns the configuration Policy
+     *
+     * @return the configuration policy
+     * @since 1.2.0 (DS 1.1)
+     */
+    public String getConfigurationPolicy()
+    {
+        return m_configurationPolicy;
+    }
+
+
+    /**
+     * Returns the name of the activate method
+     *
+     * @return the name of the activate method
+     * @since 1.2.0 (DS 1.1)
+     */
+    public String getActivate()
+    {
+        return m_activate;
+    }
+
+
+    /**
+     * Returns the name of the deactivate method
+     *
+     * @return the name of the deactivate method
+     * @since 1.2.0 (DS 1.1)
+     */
+    public String getDeactivate()
+    {
+        return m_deactivate;
+    }
+
+
+    /**
      * Returns the associated ServiceMetadata
-     * 
+     *
      * @return a ServiceMetadata object or null if the Component does not provide any service
      */
     public ServiceMetadata getServiceMetadata()
@@ -292,6 +428,18 @@
 
 
     /**
+     * Returns the list of property meta data.
+     * <b>Note: This method is intended for unit testing only</b>
+     *
+     * @return the list of property meta data.
+     */
+    List getPropertyMetaData()
+    {
+        return m_propertyMetaData;
+    }
+
+
+    /**
      * Returns the dependency descriptors
      *
      * @return a Collection of dependency descriptors
@@ -327,7 +475,12 @@
         // 112.10 The name of the component is required
         if ( m_name == null )
         {
-            throw new ComponentException( "The component name has not been set" );
+            // 112.4.3 name is optional defaulting to implementation class name since DS 1.1
+            if ( m_namespaceCode < XmlHandler.DS_VERSION_1_1 )
+            {
+                throw new ComponentException( "The component name has not been set" );
+            }
+            setName( getImplementationClassName() );
         }
 
         // 112.10 There must be one implementation element and the class atribute is required
@@ -336,6 +489,49 @@
             throw validationFailure( "Implementation class name missing" );
         }
 
+        // 112.4.3 configuration-policy (since DS 1.1)
+        if ( m_configurationPolicy == null )
+        {
+            // default if not specified or pre DS 1.1
+            m_configurationPolicy = CONFIGURATION_POLICY_OPTIONAL;
+        }
+        else if ( m_namespaceCode < XmlHandler.DS_VERSION_1_1 )
+        {
+            logger.log( LogService.LOG_WARNING, "Ignoring configuration policy, DS 1.1 or later namespace required",
+                this, null );
+            m_configurationPolicy = CONFIGURATION_POLICY_OPTIONAL;
+        }
+        else if ( !CONFIGURATION_POLICY_VALID.contains( m_configurationPolicy ) )
+        {
+            throw validationFailure( "Configuration policy must be one of " + CONFIGURATION_POLICY_VALID );
+        }
+
+        // 112.5.8 activate can be specified (since DS 1.1)
+        if ( m_activate == null )
+        {
+            // default if not specified or pre DS 1.1
+            m_activate = "activate";
+        }
+        else if ( m_namespaceCode < XmlHandler.DS_VERSION_1_1 )
+        {
+            logger.log( LogService.LOG_WARNING,
+                "Ignoring activate method declaration, DS 1.1 or later namespace required", this, null );
+            m_activate = "activate";
+        }
+
+        // 112.5.12 deactivate can be specified (since DS 1.1)
+        if ( m_deactivate == null )
+        {
+            // default if not specified or pre DS 1.1
+            m_deactivate = "deactivate";
+        }
+        else if ( m_namespaceCode < XmlHandler.DS_VERSION_1_1 )
+        {
+            logger.log( LogService.LOG_WARNING,
+                "Ignoring deactivate method declaration, DS 1.1 or later namespace required", this, null );
+            m_deactivate = "deactivate";
+        }
+
         // Next check if the properties are valid (and extract property values)
         Iterator propertyIterator = m_propertyMetaData.iterator();
         while ( propertyIterator.hasNext() )
@@ -391,7 +587,7 @@
             }
         }
 
-        // 112.4.6 The serviceFactory attribute (of a provided service) must not be true if 
+        // 112.4.6 The serviceFactory attribute (of a provided service) must not be true if
         // the component is a factory component or an immediate component
         if ( m_service != null )
         {
@@ -409,7 +605,7 @@
     /**
      * Returns a <code>ComponentException</code> for this compeonent with the
      * given explanation for failure.
-     * 
+     *
      * @param reason The explanation for failing to validate this component.
      */
     ComponentException validationFailure( String reason )
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/ReferenceMetadata.java b/scr/src/main/java/org/apache/felix/scr/impl/ReferenceMetadata.java
index 402528f..2e158a2 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/ReferenceMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/ReferenceMetadata.java
@@ -18,12 +18,39 @@
  */
 package org.apache.felix.scr.impl;
 
+import java.util.Set;
+import java.util.TreeSet;
+
 /**
  * Information associated to a dependency
  *
  */
 public class ReferenceMetadata
 {
+    // constant for option single reference - 0..1
+    public static final String CARDINALITY_0_1 = "0..1";
+
+    // constant for option multiple reference - 0..n
+    public static final String CARDINALITY_0_N = "0..n";
+
+    // constant for required single reference - 1..1
+    public static final String CARDINALITY_1_1 = "1..1";
+
+    // constant for required multiple reference - 1..n
+    public static final String CARDINALITY_1_N = "1..n";
+
+    // set of valid cardinality settings
+    private static final Set CARDINALITY_VALID;
+
+    // constant for static policy
+    public static final String POLICY_STATIC = "static";
+
+    // constant for dynamic policy
+    public static final String POLICY_DYNAMIC = "dynamic";
+
+    // set of valid policy settings
+    private static final Set POLICY_VALID;
+
     // Name for the reference (required)
     private String m_name = null;
 
@@ -31,7 +58,7 @@
     private String m_interface = null;
 
     // Cardinality (optional, default="1..1")
-    private String m_cardinality = "1..1";
+    private String m_cardinality = null;
 
     // Target (optional)
     private String m_target;
@@ -43,7 +70,7 @@
     private String m_unbind = null;
 
     // Policy attribute (optional, default = static)
-    private String m_policy = "static";
+    private String m_policy = null;
 
     // Flag that is set once the component is verified (its properties cannot be changed)
     private boolean m_validated = false;
@@ -53,6 +80,19 @@
     private boolean m_isOptional = false;
     private boolean m_isMultiple = false;
 
+    static
+    {
+        CARDINALITY_VALID = new TreeSet();
+        CARDINALITY_VALID.add( CARDINALITY_0_1 );
+        CARDINALITY_VALID.add( CARDINALITY_0_N );
+        CARDINALITY_VALID.add( CARDINALITY_1_1 );
+        CARDINALITY_VALID.add( CARDINALITY_1_N );
+
+        POLICY_VALID = new TreeSet();
+        POLICY_VALID.add( POLICY_DYNAMIC );
+        POLICY_VALID.add( POLICY_STATIC );
+    }
+
 
     /////////////////////////////////////////////// setters ///////////////////////////////////
 
@@ -103,20 +143,9 @@
 
         m_cardinality = cardinality;
 
-        if ( !m_cardinality.equals( "0..1" ) && !m_cardinality.equals( "0..n" ) && !m_cardinality.equals( "1..1" )
-            && !m_cardinality.equals( "1..n" ) )
-        {
-            throw new IllegalArgumentException(
-                "Cardinality should take one of the following values: 0..1, 0..n, 1..1, 1..n" );
-        }
-        if ( m_cardinality.equals( "0..1" ) || m_cardinality.equals( "0..n" ) )
-        {
-            m_isOptional = true;
-        }
-        if ( m_cardinality.equals( "0..n" ) || m_cardinality.equals( "1..n" ) )
-        {
-            m_isMultiple = true;
-        }
+        // secondary properties
+        m_isOptional = CARDINALITY_0_1.equals( cardinality ) || CARDINALITY_0_N.equals( cardinality );
+        m_isMultiple = CARDINALITY_0_N.equals( cardinality ) || CARDINALITY_1_N.equals( cardinality );
     }
 
 
@@ -132,16 +161,10 @@
             return;
         }
 
-        if ( !m_policy.equals( "static" ) && !m_policy.equals( "dynamic" ) )
-        {
-            throw new IllegalArgumentException( "Policy must be either 'static' or 'dynamic'" );
-        }
-        if ( policy.equals( "static" ) == false )
-        {
-            m_isStatic = false;
-        }
-
         m_policy = policy;
+        
+        // secondary property
+        m_isStatic = POLICY_STATIC.equals( policy );
     }
 
 
@@ -330,13 +353,37 @@
     {
         if ( m_name == null )
         {
-            throw componentMetadata.validationFailure( "A name must be declared for the reference" );
+            // 112.10 name attribute is optional, defaults to interface since DS 1.1
+            if ( componentMetadata.getNamespaceCode() < XmlHandler.DS_VERSION_1_1 )
+            {
+                throw componentMetadata.validationFailure( "A name must be declared for the reference" );
+            }
+            setName( getInterface() );
         }
 
         if ( m_interface == null )
         {
             throw componentMetadata.validationFailure( "An interface must be declared for the reference" );
         }
+        
+
+        if ( m_cardinality == null )
+        {
+            setCardinality( CARDINALITY_1_1 );
+        }
+        else if ( !CARDINALITY_VALID.contains( m_cardinality ) )
+        {
+            throw componentMetadata.validationFailure( "Cardinality must be one of " + CARDINALITY_VALID );
+        }
+
+        if ( m_policy == null )
+        {
+            setPolicy( POLICY_STATIC );
+        }
+        else if ( !POLICY_VALID.contains( m_policy ) )
+        {
+            throw componentMetadata.validationFailure( "Policy must be one of " + POLICY_VALID );
+        }
     }
 
 }
\ No newline at end of file
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/XmlHandler.java b/scr/src/main/java/org/apache/felix/scr/impl/XmlHandler.java
index b144734..9b537f7 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/XmlHandler.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/XmlHandler.java
@@ -37,8 +37,27 @@
 public class XmlHandler implements KXml2SAXHandler
 {
 
-    public static final String NAMESPACE_URI = "http://www.osgi.org/xmlns/scr/v1.0.0";
+    // Empty Namespace URI maps to DS 1.0
+    public static final String NAMESPACE_URI_EMPTY = "";
 
+    // Namespace URI of DS 1.0
+    public static final String NAMESPACE_URI = "http://www.osgi.org/xmlns/scr/v1.0.0";
+    
+    // Namespace URI of DS 1.1
+    public static final String NAMESPACE_URI_1_1 = "http://www.osgi.org/xmlns/scr/v1.1.0";
+    
+    // namespace code for non-DS namespace
+    public static final int DS_VERSION_NONE = -1;
+    
+    // namespace code for the DS 1.0 specification
+    public static final int DS_VERSION_1_0 = 0;
+    
+    // namespace code for the DS 1.0 specification
+    public static final int DS_VERSION_1_1 = 1;
+
+    // mapping of namespace URI to namespace code
+    private static final Map NAMESPACE_CODE_MAP;
+    
     // the bundle containing the XML resource being parsed
     private final Bundle m_bundle;
 
@@ -66,6 +85,14 @@
     /** Flag for elements inside a component element */
     protected boolean isComponent = false;
 
+    static
+    {
+        NAMESPACE_CODE_MAP = new HashMap();
+        NAMESPACE_CODE_MAP.put( NAMESPACE_URI_EMPTY, new Integer( DS_VERSION_1_0 ) );
+        NAMESPACE_CODE_MAP.put( NAMESPACE_URI, new Integer( DS_VERSION_1_0 ) );
+        NAMESPACE_CODE_MAP.put( NAMESPACE_URI_1_1, new Integer( DS_VERSION_1_1 ) );
+    }
+
 
     // creates an instance with the bundle owning the component descriptor
     // file parsed by this instance
@@ -111,8 +138,10 @@
             uri = NAMESPACE_URI;
         }
 
+        // get the namespace code for the namespace uri
+        Integer namespaceCode = (Integer) NAMESPACE_CODE_MAP.get( uri );
         // from now on uri points to the namespace
-        if ( NAMESPACE_URI.equals( uri ) )
+        if ( namespaceCode != null )
         {
             try
             {
@@ -123,10 +152,13 @@
                     this.isComponent = true;
 
                     // Create a new ComponentMetadata
-                    m_currentComponent = new ComponentMetadata();
+                    m_currentComponent = new ComponentMetadata( namespaceCode.intValue() );
 
-                    // name attribute is mandatory
-                    m_currentComponent.setName( attrib.getProperty( "name" ) );
+                    // name attribute is optional (since DS 1.1)
+                    if ( attrib.getProperty( "name" ) != null )
+                    {
+                        m_currentComponent.setName( attrib.getProperty( "name" ) );
+                    }
 
                     // enabled attribute is optional
                     if ( attrib.getProperty( "enabled" ) != null )
@@ -146,6 +178,24 @@
                         m_currentComponent.setFactoryIdentifier( attrib.getProperty( "factory" ) );
                     }
 
+                    // configuration-policy is optional (since DS 1.1)
+                    if ( attrib.getProperty( "configuration-policy" ) != null )
+                    {
+                        m_currentComponent.setConfigurationPolicy( attrib.getProperty( "configuration-policy" ) );
+                    }
+
+                    // activate attribute is optional (since DS 1.1)
+                    if ( attrib.getProperty( "activate" ) != null )
+                    {
+                        m_currentComponent.setActivate( attrib.getProperty( "activate" ) );
+                    }
+
+                    // deactivate attribute is optional (since DS 1.1)
+                    if ( attrib.getProperty( "deactivate" ) != null )
+                    {
+                        m_currentComponent.setDeactivate( attrib.getProperty( "deactivate" ) );
+                    }
+
                     // Add this component to the list
                     m_components.add( m_currentComponent );
                 }
@@ -210,7 +260,13 @@
                 else if ( localName.equals( "reference" ) )
                 {
                     ReferenceMetadata ref = new ReferenceMetadata();
-                    ref.setName( attrib.getProperty( "name" ) );
+
+                    // name attribute is optional (since DS 1.1)
+                    if ( attrib.getProperty( "name" ) != null )
+                    {
+                        ref.setName( attrib.getProperty( "name" ) );
+                    }
+
                     ref.setInterface( attrib.getProperty( "interface" ) );
 
                     // Cardinality
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/ComponentMetadataTest.java b/scr/src/test/java/org/apache/felix/scr/impl/ComponentMetadataTest.java
index 2e79705..3d2bad8 100644
--- a/scr/src/test/java/org/apache/felix/scr/impl/ComponentMetadataTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/impl/ComponentMetadataTest.java
@@ -27,7 +27,7 @@
 public class ComponentMetadataTest extends TestCase
 {
 
-    private TestLogger logger = new TestLogger();
+    private MockLogger logger = new MockLogger();
 
 
     // test various combinations of component metadata with respect to
@@ -243,27 +243,230 @@
     }
 
 
-    public void testReference()
+    public void test_component_no_name_ds10()
+    {
+        final ComponentMetadata cm1 = createComponentMetadata( Boolean.TRUE, null );
+        cm1.setName( null );
+        try
+        {
+            cm1.validate( logger );
+            fail( "Expected validation failure for DS 1.0 component without name" );
+        }
+        catch ( ComponentException ce )
+        {
+            // expected
+        }
+    }
+
+
+    public void test_component_no_name_ds11()
+    {
+        final ComponentMetadata cm1 = createComponentMetadata11( Boolean.TRUE, null );
+        cm1.setName( null );
+        cm1.validate( logger );
+        assertEquals( "Expected name to equal implementation class name", cm1.getImplementationClassName(), cm1
+            .getName() );
+    }
+
+
+    public void test_component_activate_ds10()
+    {
+        final ComponentMetadata cm1 = createComponentMetadata( Boolean.TRUE, null );
+        cm1.validate( logger );
+        assertEquals( "Activate method name", "activate", cm1.getActivate() );
+
+        final ComponentMetadata cm2 = createComponentMetadata( Boolean.TRUE, null );
+        cm2.setActivate( "someMethod" );
+        cm2.validate( logger );
+        assertEquals( "Activate method name", "activate", cm2.getActivate() );
+    }
+
+
+    public void test_component_activate_ds11()
+    {
+        final ComponentMetadata cm1 = createComponentMetadata11( Boolean.TRUE, null );
+        cm1.validate( logger );
+        assertEquals( "Activate method name", "activate", cm1.getActivate() );
+
+        final ComponentMetadata cm2 = createComponentMetadata11( Boolean.TRUE, null );
+        cm2.setActivate( "someMethod" );
+        cm2.validate( logger );
+        assertEquals( "Activate method name", "someMethod", cm2.getActivate() );
+    }
+
+
+    public void test_component_deactivate_ds10()
+    {
+        final ComponentMetadata cm1 = createComponentMetadata( Boolean.TRUE, null );
+        cm1.validate( logger );
+        assertEquals( "Deactivate method name", "deactivate", cm1.getDeactivate() );
+
+        final ComponentMetadata cm2 = createComponentMetadata( Boolean.TRUE, null );
+        cm2.setActivate( "someMethod" );
+        cm2.validate( logger );
+        assertEquals( "Deactivate method name", "deactivate", cm2.getDeactivate() );
+    }
+
+
+    public void test_component_deactivate_ds11()
+    {
+        final ComponentMetadata cm1 = createComponentMetadata11( Boolean.TRUE, null );
+        cm1.validate( logger );
+        assertEquals( "Deactivate method name", "deactivate", cm1.getDeactivate() );
+
+        final ComponentMetadata cm2 = createComponentMetadata11( Boolean.TRUE, null );
+        cm2.setDeactivate( "someMethod" );
+        cm2.validate( logger );
+        assertEquals( "Deactivate method name", "someMethod", cm2.getDeactivate() );
+    }
+
+
+    public void test_component_configuration_policy_ds10()
+    {
+        final ComponentMetadata cm1 = createComponentMetadata( Boolean.TRUE, null );
+        cm1.validate( logger );
+        assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL, cm1
+            .getConfigurationPolicy() );
+
+        final ComponentMetadata cm2 = createComponentMetadata( Boolean.TRUE, null );
+        cm2.setConfigurationPolicy( ComponentMetadata.CONFIGURATION_POLICY_IGNORE );
+        cm2.validate( logger );
+        assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL, cm2
+            .getConfigurationPolicy() );
+
+        final ComponentMetadata cm3 = createComponentMetadata( Boolean.TRUE, null );
+        cm3.setConfigurationPolicy( ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL );
+        cm3.validate( logger );
+        assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL, cm3
+            .getConfigurationPolicy() );
+
+        final ComponentMetadata cm4 = createComponentMetadata( Boolean.TRUE, null );
+        cm4.setConfigurationPolicy( ComponentMetadata.CONFIGURATION_POLICY_REQUIRE );
+        cm4.validate( logger );
+        assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL, cm4
+            .getConfigurationPolicy() );
+
+        final ComponentMetadata cm5 = createComponentMetadata( Boolean.TRUE, null );
+        cm5.setConfigurationPolicy( "undefined" );
+        cm5.validate( logger );
+        assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL, cm5
+            .getConfigurationPolicy() );
+    }
+
+
+    public void test_component_configuration_policy_ds11()
+    {
+        final ComponentMetadata cm1 = createComponentMetadata11( Boolean.TRUE, null );
+        cm1.validate( logger );
+        assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL, cm1
+            .getConfigurationPolicy() );
+
+        final ComponentMetadata cm2 = createComponentMetadata11( Boolean.TRUE, null );
+        cm2.setConfigurationPolicy( ComponentMetadata.CONFIGURATION_POLICY_IGNORE );
+        cm2.validate( logger );
+        assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_IGNORE, cm2
+            .getConfigurationPolicy() );
+
+        final ComponentMetadata cm3 = createComponentMetadata11( Boolean.TRUE, null );
+        cm3.setConfigurationPolicy( ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL );
+        cm3.validate( logger );
+        assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL, cm3
+            .getConfigurationPolicy() );
+
+        final ComponentMetadata cm4 = createComponentMetadata11( Boolean.TRUE, null );
+        cm4.setConfigurationPolicy( ComponentMetadata.CONFIGURATION_POLICY_REQUIRE );
+        cm4.validate( logger );
+        assertEquals( "Configuration policy", ComponentMetadata.CONFIGURATION_POLICY_REQUIRE, cm4
+            .getConfigurationPolicy() );
+
+        final ComponentMetadata cm5 = createComponentMetadata11( Boolean.TRUE, null );
+        cm5.setConfigurationPolicy( "undefined" );
+        try
+        {
+            cm5.validate( logger );
+            fail( "Expected validation failure due to undefined configuration policy" );
+        }
+        catch ( ComponentException ce )
+        {
+            // expected due to undefned configuration policy
+        }
+    }
+
+
+    public void test_reference_valid()
     {
         // two references, should validate
         final ComponentMetadata cm1 = createComponentMetadata( Boolean.TRUE, null );
         cm1.addDependency( createReferenceMetadata( "name1" ) );
         cm1.addDependency( createReferenceMetadata( "name2" ) );
         cm1.validate( logger );
+    }
 
-        // two references, must warn
+
+    public void test_reference_duplicate_name()
+    {
+        // two references with same name, must warn
         final ComponentMetadata cm2 = createComponentMetadata( Boolean.TRUE, null );
         cm2.addDependency( createReferenceMetadata( "name1" ) );
         cm2.addDependency( createReferenceMetadata( "name1" ) );
         cm2.validate( logger );
-        assertTrue( "Expected warning for duplicate reference name", logger.lastMessage != null
-            && logger.lastMessage.indexOf( "Detected duplicate reference name" ) >= 0 );
+        assertTrue( "Expected warning for duplicate reference name", logger
+            .messageContains( "Detected duplicate reference name" ) );
     }
 
 
+    public void test_reference_no_name_ds10()
+    {
+        // un-named reference, illegal for pre DS 1.1
+        final ComponentMetadata cm3 = createComponentMetadata( Boolean.TRUE, null );
+        cm3.addDependency( createReferenceMetadata( null ) );
+        try
+        {
+            cm3.validate( logger );
+            fail( "Expect validation failure for DS 1.0 reference without name" );
+        }
+        catch ( ComponentException ce )
+        {
+            // expected
+        }
+    }
+
+
+    public void test_reference_no_name_ds11()
+    {
+        // un-named reference, illegal for DS 1.1
+        final ComponentMetadata cm4 = createComponentMetadata11( Boolean.TRUE, null );
+        final ReferenceMetadata rm4 = createReferenceMetadata( null );
+        cm4.addDependency( rm4 );
+        cm4.validate( logger );
+        assertEquals( "Reference name defaults to interface", rm4.getInterface(), rm4.getName() );
+    }
+
+
+    //---------- Helper methods
+
+    // Creates DS 1.0 Component Metadata
     private ComponentMetadata createComponentMetadata( Boolean immediate, String factory )
     {
-        ComponentMetadata meta = new ComponentMetadata();
+        ComponentMetadata meta = new ComponentMetadata( XmlHandler.DS_VERSION_1_0 );
+        meta.setName( "place.holder" );
+        meta.setImplementationClassName( "place.holder.implementation" );
+        if ( immediate != null )
+        {
+            meta.setImmediate( immediate.booleanValue() );
+        }
+        if ( factory != null )
+        {
+            meta.setFactoryIdentifier( factory );
+        }
+        return meta;
+    }
+
+
+    // Creates DS 1.1 Component Metadata
+    private ComponentMetadata createComponentMetadata11( Boolean immediate, String factory )
+    {
+        ComponentMetadata meta = new ComponentMetadata( XmlHandler.DS_VERSION_1_1 );
         meta.setName( "place.holder" );
         meta.setImplementationClassName( "place.holder.implementation" );
         if ( immediate != null )
@@ -297,15 +500,4 @@
         meta.setInterface( "place.holder" );
         return meta;
     }
-
-    private static class TestLogger implements Logger
-    {
-        String lastMessage;
-
-
-        public void log( int level, String message, ComponentMetadata metadata, Throwable ex )
-        {
-            lastMessage = message;
-        }
-    }
 }
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/MockBundle.java b/scr/src/test/java/org/apache/felix/scr/impl/MockBundle.java
new file mode 100644
index 0000000..ddc18eb
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/impl/MockBundle.java
@@ -0,0 +1,166 @@
+/*
+ * 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.felix.scr.impl;
+
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Enumeration;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+
+public class MockBundle implements Bundle
+{
+
+    public Enumeration findEntries( String arg0, String arg1, boolean arg2 )
+    {
+        return null;
+    }
+
+
+    public BundleContext getBundleContext()
+    {
+        return null;
+    }
+
+
+    public long getBundleId()
+    {
+        return 0;
+    }
+
+
+    public URL getEntry( String name )
+    {
+        return getClass().getClassLoader().getResource( name );
+    }
+
+
+    public Enumeration getEntryPaths( String arg0 )
+    {
+        return null;
+    }
+
+
+    public Dictionary getHeaders()
+    {
+        return null;
+    }
+
+
+    public Dictionary getHeaders( String arg0 )
+    {
+        return null;
+    }
+
+
+    public long getLastModified()
+    {
+        return 0;
+    }
+
+
+    public String getLocation()
+    {
+        return "test:mockbundle";
+    }
+
+
+    public ServiceReference[] getRegisteredServices()
+    {
+        return null;
+    }
+
+
+    public URL getResource( String arg0 )
+    {
+        return null;
+    }
+
+
+    public Enumeration getResources( String arg0 )
+    {
+        return null;
+    }
+
+
+    public ServiceReference[] getServicesInUse()
+    {
+        return null;
+    }
+
+
+    public int getState()
+    {
+        return 0;
+    }
+
+
+    public String getSymbolicName()
+    {
+        return null;
+    }
+
+
+    public boolean hasPermission( Object arg0 )
+    {
+        return false;
+    }
+
+
+    public Class loadClass( String arg0 )
+    {
+        return null;
+    }
+
+
+    public void start()
+    {
+
+    }
+
+
+    public void stop()
+    {
+
+    }
+
+
+    public void uninstall()
+    {
+
+    }
+
+
+    public void update()
+    {
+
+    }
+
+
+    public void update( InputStream arg0 )
+    {
+
+    }
+
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/MockLogger.java b/scr/src/test/java/org/apache/felix/scr/impl/MockLogger.java
new file mode 100644
index 0000000..3bf9061
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/impl/MockLogger.java
@@ -0,0 +1,37 @@
+/*
+ * 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.felix.scr.impl;
+
+
+public class MockLogger implements Logger
+{
+    String lastMessage;
+
+
+    public void log( int level, String message, ComponentMetadata metadata, Throwable ex )
+    {
+        lastMessage = message;
+    }
+
+
+    public boolean messageContains( String value )
+    {
+        return lastMessage != null && lastMessage.indexOf( value ) >= 0;
+    }
+}
\ No newline at end of file
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/XmlHandlerTest.java b/scr/src/test/java/org/apache/felix/scr/impl/XmlHandlerTest.java
new file mode 100644
index 0000000..c823a70
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/impl/XmlHandlerTest.java
@@ -0,0 +1,239 @@
+/*
+ * 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.felix.scr.impl;
+
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.felix.scr.impl.parser.KXml2SAXParser;
+import org.osgi.service.component.ComponentException;
+import org.xmlpull.v1.XmlPullParserException;
+
+
+public class XmlHandlerTest extends TestCase
+{
+    private MockLogger logger;
+
+
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+
+        logger = new MockLogger();
+    }
+
+
+    public void test_component_attributes_11() throws Exception
+    {
+        final List metadataList10 = readMetadata( "/components_activate_10.xml" );
+        assertEquals( "Component Descriptors", 1, metadataList10.size() );
+
+        final ComponentMetadata cm10 = ( ComponentMetadata ) metadataList10.get( 0 );
+        cm10.validate( logger );
+        assertEquals( "DS Version 1.0", XmlHandler.DS_VERSION_1_0, cm10.getNamespaceCode() );
+        assertEquals( "Expected Activate Method not set", "activate", cm10.getActivate() );
+        assertEquals( "Expected Deactivate Method not set", "deactivate", cm10.getDeactivate() );
+        assertEquals( "Expected Configuration Policy not set", ComponentMetadata.CONFIGURATION_POLICY_OPTIONAL, cm10
+            .getConfigurationPolicy() );
+
+        final List metadataList11 = readMetadata( "/components_activate_11.xml" );
+        assertEquals( "Component Descriptors", 1, metadataList11.size() );
+        final ComponentMetadata cm11 = ( ComponentMetadata ) metadataList11.get( 0 );
+        cm11.validate( logger );
+        assertEquals( "DS Version 1.1", XmlHandler.DS_VERSION_1_1, cm11.getNamespaceCode() );
+        assertEquals( "Expected Activate Method set", "myactivate", cm11.getActivate() );
+        assertEquals( "Expected Deactivate Method set", "mydeactivate", cm11.getDeactivate() );
+        assertEquals( "Expected Configuration Policy set", ComponentMetadata.CONFIGURATION_POLICY_IGNORE, cm11
+            .getConfigurationPolicy() );
+    }
+
+
+    public void test_component_no_name() throws Exception
+    {
+        final List metadataList10 = readMetadata( "/components_anonymous_10.xml" );
+        assertEquals( "Component Descriptors", 1, metadataList10.size() );
+        final ComponentMetadata cm10 = ( ComponentMetadata ) metadataList10.get( 0 );
+        try
+        {
+            cm10.validate( logger );
+            fail( "Expected validation failure for component without name" );
+        }
+        catch ( ComponentException ce )
+        {
+            // expected !!
+        }
+
+        final List metadataList11 = readMetadata( "/components_anonymous_11.xml" );
+        assertEquals( "Component Descriptors", 1, metadataList11.size() );
+        final ComponentMetadata cm11 = ( ComponentMetadata ) metadataList11.get( 0 );
+        cm11.validate( logger );
+        assertEquals( "Expected name equals class", cm11.getImplementationClassName(), cm11.getName() );
+    }
+
+
+    public void test_reference_no_name() throws Exception
+    {
+        final List metadataList10 = readMetadata( "/components_anonymous_10.xml" );
+        assertEquals( "Component Descriptors", 1, metadataList10.size() );
+        final ComponentMetadata cm10 = ( ComponentMetadata ) metadataList10.get( 0 );
+        try
+        {
+            cm10.validate( logger );
+            fail( "Expected validation failure for component without name" );
+        }
+        catch ( ComponentException ce )
+        {
+            // expected !!
+        }
+
+        final List metadataList11 = readMetadata( "/components_anonymous_11.xml" );
+        assertEquals( "Component Descriptors", 1, metadataList11.size() );
+        final ComponentMetadata cm11 = ( ComponentMetadata ) metadataList11.get( 0 );
+        cm11.validate( logger );
+        assertEquals( "Expected name equals class", cm11.getImplementationClassName(), cm11.getName() );
+    }
+
+
+    public void test_all_elements_10() throws Exception
+    {
+        final List metadataList10 = readMetadata( "/components_all_elements_10.xml" );
+        assertEquals( "Component Descriptors", 1, metadataList10.size() );
+        final ComponentMetadata cm10 = ( ComponentMetadata ) metadataList10.get( 0 );
+
+        // dont validate this, we test the raw reading
+
+        // ds namespace
+        assertEquals( "ds name space", XmlHandler.DS_VERSION_1_0, cm10.getNamespaceCode() );
+
+        // base component attributes
+        assertEquals( "component name", true, cm10.isEnabled() );
+        assertEquals( "component name", "components.all.name", cm10.getName() );
+        assertEquals( "component name", "components.all.factory", cm10.getFactoryIdentifier() );
+        assertEquals( "component name", true, cm10.isFactory() );
+        assertEquals( "component name", true, cm10.isImmediate() );
+
+        // ds 1.1 elements
+        assertEquals( "activate method", "myactivate", cm10.getActivate() );
+        assertEquals( "deactivate method", "mydeactivate", cm10.getDeactivate() );
+        assertEquals( "configuration policy", "ignore", cm10.getConfigurationPolicy() );
+
+        // from the implementation element
+        assertEquals( "component name", "components.all.impl", cm10.getImplementationClassName() );
+
+        // property setting
+        final PropertyMetadata prop = getPropertyMetadata( cm10, "prop" );
+        assertNotNull( "prop exists", prop );
+        assertEquals( "prop type", "Integer", prop.getType() );
+        assertEquals( "prop value", 1234, ( ( Integer ) prop.getValue() ).intValue() );
+
+        final PropertyMetadata file_property = getPropertyMetadata( cm10, "file.property" );
+        assertNotNull( "file.property exists", file_property );
+        assertEquals( "file.property type", "String", file_property.getType() );
+        assertEquals( "file.property value", "Property from File", file_property.getValue() );
+
+        // service setup
+        final ServiceMetadata sm = cm10.getServiceMetadata();
+        assertNotNull( "service", sm );
+        assertEquals( "servicefactory", true, sm.isServiceFactory() );
+        assertEquals( "1 interface", 1, sm.getProvides().length );
+        assertEquals( "service interface", "components.all.service", sm.getProvides()[0] );
+
+        // references - basic
+        final ReferenceMetadata rm = getReference( cm10, "ref.name" );
+        assertNotNull( "refeference ref.name", rm );
+        assertEquals( "ref.name name", "ref.name", rm.getName() );
+        assertEquals( "ref.name interface", "ref.service", rm.getInterface() );
+        assertEquals( "ref.name cardinality", "0..n", rm.getCardinality() );
+        assertEquals( "ref.name policy", "dynamic", rm.getPolicy() );
+        assertEquals( "ref.name target", "ref.target", rm.getTarget() );
+        assertEquals( "ref.name target prop name", "ref.name.target", rm.getTargetPropertyName() );
+        assertEquals( "ref.name bind method", "ref_bind", rm.getBind() );
+        assertEquals( "ref.name undbind method", "ref_unbind", rm.getUnbind() );
+
+        // references - cardinality side properties (isOptional, isMultiple)
+        final ReferenceMetadata rm01 = getReference( cm10, "ref.01" );
+        assertNotNull( "refeference ref.01", rm01 );
+        assertEquals( "ref.01 cardinality", "0..1", rm01.getCardinality() );
+        final ReferenceMetadata rm11 = getReference( cm10, "ref.11" );
+        assertNotNull( "refeference ref.11", rm11 );
+        assertEquals( "ref.11 cardinality", "1..1", rm11.getCardinality() );
+        final ReferenceMetadata rm0n = getReference( cm10, "ref.0n" );
+        assertNotNull( "refeference ref.0n", rm0n );
+        assertEquals( "ref.0n cardinality", "0..n", rm0n.getCardinality() );
+        final ReferenceMetadata rm1n = getReference( cm10, "ref.1n" );
+        assertNotNull( "refeference ref.1n", rm1n );
+        assertEquals( "ref.1n cardinality", "1..n", rm1n.getCardinality() );
+    }
+
+
+    //---------- helper
+
+    private List readMetadata( String filename ) throws IOException, ComponentException, XmlPullParserException,
+        Exception
+    {
+        BufferedReader in = new BufferedReader( new InputStreamReader( getClass().getResourceAsStream( filename ),
+            "UTF-8" ) );
+        final KXml2SAXParser parser = new KXml2SAXParser( in );
+
+        XmlHandler handler = new XmlHandler( new MockBundle(), logger );
+        parser.parseXML( handler );
+
+        return handler.getComponentMetadataList();
+    }
+
+
+    private ReferenceMetadata getReference( final ComponentMetadata cm, final String name )
+    {
+        List rmlist = cm.getDependencies();
+        for ( Iterator rmi = rmlist.iterator(); rmi.hasNext(); )
+        {
+            ReferenceMetadata rm = ( ReferenceMetadata ) rmi.next();
+            if ( name.equals( rm.getName() ) )
+            {
+                return rm;
+            }
+        }
+
+        // none found
+        return null;
+    }
+
+
+    private PropertyMetadata getPropertyMetadata( final ComponentMetadata cm, final String name )
+    {
+        List pmlist = cm.getPropertyMetaData();
+        for ( Iterator pmi = pmlist.iterator(); pmi.hasNext(); )
+        {
+            PropertyMetadata pm = ( PropertyMetadata ) pmi.next();
+            if ( name.equals( pm.getName() ) )
+            {
+                return pm;
+            }
+        }
+
+        // none found
+        return null;
+    }
+}
diff --git a/scr/src/test/resources/components_activate_10.xml b/scr/src/test/resources/components_activate_10.xml
new file mode 100644
index 0000000..2c754b5
--- /dev/null
+++ b/scr/src/test/resources/components_activate_10.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<components>
+    <scr:component name="components.activate.10"
+        activate="myactivate" deactivate="mydeactivate"
+        configuration-policy="ignore" xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
+        <implementation class="components.activate.10" />
+    </scr:component>
+</components>
diff --git a/scr/src/test/resources/components_activate_11.xml b/scr/src/test/resources/components_activate_11.xml
new file mode 100644
index 0000000..b046ea6
--- /dev/null
+++ b/scr/src/test/resources/components_activate_11.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<components>
+    <scr:component name="components.activate.11"
+        activate="myactivate" deactivate="mydeactivate"
+        configuration-policy="ignore" xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+        <implementation class="components.activate.11" />
+    </scr:component>
+</components>
diff --git a/scr/src/test/resources/components_all_elements_10.properties b/scr/src/test/resources/components_all_elements_10.properties
new file mode 100644
index 0000000..da7d322
--- /dev/null
+++ b/scr/src/test/resources/components_all_elements_10.properties
@@ -0,0 +1,20 @@
+# 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.
+#
+# Sample properties file for the metadate load test
+
+file.property = Property from File
\ No newline at end of file
diff --git a/scr/src/test/resources/components_all_elements_10.xml b/scr/src/test/resources/components_all_elements_10.xml
new file mode 100644
index 0000000..0587053
--- /dev/null
+++ b/scr/src/test/resources/components_all_elements_10.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+
+<!-- 
+
+    This file has a component descriptor with values for all elements
+    and attributes defined in the Declarative Services XML Schema for
+    the Declarative Services Specification 1.0.
+    
+    The goal of this file is to test the XML parsing whether all elements
+    are read and stored in the metadata objects and fields. Semantic
+    correctness according to the specificiation is not tested.
+ -->
+
+<components>
+    <!--
+        component element with
+        * DS 1.0 namespace (sets the ds namespace code)
+        * DS 1.0 attributes
+        * DS 1.1 attributes (must be read)
+    -->
+    <scr:component
+        xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0"
+        
+        enabled="true"
+        name="components.all.name"
+        factory="components.all.factory"
+        immediate="true"
+        
+        activate="myactivate"
+        deactivate="mydeactivate"
+        configuration-policy="ignore"
+        >
+
+        <implementation class="components.all.impl" />
+
+        <property
+            name="prop"
+            value="1234"
+            type="Integer"
+        />
+
+        <properties
+            entry="components_all_elements_10.properties"
+        />
+
+        <service
+            servicefactory="true"
+        >
+            <provide
+                interface="components.all.service"
+            />
+        </service>
+
+        <!-- Basic reference testing reading -->
+        <reference
+            name="ref.name"
+            interface="ref.service"
+            cardinality="0..n"
+            policy="dynamic"
+            target="ref.target"
+            bind="ref_bind"
+            unbind="ref_unbind"
+        />
+        
+        <!--
+            references testing the setting of secondary properties
+            isStatic, isMultiple and isOptional
+        -->
+        <reference name="ref.01" cardinality="0..1" />
+        <reference name="ref.11" cardinality="1..1" />
+        <reference name="ref.0n" cardinality="0..n" />
+        <reference name="ref.1n" cardinality="1..n" />
+        <reference name="ref.static" policy="static" />
+        <reference name="ref.dynamic" policy="dynamic" />
+
+    </scr:component>
+</components>
diff --git a/scr/src/test/resources/components_anonymous_10.xml b/scr/src/test/resources/components_anonymous_10.xml
new file mode 100644
index 0000000..0627e5a
--- /dev/null
+++ b/scr/src/test/resources/components_anonymous_10.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
+    <scr:component enabled="true" immediate="true">
+        <implementation class="components.anonymous.10" />
+    </scr:component>
+</components>
diff --git a/scr/src/test/resources/components_anonymous_11.xml b/scr/src/test/resources/components_anonymous_11.xml
new file mode 100644
index 0000000..5254df9
--- /dev/null
+++ b/scr/src/test/resources/components_anonymous_11.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+    <scr:component enabled="true" immediate="true">
+        <implementation class="components.anonymous.11" />
+    </scr:component>
+</components>
diff --git a/scr/src/test/resources/reference_anonymous_10.xml b/scr/src/test/resources/reference_anonymous_10.xml
new file mode 100644
index 0000000..c1d68ea
--- /dev/null
+++ b/scr/src/test/resources/reference_anonymous_10.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
+    <scr:component enabled="true" immediate="true"
+        name="reference.anonymous.10">
+        <implementation class="reference.anonymous.10" />
+        <reference interface="ref.anon" />
+    </scr:component>
+</components>
diff --git a/scr/src/test/resources/reference_anonymous_11.xml b/scr/src/test/resources/reference_anonymous_11.xml
new file mode 100644
index 0000000..11a5bf4
--- /dev/null
+++ b/scr/src/test/resources/reference_anonymous_11.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+    <scr:component enabled="true" immediate="true"
+        name="reference.anonymous.10">
+        <implementation class="reference.anonymous.10" />
+        <reference interface="ref.anon" />
+    </scr:component>
+</components>