FELIX-3550 : Reimplement the SCR Generator

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1349773 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scrplugin/generator/DEPENDENCIES b/scrplugin/generator/DEPENDENCIES
index 23a9770..cdfe014 100644
--- a/scrplugin/generator/DEPENDENCIES
+++ b/scrplugin/generator/DEPENDENCIES
@@ -1,5 +1,5 @@
 Apache Felix Descriptor Generator Implementation
-Copyright 2010-2011 The Apache Software Foundation
+Copyright 2010-2012 The Apache Software Foundation
 
 This software was developed at the Apache Software Foundation
 (http://www.apache.org) and may have dependencies on other
@@ -19,10 +19,6 @@
 Copyright (c) 2000-2005 INRIA, France Telecom
 Licensed under the BSD License.
 
-This product uses software developed at
-The Codehaus (http://www.codehaus.org)
-Licensed under the Apache License 2.0.
-
 
 III. License Summary
 - Apache License 2.0
diff --git a/scrplugin/generator/NOTICE b/scrplugin/generator/NOTICE
index 9d3e412..4441938 100644
--- a/scrplugin/generator/NOTICE
+++ b/scrplugin/generator/NOTICE
@@ -1,5 +1,5 @@
 Apache Felix Descriptor Generator Implementation
-Copyright 2010-2011 The Apache Software Foundation
+Copyright 2010-2012 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
diff --git a/scrplugin/generator/pom.xml b/scrplugin/generator/pom.xml
index 45ffdd7..67794f3 100644
--- a/scrplugin/generator/pom.xml
+++ b/scrplugin/generator/pom.xml
@@ -29,7 +29,7 @@
     <groupId>org.apache.felix</groupId>
     <artifactId>org.apache.felix.scr.generator</artifactId>
 
-    <version>1.1.5-SNAPSHOT</version>
+    <version>1.2.0-SNAPSHOT</version>
     <packaging>jar</packaging>
 
     <name>Descriptor Generator Implementation</name>
@@ -45,14 +45,6 @@
     </scm>
 
     <dependencies>
-        <!-- JavaDoc Tags -->
-        <dependency>
-            <groupId>com.thoughtworks.qdox</groupId>
-            <artifactId>qdox</artifactId>
-            <version>1.12</version>
-            <scope>compile</scope>
-        </dependency>
-
         <!-- bind/unbind method generation -->
         <dependency>
             <groupId>asm</groupId>
@@ -60,19 +52,15 @@
             <version>3.1</version>
             <scope>compile</scope>
         </dependency>
-
-        <!-- OSGi APIs (some constant references used only) -->        
         <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.core</artifactId>
-            <version>4.0.0</version>           
-            <scope>provided</scope>
+        	<groupId>org.osgi</groupId>
+        	<artifactId>org.osgi.core</artifactId>
+        	<version>4.2.0</version>
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.compendium</artifactId>
-            <version>4.0.0</version>
-            <scope>provided</scope>
+            <version>4.2.0</version>
         </dependency>
     </dependencies>
     
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/AnnotationProcessor.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/AnnotationProcessor.java
new file mode 100644
index 0000000..376df37
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/AnnotationProcessor.java
@@ -0,0 +1,49 @@
+/*
+ * 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.scrplugin;
+
+import org.apache.felix.scrplugin.description.ClassDescription;
+import org.apache.felix.scrplugin.scanner.ScannedClass;
+
+/**
+ * This service provides a plugin for annotation processing. Custom tags
+ * can be processed.
+ * On a scanned class all available annotation processors are called in
+ * order of their {@link #getRanking()} value (lowest value first).
+ */
+public interface AnnotationProcessor {
+
+    /**
+     * Processes annotations from the provided list and adds objects
+     * to the object model based on the read annotations.
+     * If this service processes an annotation, it should remove this
+     * annotation from the provided list to avoid duplicate processing
+     * by other processors.
+     * @param scannedClass The scanned class.
+     * @param describedClass The descriptions.
+     */
+    void process(final ScannedClass scannedClass,
+            final ClassDescription describedClass)
+    throws SCRDescriptorException, SCRDescriptorFailureException;
+
+    /**
+     * The ranking of this processor.
+     */
+    int getRanking();
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Constants.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Constants.java
deleted file mode 100644
index 5a362e2..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Constants.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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.scrplugin;
-
-import java.io.File;
-
-/**
- * The <code>Constants</code> interface provides use full constants for various
- * values used for processing SCR annotations and JavaDoc tags into SCR
- * descriptors.
- */
-public interface Constants {
-
-    /** Version 1.0 (R4.1) */
-    public static final int VERSION_1_0 = 0;
-
-    /** Version 1.1 (R4.2) */
-    public static final int VERSION_1_1 = 1;
-
-    /** Version 1.1-felix (R4.2 + FELIX-1893) */
-    public static final int VERSION_1_1_FELIX = 2;
-
-    /**
-     * The name of the Bundle manifest header providing the list of service
-     * component descriptor files.
-     */
-    public static final String SERVICE_COMPONENT = "Service-Component";
-
-    public static final String COMPONENT = "scr.component";
-
-    public static final String COMPONENT_NAME = "name";
-
-    public static final String COMPONENT_LABEL = "label";
-
-    public static final String COMPONENT_DESCRIPTION = "description";
-
-    public static final String COMPONENT_ENABLED = "enabled";
-
-    public static final String COMPONENT_FACTORY = "factory";
-
-    public static final String COMPONENT_IMMEDIATE = "immediate";
-
-    public static final String COMPONENT_INHERIT = "inherit";
-
-    public static final String COMPONENT_METATYPE = "metatype";
-
-    public static final String COMPONENT_ABSTRACT = "abstract";
-
-    public static final String COMPONENT_DS = "ds";
-
-    // Force the descriptor version (since 1.4.1)
-    public static final String COMPONENT_DS_SPEC_VERSION = "specVersion";
-
-    // Specification version identifier for SCR 1.0 (R 4.1)
-    public static final String COMPONENT_DS_SPEC_VERSION_10 = "1.0";
-
-    // Specification version identifier for SCR 1.1 (R 4.2)
-    public static final String COMPONENT_DS_SPEC_VERSION_11 = "1.1";
-
-    // Specification version identifier for SCR 1.1-felix (R 4.2+FELIX-1893)
-    public static final String COMPONENT_DS_SPEC_VERSION_11_FELIX = "1.1-felix";
-
-    public static final String COMPONENT_CREATE_PID = "create-pid";
-
-    public static final String COMPONENT_SET_METATYPE_FACTORY_PID = "configurationFactory";
-
-    // The component configuration policy (V1.1)
-    public static final String COMPONENT_CONFIG_POLICY = "policy";
-    public static final String COMPONENT_CONFIG_POLICY_OPTIONAL = "optional";
-    public static final String COMPONENT_CONFIG_POLICY_REQUIRE = "require";
-    public static final String COMPONENT_CONFIG_POLICY_IGNORE = "ignore";
-
-    // The component activate method name (V1.1)
-    public static final String COMPONENT_ACTIVATE = "activate";
-
-    // The component activate method name (V1.1)
-    public static final String COMPONENT_DEACTIVATE = "deactivate";
-
-    // The component modified method name (V1.1)
-    public static final String COMPONENT_MODIFIED = "modified";
-
-    public static final String PROPERTY = "scr.property";
-
-    public static final String PROPERTY_NAME = "name";
-
-    public static final String PROPERTY_NAME_REF = "nameRef";
-
-    public static final String PROPERTY_LABEL = "label";
-
-    public static final String PROPERTY_DESCRIPTION = "description";
-
-    public static final String PROPERTY_VALUE = "value";
-
-    public static final String PROPERTY_MULTIVALUE_PREFIX = "values";
-
-    public static final String PROPERTY_VALUE_REF = "valueRef";
-
-    /** Property for multi value fields using references. */
-    public static final String PROPERTY_MULTIVALUE_REF_PREFIX = "valueRefs";
-
-    // property type
-    public static final String PROPERTY_TYPE = "type";
-    public static final String PROPERTY_TYPE_STRING = "String";
-    public static final String PROPERTY_TYPE_LONG = "Long";
-    public static final String PROPERTY_TYPE_DOUBLE = "Double";
-    public static final String PROPERTY_TYPE_FLOAT = "Float";
-    public static final String PROPERTY_TYPE_INTEGER = "Integer";
-    public static final String PROPERTY_TYPE_BYTE = "Byte";
-    public static final String PROPERTY_TYPE_CHAR = "Char";
-    public static final String PROPERTY_TYPE_CHAR_1_1 = "Character";
-    public static final String PROPERTY_TYPE_BOOLEAN = "Boolean";
-    public static final String PROPERTY_TYPE_SHORT = "Short";
-
-    public static final String PROPERTY_CARDINALITY = "cardinality";
-
-    public static final String PROPERTY_PRIVATE = "private";
-
-    public static final String PROPERTY_OPTIONS = "options";
-
-    public static final String SERVICE = "scr.service";
-
-    public static final String SERVICE_INTERFACE = "interface";
-
-    public static final String SERVICE_FACTORY = "servicefactory";
-
-    public static final String REFERENCE = "scr.reference";
-
-    public static final String REFERENCE_NAME = "name";
-
-    public static final String REFERENCE_NAME_REF = "nameRef";
-
-    public static final String REFERENCE_INTERFACE = "interface";
-
-    public static final String REFERENCE_CARDINALITY = "cardinality";
-
-    public static final String REFERENCE_POLICY = "policy";
-
-    public static final String REFERENCE_TARGET = "target";
-
-    public static final String REFERENCE_BIND = "bind";
-
-    public static final String REFERENCE_UNDBIND = "unbind";
-
-    public static final String REFERENCE_UPDATED = "updated";
-
-    public static final String REFERENCE_CHECKED = "checked";
-
-    /** Lookup strategy for references @since 1.0.9 */
-    public static final String REFERENCE_STRATEGY = "strategy";
-    public static final String REFERENCE_STRATEGY_LOOKUP = "lookup";
-    public static final String REFERENCE_STRATEGY_EVENT = "event";
-
-    public static final String ABSTRACT_DESCRIPTOR_FILENAME = "scrinfo.xml";
-
-    public static final String ABSTRACT_DESCRIPTOR_ARCHIV_PATH = "OSGI-INF/scr-plugin/" + ABSTRACT_DESCRIPTOR_FILENAME;
-
-    public static final String ABSTRACT_DESCRIPTOR_RELATIVE_PATH = ABSTRACT_DESCRIPTOR_ARCHIV_PATH.replace( '/',
-        File.separatorChar );
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/JavaClassDescriptorManager.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/JavaClassDescriptorManager.java
deleted file mode 100644
index 4fd2f48..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/JavaClassDescriptorManager.java
+++ /dev/null
@@ -1,666 +0,0 @@
-/*
- * 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.scrplugin;
-
-
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-
-import org.apache.felix.scrplugin.om.Component;
-import org.apache.felix.scrplugin.om.Components;
-import org.apache.felix.scrplugin.tags.JavaClassDescription;
-import org.apache.felix.scrplugin.tags.JavaTag;
-import org.apache.felix.scrplugin.tags.annotation.AnnotationJavaClassDescription;
-import org.apache.felix.scrplugin.tags.annotation.AnnotationTagProviderManager;
-import org.apache.felix.scrplugin.tags.cl.ClassLoaderJavaClassDescription;
-import org.apache.felix.scrplugin.tags.qdox.QDoxJavaClassDescription;
-import org.apache.felix.scrplugin.xml.ComponentDescriptorIO;
-
-import com.thoughtworks.qdox.JavaDocBuilder;
-import com.thoughtworks.qdox.model.JavaClass;
-import com.thoughtworks.qdox.model.JavaSource;
-
-
-/**
- * The <code>JavaClassDescriptorManager</code> must be implemented to provide
- * access to the java sources to be scanned for descriptor annotations and
- * JavaDoc tags, the descriptors of components from the class path and the
- * location of the generated class files to be able to add the bind and unbind
- * methods.
- */
-public abstract class JavaClassDescriptorManager
-{
-
-    /** The maven log. */
-    protected final Log log;
-
-    /** The classloader used to compile the classes. */
-    private final ClassLoader classloader;
-
-    /** A cache containing the java class descriptions hashed by classname. */
-    private final Map<String, JavaClassDescription> javaClassDescriptions = new HashMap<String, JavaClassDescription>();
-
-    /**
-     * Supports mapping of built-in and custom java anntoations to
-     * {@link JavaTag} implementations.
-     */
-    private final AnnotationTagProviderManager annotationTagProviderManager;
-
-    /** Parse Javadocs? */
-    private final boolean parseJavadocs;
-
-    /** Process Annotations? */
-    private final boolean processAnnotations;
-
-    /** The Java sources gathered by {@link #getSourceDescriptions()} */
-    private JavaSource[] sources;
-
-    /** The component definitions from other bundles hashed by classname. */
-    private Map<String, Component> componentDescriptions;
-
-
-    /**
-     * Construct a new manager.
-     *
-     * @throws SCRDescriptorFailureException
-     */
-    public JavaClassDescriptorManager( final Log log, final ClassLoader classLoader,
-        final String[] annotationTagProviders, final boolean parseJavadocs, final boolean processAnnotations )
-        throws SCRDescriptorFailureException
-    {
-        this.processAnnotations = processAnnotations;
-        this.parseJavadocs = parseJavadocs;
-        this.log = log;
-        this.annotationTagProviderManager = new AnnotationTagProviderManager( annotationTagProviders, classLoader );
-        this.classloader = classLoader;
-    }
-
-
-    /**
-     * Returns the QDox JavaSource instances representing the source files for
-     * which the Declarative Services and Metatype descriptors have to be
-     * generated.
-     *
-     * @throws SCRDescriptorException May be thrown if an error occurrs
-     *             gathering the java sources.
-     */
-    protected JavaSource[] getSources() throws SCRDescriptorException
-    {
-        if ( this.sources == null )
-        {
-            this.log.debug( "Setting up QDox" );
-
-            JavaDocBuilder builder = new JavaDocBuilder();
-            builder.getClassLibrary().addClassLoader( this.getClassLoader() );
-
-            final Iterator<File> i = getSourceFiles();
-            while ( i.hasNext() )
-            {
-                File file = i.next();
-                this.log.debug( "Adding source file " + file );
-                try
-                {
-                    builder.addSource( file );
-                }
-                catch ( IOException e )
-                {
-                    // also FileNotFoundException
-                    throw new SCRDescriptorException( "Unable to add source file", file.toString(), 0, e );
-                }
-            }
-            this.sources = builder.getSources();
-        }
-
-        return this.sources;
-    }
-
-
-    /**
-     * Returns an iterator of paths to directories providing Java source files
-     * to be parsed.
-     * <p>
-     * This method is called by the default {@link #getSources()} implementation
-     * to return the root directories for the Java files to be parsed. This
-     * default implementation returns an empty iterator. Implementations of this
-     * class not overwriting the {@link #getSources()} method should overwrite
-     * this method by providing the concrete source locations.
-     *
-     * @return An iterator of Java source locations.
-     */
-    protected Iterator<File> getSourceFiles()
-    {
-        return Collections.<File> emptyList().iterator();
-    }
-
-
-    /**
-     * Returns a map of component descriptors which may be extended by the java
-     * sources returned by the {@link #getSources()} method.
-     * <p>
-     * This method calls the {@link #getDependencies()} method and checks for
-     * any Service-Component descriptors in the returned files.
-     * <p>
-     * This method may be overwritten by extensions of this class.
-     *
-     * @throws SCRDescriptorException May be thrown if an error occurrs
-     *             gethering the component descriptors.
-     */
-    protected Map<String, Component> getComponentDescriptors() throws SCRDescriptorException
-    {
-        if ( this.componentDescriptions == null )
-        {
-            final List<Component> components = new ArrayList<Component>();
-            final List<File> dependencies = getDependencies();
-            for ( File artifact : dependencies )
-            {
-                this.log.debug( "Trying to get manifest from artifact " + artifact );
-                try
-                {
-                    final Manifest manifest = this.getManifest( artifact );
-                    if ( manifest != null )
-                    {
-                        // read Service-Component entry
-                        if ( manifest.getMainAttributes().getValue( Constants.SERVICE_COMPONENT ) != null )
-                        {
-                            final String serviceComponent = manifest.getMainAttributes().getValue(
-                                Constants.SERVICE_COMPONENT );
-                            this.log
-                                .debug( "Found Service-Component: " + serviceComponent + " in artifact " + artifact );
-                            final StringTokenizer st = new StringTokenizer( serviceComponent, "," );
-                            while ( st.hasMoreTokens() )
-                            {
-                                final String entry = st.nextToken().trim();
-                                if ( entry.length() > 0 )
-                                {
-                                    final Components c = this.readServiceComponentDescriptor( artifact, entry );
-                                    if ( c != null )
-                                    {
-                                        components.addAll( c.getComponents() );
-                                    }
-                                }
-                            }
-                        }
-                        else
-                        {
-                            this.log.debug( "Artifact has no service component entry in manifest " + artifact );
-                        }
-                    }
-                    else
-                    {
-                        this.log.debug( "Unable to get manifest from artifact " + artifact );
-                    }
-                }
-                catch ( IOException ioe )
-                {
-                    throw new SCRDescriptorException( "Unable to get manifest from artifact", artifact.toString(), 0,
-                        ioe );
-                }
-                this.log.debug( "Trying to get scrinfo from artifact " + artifact );
-                // now read the scr private file - components stored there
-                // overwrite components already
-                // read from the service component section.
-                InputStream scrInfoFile = null;
-                try
-                {
-                    scrInfoFile = this.getFile( artifact, Constants.ABSTRACT_DESCRIPTOR_ARCHIV_PATH );
-                    if ( scrInfoFile != null )
-                    {
-                        components.addAll( this.parseServiceComponentDescriptor( scrInfoFile ).getComponents() );
-                    }
-                    else
-                    {
-                        this.log.debug( "Artifact has no scrinfo file (it's optional): " + artifact );
-                    }
-                }
-                catch ( IOException ioe )
-                {
-                    throw new SCRDescriptorException( "Unable to get scrinfo from artifact", artifact.toString(), 0,
-                        ioe );
-                }
-                finally
-                {
-                    if ( scrInfoFile != null )
-                    {
-                        try
-                        {
-                            scrInfoFile.close();
-                        }
-                        catch ( IOException ignore )
-                        {
-                        }
-                    }
-                }
-
-            }
-            // now create map with component descriptions
-            this.componentDescriptions = new HashMap<String, Component>();
-            for ( final Component component : components )
-            {
-                this.componentDescriptions.put( component.getImplementation().getClassame(), component );
-            }
-        }
-
-        return this.componentDescriptions;
-    }
-
-
-    /**
-     * Returns a list of files denoting dependencies of the module for which
-     * descriptors are to be generated. The returned dependencies are expected
-     * to be bundles which may (or may not) contain Service Component
-     * descriptors (or internal descriptors in the case of abstract components
-     * not listed in the "official" descriptors).
-     * <p>
-     * This method is called by the {@link #getComponentDescriptors()} method in
-     * this class to get the list of bundles from where base component
-     * descriptors are to be extracted.
-     * <p>
-     * Extensions of this class not overwriting the
-     * {@link #getComponentDescriptors()} method should overwrite this method if
-     * they wish to provide such base component descriptors.
-     *
-     * @return
-     */
-    protected List<File> getDependencies()
-    {
-        return Collections.<File> emptyList();
-    }
-
-
-    /**
-     * Returns the absolute filesystem path to the directory where the classes
-     * compiled from the java source files (see {@link #getSources()}) have been
-     * placed.
-     * <p>
-     * This method is called to find the class files to which bind and unbind
-     * methods are to be added.
-     */
-    public abstract String getOutputDirectory();
-
-
-    /**
-     * Return the log.
-     */
-    public Log getLog()
-    {
-        return this.log;
-    }
-
-
-    /**
-     * Return the class laoder.
-     */
-    public ClassLoader getClassLoader()
-    {
-        return this.classloader;
-    }
-
-
-    /**
-     * @return Annotation tag provider manager
-     */
-    public AnnotationTagProviderManager getAnnotationTagProviderManager()
-    {
-        return this.annotationTagProviderManager;
-    }
-
-
-    /**
-     * Returns <code>true</code> if this class descriptor manager is parsing
-     * JavaDoc tags.
-     */
-    public boolean isParseJavadocs()
-    {
-        return parseJavadocs;
-    }
-
-
-    /**
-     * Returns <code>true</code> if this class descriptor manager is parsing
-     * Java 5 annotations.
-     */
-    public boolean isProcessAnnotations()
-    {
-        return processAnnotations;
-    }
-
-
-    /**
-     * Parses the descriptors read from the given input stream. This method may
-     * be called by the {@link #getComponentDescriptors()} method to parse the
-     * descriptors gathered in an implementation dependent way.
-     *
-     * @throws SCRDescriptorException If an error occurrs reading the
-     *             descriptors from the stream.
-     */
-    protected Components parseServiceComponentDescriptor( InputStream file ) throws SCRDescriptorException
-    {
-        return ComponentDescriptorIO.read( file );
-    }
-
-
-    /**
-     * Return all source descriptions of this project.
-     *
-     * @return All contained java class descriptions.
-     */
-    public JavaClassDescription[] getSourceDescriptions() throws SCRDescriptorException
-    {
-        final JavaClass[] javaClasses = getJavaClassesFromSources();
-        final JavaClassDescription[] descs = new JavaClassDescription[javaClasses.length];
-        for ( int i = 0; i < javaClasses.length; i++ )
-        {
-            descs[i] = this.getJavaClassDescription( javaClasses[i].getFullyQualifiedName() );
-        }
-        return descs;
-    }
-
-    private boolean doingHasScrPluginAnnotationCheck = false;
-
-    private boolean hasScrPluginAnnotation(final Class<?> clazz, final JavaClass javaClass)
-    {
-        boolean result;
-        doingHasScrPluginAnnotationCheck = true;
-
-        result = getAnnotationTagProviderManager().hasScrPluginAnnotation( javaClass,
-                new AnnotationJavaClassDescription( clazz, javaClass, this ));
-        doingHasScrPluginAnnotationCheck = false;
-        return result;
-    }
-
-    /**
-     * Get a java class description for the class.
-     *
-     * @param className
-     * @return The java class description.
-     * @throws SCRDescriptorException
-     */
-    public JavaClassDescription getJavaClassDescription( String className ) throws SCRDescriptorException
-    {
-        JavaClassDescription result = this.javaClassDescriptions.get( className );
-        if ( result == null )
-        {
-            this.log.debug( "Searching description for: " + className );
-            int index = 0;
-            final JavaClass[] javaClasses = getJavaClassesFromSources();
-            while ( result == null && index < javaClasses.length )
-            {
-                final JavaClass javaClass = javaClasses[index];
-                if ( javaClass.getFullyQualifiedName().equals( className ) )
-                {
-                    try
-                    {
-                        // check for java annotation descriptions - fallback to
-                        // QDox if none found
-                        Class<?> clazz = this.classloader.loadClass( className );
-                        if ( this.processAnnotations && !doingHasScrPluginAnnotationCheck
-                            && hasScrPluginAnnotation(clazz, javaClass) )
-                        {
-                            this.log.debug( "Generating java annotation description for: " + className );
-                            result = new AnnotationJavaClassDescription( clazz, javaClass, this );
-                        }
-                        else if ( this.parseJavadocs )
-                        {
-                            this.log.debug( "Generating qdox description for: " + className );
-                            result = new QDoxJavaClassDescription( clazz, javaClass, this );
-                        }
-                        else
-                        {
-                            index++;
-                        }
-                    }
-                    catch ( ClassNotFoundException e )
-                    {
-                        throw new SCRDescriptorException( "Unable to load class", className, 0 );
-                    }
-                }
-                else
-                {
-                    index++;
-                }
-            }
-            if ( result == null )
-            {
-                try
-                {
-                    this.log.debug( "Generating classloader description for: " + className );
-                    result = new ClassLoaderJavaClassDescription( this.classloader.loadClass( className ), this
-                        .getComponentDescriptors().get( className ), this );
-                }
-                catch ( ClassNotFoundException e )
-                {
-                    throw new SCRDescriptorException( "Unable to load class", className, 0 );
-                }
-            }
-            if ( !doingHasScrPluginAnnotationCheck ) {
-                this.javaClassDescriptions.put( className, result );
-            }
-        }
-        return result;
-    }
-
-
-    /**
-     * Get a list of all {@link JavaClass} definitions four all source files
-     * (including nested/inner classes)
-     *
-     * @return List of {@link JavaClass} definitions
-     */
-    private JavaClass[] getJavaClassesFromSources() throws SCRDescriptorException
-    {
-        final JavaSource[] sources = this.getSources();
-        final List<JavaClass> classes = new ArrayList<JavaClass>();
-        for ( int i = 0; i < sources.length; i++ )
-        {
-            if ( sources[i].getClasses() == null || sources[i].getClasses().length == 0 )
-            {
-                continue;
-            }
-            for ( int j = 0; j < sources[i].getClasses().length; j++ )
-            {
-                final JavaClass clazz = sources[i].getClasses()[j];
-                classes.add( clazz );
-                for ( int k = 0; k < clazz.getNestedClasses().length; k++ )
-                {
-                    final JavaClass nestedClass = clazz.getNestedClasses()[k];
-                    classes.add( nestedClass );
-                }
-            }
-        }
-        return classes.toArray( new JavaClass[classes.size()] );
-    }
-
-
-    /**
-     * Read the service component description.
-     *
-     * @param artifact
-     * @param entry
-     * @throws IOException
-     * @throws SCRDescriptorException
-     */
-    private Components readServiceComponentDescriptor( final File artifactFile, String entry )
-    {
-        this.log.debug( "Reading " + entry + " from " + artifactFile );
-        InputStream xml = null;
-        try
-        {
-            xml = this.getFile( artifactFile, entry );
-            if ( xml == null )
-            {
-                throw new SCRDescriptorException( "Entry " + entry + " not contained in JAR File ", artifactFile.toString(),
-                    0 );
-            }
-            return this.parseServiceComponentDescriptor( xml );
-        }
-        catch ( IOException mee )
-        {
-            this.log.warn( "Unable to read SCR descriptor file from JAR File " + artifactFile + " at " + entry );
-            this.log.debug( "Exception occurred during reading: " + mee.getMessage(), mee );
-        }
-        catch ( SCRDescriptorException mee )
-        {
-            this.log.warn( "Unable to read SCR descriptor file from JAR File " + artifactFile + " at " + entry );
-            this.log.debug( "Exception occurred during reading: " + mee.getMessage(), mee );
-        }
-        finally
-        {
-            if ( xml != null )
-            {
-                try
-                {
-                    xml.close();
-                }
-                catch ( IOException ignore )
-                {
-                }
-            }
-        }
-        return null;
-    }
-
-
-    private Manifest getManifest( File artifact ) throws IOException
-    {
-        if ( artifact.isDirectory() )
-        {
-            // this is maybe a classes directory, try to read manifest file directly
-            final File dir = new File(artifact, "META-INF");
-            if ( !dir.exists() || !dir.isDirectory() )
-            {
-                return null;
-            }
-            final File mf = new File(dir, "MANIFEST.MF");
-            if ( !mf.exists() || !mf.isFile() )
-            {
-                return null;
-            }
-            final InputStream is = new FileInputStream(mf);
-            try
-            {
-                return new Manifest(is);
-            }
-            finally
-            {
-                try
-                {
-                    is.close();
-                }
-                catch (final IOException ignore) { }
-            }
-        }
-        JarFile file = null;
-        try
-        {
-            file = new JarFile( artifact );
-            return file.getManifest();
-        }
-        finally
-        {
-            if ( file != null )
-            {
-                try
-                {
-                    file.close();
-                }
-                catch ( IOException ignore )
-                {
-                }
-            }
-        }
-    }
-
-
-    private InputStream getFile( final File artifactFile, final String path ) throws IOException
-    {
-        if ( artifactFile.isDirectory() )
-        {
-            final String filePath = path.replace('/', File.separatorChar).replace('\\', File.separatorChar);
-            final File file = new File(artifactFile, filePath);
-            if ( file.exists() && file.isFile() )
-            {
-                return new FileInputStream(file);
-            }
-            return null;
-        }
-        JarFile file = null;
-        try
-        {
-            file = new JarFile( artifactFile );
-            final JarEntry entry = file.getJarEntry( path );
-            if ( entry != null )
-            {
-                final InputStream stream = new ArtifactFileInputStream( file, entry );
-                file = null; // prevent file from being closed now
-                return stream;
-            }
-            return null;
-        }
-        finally
-        {
-            if ( file != null )
-            {
-                try
-                {
-                    file.close();
-                }
-                catch ( IOException ignore )
-                {
-                }
-            }
-        }
-    }
-
-    private static class ArtifactFileInputStream extends FilterInputStream
-    {
-        final JarFile jarFile;
-
-
-        ArtifactFileInputStream( JarFile jarFile, JarEntry jarEntry ) throws IOException
-        {
-            super( jarFile.getInputStream( jarEntry ) );
-            this.jarFile = jarFile;
-        }
-
-
-        @Override
-        public void close() throws IOException
-        {
-            try
-            {
-                super.close();
-            }
-            catch ( IOException ioe )
-            {
-            }
-            jarFile.close();
-        }
-
-
-        @Override
-        protected void finalize() throws Throwable
-        {
-            try
-            {
-                close();
-            }
-            finally
-            {
-                super.finalize();
-            }
-        }
-    }
-
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Log.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Log.java
index 46d44ff..ec679cb 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Log.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Log.java
@@ -24,8 +24,8 @@
  * SCR descriptor generation process using whatever means is implemented. There
  * should be no big surprises here.
  */
-public interface Log
-{
+public interface Log {
+
     /**
      * @return true if the <b>debug</b> error level is enabled
      */
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Options.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Options.java
new file mode 100644
index 0000000..bc5e041
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Options.java
@@ -0,0 +1,115 @@
+/*
+ * 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.scrplugin;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.felix.scrplugin.description.SpecVersion;
+
+
+public class Options {
+
+    private boolean generateAccessors = true;
+
+    private boolean strictMode = false;
+
+    private Map<String, String> properties = Collections.emptyMap();
+
+    private SpecVersion specVersion;
+
+    private String[] annotationProcessors;
+
+    public String[] getAnnotationProcessors() {
+        return annotationProcessors;
+    }
+
+    public void setAnnotationProcessors(String[] annotationProcessors) {
+        this.annotationProcessors = annotationProcessors;
+    }
+
+    public boolean isGenerateAccessors() {
+        return generateAccessors;
+    }
+
+    /**
+     * Defines whether bind and unbind methods are automatically created by
+     * the SCR descriptor generator.
+     * <p>
+     * The generator uses the ASM library to create the method byte codes
+     * directly inside the class files. If bind and unbind methods are not
+     * to be created, the generator fails if such methods are missing.
+     * <p>
+     * The default value of this property is <code>true</code>.
+     */
+    public void setGenerateAccessors(boolean generateAccessors) {
+        this.generateAccessors = generateAccessors;
+    }
+
+    public boolean isStrictMode() {
+        return strictMode;
+    }
+
+    /**
+     * Defines whether warnings should be considered as errors and thus cause
+     * the generation process to fail.
+     * <p>
+     * The default value of this property is <code>false</code>.
+     */
+    public void setStrictMode(boolean strictMode) {
+        this.strictMode = strictMode;
+    }
+
+    public Map<String, String> getProperties() {
+        return properties;
+    }
+
+    /**
+     * Sets global properties to be set for each descriptor. If a descriptor
+     * provides properties of the same name, the descriptor properties are preferred
+     * over the properties provided here.
+     * <p>
+     * The are no default global properties.
+     */
+    public void setProperties(Map<String, String> properties) {
+        this.properties = properties;
+    }
+
+    public SpecVersion getSpecVersion() {
+        return specVersion;
+    }
+
+    /**
+     * Sets the Declarative Services specification version number to be forced
+     * on the declarations.
+     * <p>
+     * Supported values for this property are <code>null</code> to autodetect
+     * the specification version, or one of the enum values from
+     * {@link SpecVersion}.
+     * <p>
+     * The default is to generate the descriptor version according to the
+     * capabilities used by the descriptors. If no 1.1 capabilities, such as
+     * <code>configuration-policy</code>, are used, version 1.0 is used,
+     * otherwise a 1.1 descriptor is generated.
+     */
+    public void setSpecVersion(SpecVersion specVersion) {
+        this.specVersion = specVersion;
+    }
+
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Project.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Project.java
new file mode 100644
index 0000000..91e4658
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Project.java
@@ -0,0 +1,67 @@
+/*
+ * 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.scrplugin;
+
+import java.io.File;
+import java.util.Collection;
+
+import org.apache.felix.scrplugin.scanner.Source;
+
+public class Project {
+
+    private Collection<Source> sources;
+
+    private Collection<File> dependencies;
+
+    private ClassLoader classLoader;
+
+    private String classesDirectory;
+
+    public Collection<Source> getSources() {
+        return sources;
+    }
+
+    public void setSources(Collection<Source> sources) {
+        this.sources = sources;
+    }
+
+    public Collection<File> getDependencies() {
+        return dependencies;
+    }
+
+    public void setDependencies(Collection<File> dependencies) {
+        this.dependencies = dependencies;
+    }
+
+    public ClassLoader getClassLoader() {
+        return classLoader;
+    }
+
+    public void setClassLoader(ClassLoader classLoader) {
+        this.classLoader = classLoader;
+    }
+
+    public String getClassesDirectory() {
+        return this.classesDirectory;
+    }
+
+    public void setClassesDirectory(final String dir) {
+        this.classesDirectory = dir;
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Result.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Result.java
new file mode 100644
index 0000000..5ebe459
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Result.java
@@ -0,0 +1,64 @@
+/*
+ * 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.scrplugin;
+
+import java.util.List;
+
+
+/**
+ * The result of the generation.
+ */
+public class Result {
+
+    /** The list of metatype files. */
+    private List<String> metatypeFiles;
+
+    /** The list of scr files. */
+    private List<String> scrFiles;
+
+    /**
+     * Set the list of metatype files
+     */
+    public void setMetatypeFiles(List<String> metatypeFiles) {
+        this.metatypeFiles = metatypeFiles;
+    }
+
+    /**
+     * Set the list of scr files
+     */
+    public void setScrFiles(List<String> scrFiles) {
+        this.scrFiles = scrFiles;
+    }
+
+    /**
+     * Return a list of generated metatype files
+     * @return A list of relative paths or <code>null</code>
+     */
+    public List<String> getMetatypeFiles() {
+        return metatypeFiles;
+    }
+
+    /**
+     * Return a list of generated scr files
+     * @return A list of relative paths or <code>null</code>
+     */
+    public List<String> getScrFiles() {
+        return scrFiles;
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorException.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorException.java
index 0721681..fec894b 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorException.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorException.java
@@ -19,11 +19,7 @@
 package org.apache.felix.scrplugin;
 
 
-import org.apache.felix.scrplugin.tags.JavaTag;
-
-
-public class SCRDescriptorException extends Exception
-{
+public class SCRDescriptorException extends Exception {
 
     private static final long serialVersionUID = 1L;
 
@@ -32,12 +28,6 @@
     private final int m_lineNumber;
 
 
-    public SCRDescriptorException( final String message, final JavaTag tag )
-    {
-        this( message, tag.getSourceLocation(), tag.getLineNumber() );
-    }
-
-
     public SCRDescriptorException( final String message, final String sourceLocation, final int lineNumber )
     {
         super( message );
@@ -46,9 +36,9 @@
     }
 
 
-    public SCRDescriptorException( final String message, final JavaTag tag, final Throwable cause )
+    public SCRDescriptorException( final String message, final Throwable cause )
     {
-        this( message, tag.getSourceLocation(), tag.getLineNumber(), cause );
+        this( message, null, -1, cause );
     }
 
 
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java
index c4db2a5..83d5d45 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java
@@ -18,994 +18,685 @@
  */
 package org.apache.felix.scrplugin;
 
-
 import java.io.File;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
 
-import org.apache.felix.scrplugin.helper.*;
-import org.apache.felix.scrplugin.om.*;
-import org.apache.felix.scrplugin.om.metatype.*;
-import org.apache.felix.scrplugin.tags.*;
-import org.apache.felix.scrplugin.tags.annotation.AnnotationJavaClassDescription;
-import org.apache.felix.scrplugin.tags.qdox.QDoxJavaClassDescription;
+import org.apache.felix.scrplugin.description.ClassDescription;
+import org.apache.felix.scrplugin.description.ComponentDescription;
+import org.apache.felix.scrplugin.description.PropertyDescription;
+import org.apache.felix.scrplugin.description.PropertyType;
+import org.apache.felix.scrplugin.description.PropertyUnbounded;
+import org.apache.felix.scrplugin.description.ReferenceCardinality;
+import org.apache.felix.scrplugin.description.ReferenceDescription;
+import org.apache.felix.scrplugin.description.ServiceDescription;
+import org.apache.felix.scrplugin.description.SpecVersion;
+import org.apache.felix.scrplugin.helper.AnnotationProcessorManager;
+import org.apache.felix.scrplugin.helper.ClassModifier;
+import org.apache.felix.scrplugin.helper.ClassScanner;
+import org.apache.felix.scrplugin.helper.IssueLog;
+import org.apache.felix.scrplugin.helper.StringUtils;
+import org.apache.felix.scrplugin.om.Component;
+import org.apache.felix.scrplugin.om.Components;
+import org.apache.felix.scrplugin.om.Context;
+import org.apache.felix.scrplugin.om.Implementation;
+import org.apache.felix.scrplugin.om.Interface;
+import org.apache.felix.scrplugin.om.Property;
+import org.apache.felix.scrplugin.om.Reference;
+import org.apache.felix.scrplugin.om.Service;
+import org.apache.felix.scrplugin.om.metatype.AttributeDefinition;
+import org.apache.felix.scrplugin.om.metatype.Designate;
+import org.apache.felix.scrplugin.om.metatype.MTObject;
+import org.apache.felix.scrplugin.om.metatype.MetaData;
+import org.apache.felix.scrplugin.om.metatype.OCD;
 import org.apache.felix.scrplugin.xml.ComponentDescriptorIO;
 import org.apache.felix.scrplugin.xml.MetaTypeIO;
+import org.osgi.service.cm.ConfigurationAdmin;
 import org.osgi.service.metatype.MetaTypeService;
 
-
 /**
  * The <code>SCRDescriptorGenerator</code> class does the hard work of
  * generating the SCR descriptors. This class is being instantiated and
  * configured by clients and the {@link #execute()} method called to generate
  * the descriptor files.
  * <p>
- * When using this class carefully consider calling <i>all</i> setter methods
- * to properly configure the generator. All setter method document, which
- * default value is assumed for the respective property if the setter is
- * not called.
+ * When using this class carefully consider calling <i>all</i> setter methods to properly configure the generator. All setter
+ * method document, which default value is assumed for the respective property if the setter is not called.
  * <p>
  * Instances of this class are not thread save and should not be reused.
  */
-public class SCRDescriptorGenerator
-{
+public class SCRDescriptorGenerator {
 
     private final Log logger;
 
-    private File outputDirectory = null;
-
-    private JavaClassDescriptorManager descriptorManager;
+    private File outputDirectory;
 
     private String finalName = "serviceComponents.xml";
 
     private String metaTypeName = "metatype.xml";
 
-    private boolean generateAccessors = true;
+    /** The project. */
+    private Project project;
 
-    protected boolean strictMode = false;
+    /** The options. */
+    private Options options = new Options();
 
-    private Map<String, String> properties = new HashMap<String, String>();
+    /** The annotation scanner. */
+    private ClassScanner scanner;
 
-    private String specVersion = null;
-
+    /** The issue log. */
+    private IssueLog iLog;
 
     /**
-     * Create an instance of this generator using the given {@link Log}
-     * instance of logging.
+     * Create an instance of this generator using the given {@link Log} instance
+     * of logging.
      */
-    public SCRDescriptorGenerator( Log logger )
-    {
+    public SCRDescriptorGenerator(final Log logger) {
         this.logger = logger;
     }
 
+    /**
+     * Set the project. This is required.
+     */
+    public void setProject(final Project p) {
+        this.project = p;
+    }
+
+    /**
+     * Set the options.
+     */
+    public void setOptions(final Options p) {
+        this.options = p;
+    }
 
     /**
      * Sets the directory where the descriptor files will be created.
      * <p>
-     * This field has no default value and this setter <b>must</b> called prior
-     * to calling {@link #execute()}.
+     * This field has no default value and this setter <b>must</b> called prior to calling {@link #execute()}.
      */
-    public void setOutputDirectory( File outputDirectory )
-    {
+    public void setOutputDirectory(final File outputDirectory) {
         this.outputDirectory = outputDirectory;
     }
 
-
-    /**
-     * Sets the {@link JavaClassDescriptorManager} instance used to access
-     * existing descriptors and to parse JavaDoc tags as well as interpret
-     * the SCR annotations.
-     * <p>
-     * This field has no default value and this setter <b>must</b> called prior
-     * to calling {@link #execute()}.
-     */
-    public void setDescriptorManager( JavaClassDescriptorManager descriptorManager )
-    {
-        this.descriptorManager = descriptorManager;
-    }
-
-
     /**
      * Sets the name of the SCR declaration descriptor file. This file will be
-     * created in the <i>OSGI-INF</i> directory below the
-     * {@link #setOutputDirectory(File) output directory}.
+     * created in the <i>OSGI-INF</i> directory below the {@link #setOutputDirectory(File) output directory}.
      * <p>
-     * This file will be overwritten if already existing. If no descriptors
-     * are created the file is actually removed.
+     * This file will be overwritten if already existing. If no descriptors are created the file is actually removed.
      * <p>
      * The default value of this property is <code>serviceComponents.xml</code>.
      */
-    public void setFinalName( String finalName )
-    {
+    public void setFinalName(final String finalName) {
         this.finalName = finalName;
     }
 
-
     /**
      * Sets the name of the file taking the Metatype Service descriptors. This
-     * file will be created in the <i>OSGI-INF/metatype</i> directory below the
-     * {@link #setOutputDirectory(File) output directory}.
+     * file will be created in the <i>OSGI-INF/metatype</i> directory below the {@link #setOutputDirectory(File) output directory}
+     * .
      * <p>
-     * This file will be overwritten if already existing. If no descriptors
-     * are created the file is actually removed.
+     * This file will be overwritten if already existing. If no descriptors are created the file is actually removed.
      * <p>
      * The default value of this property is <code>metatype.xml</code>.
      */
-    public void setMetaTypeName( String metaTypeName )
-    {
+    public void setMetaTypeName(final String metaTypeName) {
         this.metaTypeName = metaTypeName;
     }
 
-
-    /**
-     * Defines whether bind and unbind methods are automatically created by
-     * the SCR descriptor generator.
-     * <p>
-     * The generator uses the ASM library to create the method byte codes
-     * directly inside the class files. If bind and unbind methods are not
-     * to be created, the generator fails if such methods are missing.
-     * <p>
-     * The default value of this property is <code>true</code>.
-     */
-    public void setGenerateAccessors( boolean generateAccessors )
-    {
-        this.generateAccessors = generateAccessors;
-    }
-
-
-    /**
-     * Defines whether warnings should be considered as errors and thus cause
-     * the generation process to fail.
-     * <p>
-     * The default value of this property is <code>false</code>.
-     */
-    public void setStrictMode( boolean strictMode )
-    {
-        this.strictMode = strictMode;
-    }
-
-
-    /**
-     * Sets global properties to be set for each descriptor. If a descriptor
-     * provides properties of the same name, the descriptor properties are preferred
-     * over the properties provided here.
-     * <p>
-     * The are no default global properties.
-     */
-    public void setProperties( Map<String, String> properties )
-    {
-        this.properties = new HashMap<String, String>( properties );
-    }
-
-
-    /**
-     * Sets the Declarative Services specification version number to be forced
-     * on the declarations.
-     * <p>
-     * Supported values for this property are <code>null</code> to autodetect
-     * the specification version, <code>1.0</code> to force 1.0 descriptors and
-     * <code>1.1</code> to force 1.1 descriptors. If 1.0 descriptors are forced
-     * the generation fails if a descriptor requires 1.1 functionality.
-     * <p>
-     * The default is to generate the descriptor version according to the
-     * capabilities used by the descriptors. If no 1.1 capabilities, such as
-     * <code>configuration-policy</code>, are used, version 1.0 is used,
-     * otherwise a 1.1 descriptor is generated.
-     */
-    public void setSpecVersion( String specVersion )
-    {
-        this.specVersion = specVersion;
-    }
-
-
     /**
      * Actually generates the Declarative Services and Metatype descriptors
-     * scanning the java sources provided by the
-     * {@link #setDescriptorManager(JavaClassDescriptorManager) descriptor manager}.
+     * scanning the java sources provided by the {@link #setProject(Project)}
      *
-     * @return <code>true</code> if descriptors have been generated.
+     * @return A list of generated file names, relative to the output directory
      *
      * @throws SCRDescriptorException
      * @throws SCRDescriptorFailureException
      */
-    public boolean execute() throws SCRDescriptorException, SCRDescriptorFailureException
-    {
-        this.logger.debug( "Starting SCRDescriptorMojo...." );
-        this.logger.debug( "..generating accessors: " + this.generateAccessors );
-        this.logger.debug( "..parsing javadocs: " + this.descriptorManager.isParseJavadocs() );
-        this.logger.debug( "..processing annotations: " + this.descriptorManager.isProcessAnnotations() );
+    public Result execute() throws SCRDescriptorException, SCRDescriptorFailureException {
+        if (this.project == null) {
+            throw new SCRDescriptorFailureException("Project has not been set!");
+        }
+        if (this.options == null) {
+            // use default options
+            this.options = new Options();
+        }
+
+        this.logger.debug("Starting SCRDescriptorMojo....");
+        this.logger.debug("..generating accessors: " + this.options.isGenerateAccessors());
 
         // check speck version configuration
-        int specVersion = toSpecVersionCode( this.specVersion, null );
-        if ( this.specVersion == null )
-        {
-            this.logger.debug( "..auto detecting spec version" );
-        }
-        else
-        {
-            this.logger.debug( "..using spec version " + this.specVersion + " (" + specVersion + ")" );
+        SpecVersion specVersion = options.getSpecVersion();
+        if (specVersion == null) {
+            this.logger.debug("..auto detecting spec version");
+        } else {
+            this.logger.debug("..using spec version " + specVersion.getName());
         }
 
-        final IssueLog iLog = new IssueLog( this.strictMode );
+        // create a log
+        this.iLog = new IssueLog(this.options.isStrictMode());
 
+        // create the annotation processor manager
+        final AnnotationProcessor aProcessor = new AnnotationProcessorManager(options.getAnnotationProcessors(),
+                        this.project.getClassLoader());
+
+        // create the class scanner - and start scanning
+        this.scanner = new ClassScanner(logger, iLog, project, aProcessor);
+        final List<ClassDescription> scannedDescriptions = scanner.scanSources();
+
+        // setup metadata
         final MetaData metaData = new MetaData();
-        metaData.setLocalization( MetaTypeService.METATYPE_DOCUMENTS_LOCATION + "/metatype" );
+        metaData.setLocalization(MetaTypeService.METATYPE_DOCUMENTS_LOCATION + "/metatype");
 
-        // iterate through all source classes and check for component tag
-        final JavaClassDescription[] javaSources = descriptorManager.getSourceDescriptions();
-        Arrays.sort( javaSources, new JavaClassDescriptionInheritanceComparator() );
+        final List<Component> processedComponents = new ArrayList<Component>();
+        for (final ClassDescription desc : scannedDescriptions) {
+            this.logger.debug("Processing component class " + desc.getSource());
 
-        final List<Component> scannedComponents = new ArrayList<Component>();
-        for ( int i = 0; i < javaSources.length; i++ )
-        {
-            this.logger.debug( "Testing source " + javaSources[i].getName() );
-            final JavaTag tag = javaSources[i].getTagByName( Constants.COMPONENT );
-            if ( tag != null )
-            {
-                // FELIX-2853 : Deprecate javadoc tags.
-                // This is not the most clever way of doing this, but it is the least intrusive...
-                if ( javaSources[i] instanceof QDoxJavaClassDescription
-                     && !(javaSources[i] instanceof AnnotationJavaClassDescription)) {
-                    iLog.addDeprecationWarning("Class " + javaSources[i].getName() + " is using deprecated javadoc tags ",
-                            tag.getSourceLocation(), tag.getLineNumber());
-                }
-                this.logger.debug( "Processing service class " + javaSources[i].getName() );
-                // check if there is more than one component tag!
-                if ( javaSources[i].getTagsByName( Constants.COMPONENT, false ).length > 1 )
-                {
-                    iLog.addError( "Class " + javaSources[i].getName() + " has more than one " + Constants.COMPONENT
-                        + " tag." + " Merge the tags to a single tag.", tag.getSourceLocation(), tag.getLineNumber() );
-                }
-                else
-                {
-                    try
-                    {
-                        final Component comp = this.createComponent( javaSources[i], tag, metaData, iLog );
-                        if ( comp.getSpecVersion() > specVersion )
-                        {
+            // check if there is more than one component definition
+            if (desc.getDescriptions(ComponentDescription.class).size() > 1) {
+                iLog.addError("Class has more than one component definition." +
+                             " Check the annotations and merge the definitions to a single definition.",
+                                desc.getSource());
+            } else {
+                try {
+                    final Component comp = this.createComponent(desc, metaData, iLog);
+                    if (comp.getSpecVersion() != null) {
+                        if ( specVersion == null ) {
+                            specVersion = comp.getSpecVersion();
+                            logger.debug("Setting used spec version to " + specVersion);
+                        } else if (comp.getSpecVersion().ordinal() > specVersion.ordinal() && this.options.getSpecVersion() != null) {
                             // if a spec version has been configured and a component requires a higher
                             // version, this is considered an error!
-                            if ( this.specVersion != null )
-                            {
-                                String v = Constants.COMPONENT_DS_SPEC_VERSION_10;
-                                if ( comp.getSpecVersion() == Constants.VERSION_1_1 )
-                                {
-                                    v = Constants.COMPONENT_DS_SPEC_VERSION_11;
-                                }
-                                iLog.addError( "Component " + comp + " requires spec version " + v
-                                    + " but plugin is configured to use version " + this.specVersion, tag
-                                    .getSourceLocation(), tag.getLineNumber() );
-                            }
-                            specVersion = comp.getSpecVersion();
+                            iLog.addError("Component " + comp + " requires spec version " + comp.getSpecVersion().name()
+                                            + " but plugin is configured to use version " + this.options.getSpecVersion(),
+                                            desc.getSource());
                         }
-                        scannedComponents.add( comp );
                     }
-                    catch ( SCRDescriptorException sde )
-                    {
-                        iLog.addError( sde.getMessage(), sde.getSourceLocation(), sde.getLineNumber() );
-                    }
+                    processedComponents.add(comp);
+                } catch (final SCRDescriptorException sde) {
+                    iLog.addError(sde.getMessage(), sde.getSourceLocation());
                 }
             }
         }
-        this.logger.debug( "..generating descriptor for spec version: " + this.specVersion );
+        // if spec version is still not set, we're using lowest available
+        if ( specVersion == null ) {
+            specVersion = SpecVersion.VERSION_1_0;
+            logger.debug("Using default spec version " + specVersion);
+        }
+        this.logger.debug("Generating descriptor for spec version: " + specVersion);
 
         // now check for abstract components and fill components objects
         final Components components = new Components();
-        final Components abstractComponents = new Components();
-        components.setSpecVersion( specVersion );
-        abstractComponents.setSpecVersion( specVersion );
+        components.setSpecVersion(specVersion);
 
-        for ( final Component comp : scannedComponents )
-        {
+        for (final Component comp : processedComponents) {
             final int errorCount = iLog.getNumberOfErrors();
-            // before we can validate we should check the references for bind/unbind method
-            // in order to create them if possible
 
-            for ( final Reference ref : comp.getReferences() )
-            {
-                // if this is a field with a single cardinality,
-                // we look for the bind/unbind methods
-                // and create them if they are not availabe
-                if ( this.generateAccessors && !ref.isLookupStrategy() )
-                {
-                    if ( ref.getJavaTag().getField() != null
-                        && comp.getJavaClassDescription() instanceof ModifiableJavaClassDescription )
-                    {
-                        if ( ref.getCardinality().equals( "0..1" ) || ref.getCardinality().equals( "1..1" ) )
-                        {
-                            final String bindValue = ref.getBind();
-                            final String unbindValue = ref.getUnbind();
-                            final String name = ref.getName();
-                            final String type = ref.getInterfacename();
+            final Context ctx = new Context();
+            ctx.setClassDescription(comp.getClassDescription());
+            ctx.setIssueLog(iLog);
+            ctx.setProject(project);
+            ctx.setSpecVersion(specVersion);
+            ctx.setOptions(options);
 
-                            boolean createBind = false;
-                            boolean createUnbind = false;
-                            // Only create method if no bind name has been specified
-                            if ( bindValue == null && ref.findMethod( specVersion, "bind" ) == null )
-                            {
-                                // create bind method
-                                createBind = true;
-                            }
-                            if ( unbindValue == null && ref.findMethod( specVersion, "unbind" ) == null )
-                            {
-                                // create unbind method
-                                createUnbind = true;
-                            }
-                            if ( createBind || createUnbind )
-                            {
-                                ( ( ModifiableJavaClassDescription ) comp.getJavaClassDescription() ).addMethods( name,
-                                    type, createBind, createUnbind );
-                            }
+            if ( this.options.isGenerateAccessors() ) {
+                // before we can validate we should check the references for bind/unbind method
+                // in order to create them if possible
+
+                for (final Reference ref : comp.getReferences()) {
+                    // if this is a field with a single cardinality,
+                    // we look for the bind/unbind methods
+                    // and create them if they are not availabe
+                    if (!ref.isLookupStrategy() && ref.getField() != null
+                        && (ref.getCardinality() == ReferenceCardinality.OPTIONAL_UNARY || ref.getCardinality() == ReferenceCardinality.MANDATORY_UNARY)) {
+
+                        final String bindValue = ref.getBind();
+                        final String unbindValue = ref.getUnbind();
+                        final String name = ref.getName();
+                        final String type = ref.getInterfacename();
+
+                        boolean createBind = false;
+                        boolean createUnbind = false;
+
+                        // Only create method if no bind name has been specified
+                        if (bindValue == null && ref.findMethod(ctx, "bind") == null) {
+                            // create bind method
+                            createBind = true;
+                        }
+                        if (unbindValue == null && ref.findMethod(ctx, "unbind") == null) {
+                            // create unbind method
+                            createUnbind = true;
+                        }
+                        if (createBind || createUnbind) {
+                            ClassModifier.addMethods(comp.getClassDescription().getDescribedClass().getName(),
+                                            name,
+                                            ref.getField().getName(),
+                                            type,
+                                            createBind,
+                                            createUnbind,
+                                            this.project.getClassesDirectory());
                         }
                     }
                 }
             }
-            comp.validate( specVersion, iLog );
+            comp.validate(ctx);
+
             // ignore component if it has errors
-            if ( iLog.getNumberOfErrors() == errorCount )
-            {
-                if ( !comp.isDs() )
-                {
-                    logger.debug( "Ignoring descriptor " + comp );
-                }
-                else if ( comp.isAbstract() )
-                {
-                    this.logger.debug( "Adding abstract descriptor " + comp );
-                    abstractComponents.addComponent( comp );
-                }
-                else
-                {
-                    this.logger.debug( "Adding descriptor " + comp );
-                    components.addComponent( comp );
-                    abstractComponents.addComponent( comp );
+            if (iLog.getNumberOfErrors() == errorCount) {
+                if (!comp.isDs()) {
+                    logger.debug("Ignoring descriptor for DS : " + comp);
+                } else if (!comp.isAbstract()) {
+                    this.logger.debug("Adding descriptor for DS : " + comp);
+                    components.addComponent(comp);
                 }
             }
         }
 
         // log issues
-        iLog.logMessages( logger );
+        iLog.logMessages(logger);
 
         // after checking all classes, throw if there were any failures
-        if ( iLog.hasErrors() )
-        {
-            throw new SCRDescriptorFailureException( "SCR Descriptor parsing had failures (see log)" );
+        if (iLog.hasErrors()) {
+            throw new SCRDescriptorFailureException("SCR Descriptor parsing had failures (see log)");
         }
 
-        boolean addResources = false;
+        final Result result = new Result();
         // write meta type info if there is a file name
-        if ( !StringUtils.isEmpty( this.metaTypeName ) )
-        {
-            File mtFile = new File( this.outputDirectory, "OSGI-INF" + File.separator + "metatype" + File.separator
-                + this.metaTypeName );
+        if (!StringUtils.isEmpty(this.metaTypeName)) {
+            final String path = "OSGI-INF" + File.separator + "metatype" + File.separator + this.metaTypeName;
+            final File mtFile = new File(this.outputDirectory, path);
             final int size = metaData.getOCDs().size() + metaData.getDesignates().size();
-            if ( size > 0 )
-            {
-                this.logger.info( "Generating " + size + " MetaType Descriptors to " + mtFile );
+            if (size > 0) {
+                this.logger.info("Generating " + size + " MetaType Descriptors to " + mtFile);
                 mtFile.getParentFile().mkdirs();
-                MetaTypeIO.write( metaData, mtFile );
-                addResources = true;
-            }
-            else
-            {
-                if ( mtFile.exists() )
-                {
+                MetaTypeIO.write(metaData, mtFile);
+                result.setMetatypeFiles(Collections.singletonList(path.replace(File.separatorChar, '/')));
+            } else {
+                if (mtFile.exists()) {
                     mtFile.delete();
                 }
             }
 
-        }
-        else
-        {
-            this.logger.info( "Meta type file name is not set: meta type info is not written." );
-        }
-
-        // if we have descriptors, write them in our scr private file (for component inheritance)
-        final File adFile = new File( this.outputDirectory, Constants.ABSTRACT_DESCRIPTOR_RELATIVE_PATH );
-        if ( !abstractComponents.getComponents().isEmpty() )
-        {
-            this.logger.info( "Writing abstract service descriptor " + adFile + " with "
-                + abstractComponents.getComponents().size() + " entries." );
-            adFile.getParentFile().mkdirs();
-            ComponentDescriptorIO.write( abstractComponents, adFile, true );
-            addResources = true;
-        }
-        else
-        {
-            this.logger.debug( "No abstract SCR Descriptors found in project." );
-            // remove file
-            if ( adFile.exists() )
-            {
-                this.logger.debug( "Removing obsolete abstract service descriptor " + adFile );
-                adFile.delete();
-            }
+        } else {
+            this.logger.info("Meta type file name is not set: meta type info is not written.");
         }
 
         // check descriptor file
-        final File descriptorFile = StringUtils.isEmpty( this.finalName ) ? null : new File( new File(
-            this.outputDirectory, "OSGI-INF" ), this.finalName );
+        final String descriptorPath = "OSGI-INF" + File.separator + this.finalName;
+        final File descriptorFile = StringUtils.isEmpty(this.finalName) ? null : new File(this.outputDirectory, descriptorPath);
 
         // terminate if there is nothing else to write
-        if ( components.getComponents().isEmpty() )
-        {
-            this.logger.debug( "No SCR Descriptors found in project." );
+        if (components.getComponents().isEmpty()) {
+            this.logger.debug("No Service Component Descriptors found in project.");
             // remove file if it exists
-            if ( descriptorFile != null && descriptorFile.exists() )
-            {
-                this.logger.debug( "Removing obsolete service descriptor " + descriptorFile );
+            if (descriptorFile != null && descriptorFile.exists()) {
+                this.logger.debug("Removing obsolete service descriptor " + descriptorFile);
                 descriptorFile.delete();
             }
-        }
-        else
-        {
-            if ( descriptorFile == null )
-            {
-                throw new SCRDescriptorFailureException( "Descriptor file name must not be empty." );
+        } else {
+            if (descriptorFile == null) {
+                throw new SCRDescriptorFailureException("Descriptor file name must not be empty.");
             }
 
             // finally the descriptors have to be written ....
             descriptorFile.getParentFile().mkdirs(); // ensure parent dir
 
-            this.logger.info( "Generating " + components.getComponents().size() + " Service Component Descriptors to "
-                + descriptorFile );
+            this.logger.info("Writing " + components.getComponents().size() + " Service Component Descriptors to "
+                            + descriptorFile);
 
-            ComponentDescriptorIO.write( components, descriptorFile, false );
-            addResources = true;
+            ComponentDescriptorIO.write(components, descriptorFile);
+            result.setScrFiles(Collections.singletonList(descriptorPath.replace(File.separatorChar, '/')));
         }
 
-        return addResources;
+        return result;
     }
 
-
     /**
-     * Create a component for the java class description.
-     * @param description
-     * @return The generated component descriptor or null if any error occurs.
-     * @throws SCRDescriptorException
+     * Create the SCR objects based on the descriptions
      */
-    protected Component createComponent( JavaClassDescription description, JavaTag componentTag, MetaData metaData,
-        final IssueLog iLog ) throws SCRDescriptorException
-    {
-        // create a new component
-        final Component component = new Component( componentTag );
+    private Component createComponent(final ClassDescription desc,
+                    final MetaData metaData,
+                    final IssueLog iLog)
+    throws SCRDescriptorException, SCRDescriptorFailureException {
+        final ComponentDescription componentDesc = desc.getDescription(ComponentDescription.class);
+        final Component comp = new Component(desc, componentDesc.getAnnotation(), desc.getSource());
 
-        // set implementation
-        component.setImplementation( new Implementation( description.getName() ) );
+        comp.setName(componentDesc.getName());
+        comp.setConfigurationPolicy(componentDesc.getConfigurationPolicy());
+        comp.setAbstract(componentDesc.isAbstract());
+        comp.setDs(componentDesc.isCreateDs());
+        comp.setFactory(componentDesc.getFactory());
+        comp.setSpecVersion(componentDesc.getSpecVersion());
 
-        final boolean inherited = getBoolean( componentTag, Constants.COMPONENT_INHERIT, true );
-        final OCD ocd = this.doComponent( componentTag, component, metaData,inherited,  iLog );
-
-        this.doServices( description.getTagsByName( Constants.SERVICE, inherited ), component, description );
-
-        // collect references from class tags and fields
-        final Map<String, Object[]> references = new LinkedHashMap<String, Object[]>();
-        // Utility handler for propertie
-        final PropertyHandler propertyHandler = new PropertyHandler( component, ocd );
-
-        JavaClassDescription currentDescription = description;
-        do
-        {
-            // properties
-            final JavaTag[] props = currentDescription.getTagsByName( Constants.PROPERTY, false );
-            for ( int i = 0; i < props.length; i++ )
-            {
-                propertyHandler.testProperty( props[i], null, description == currentDescription );
-            }
-
-            // references
-            final JavaTag[] refs = currentDescription.getTagsByName( Constants.REFERENCE, false );
-            for ( int i = 0; i < refs.length; i++ )
-            {
-                this.testReference( references, refs[i], null, description == currentDescription );
-            }
-
-            // fields
-            final JavaField[] fields = currentDescription.getFields();
-            for ( int i = 0; i < fields.length; i++ )
-            {
-                JavaTag tag = fields[i].getTagByName( Constants.REFERENCE );
-                if ( tag != null )
-                {
-                    this.testReference( references, tag, fields[i].getName(), description == currentDescription );
-                }
-
-                propertyHandler.handleField( fields[i], description == currentDescription );
-            }
-
-            currentDescription = currentDescription.getSuperClass();
-        }
-        while ( inherited && currentDescription != null );
-
-        // process properties
-        propertyHandler.processProperties( this.properties, iLog );
-
-        // process references
-        final Iterator<Map.Entry<String, Object[]>> refIter = references.entrySet().iterator();
-        while ( refIter.hasNext() )
-        {
-            final Map.Entry<String, Object[]> entry = refIter.next();
-            final String refName = entry.getKey();
-            final Object[] values = entry.getValue();
-            final JavaTag tag = ( JavaTag ) values[0];
-            this.doReference( tag, refName, component, values[1].toString(), ((Boolean)values[2]).booleanValue() );
-        }
-
-        // pid handling
-        final boolean createPid = getBoolean( componentTag, Constants.COMPONENT_CREATE_PID, true );
-        if ( createPid )
-        {
-            // check for an existing pid first
-            boolean found = false;
-            final Iterator<Property> iter = component.getProperties().iterator();
-            while ( !found && iter.hasNext() )
-            {
-                final Property prop = iter.next();
-                found = org.osgi.framework.Constants.SERVICE_PID.equals( prop.getName() );
-            }
-            if ( !found )
-            {
-                final Property pid = new Property();
-                component.addProperty( pid );
-                pid.setName( org.osgi.framework.Constants.SERVICE_PID );
-                pid.setValue( component.getName() );
-            }
-        }
-        return component;
-    }
-
-
-    /**
-     * Fill the component object with the information from the tag.
-     * @param tag
-     * @param component
-     */
-    protected OCD doComponent( final JavaTag tag,
-            final Component component,
-            final MetaData metaData,
-            final boolean inherit,
-            final IssueLog iLog )
-        throws SCRDescriptorException
-    {
-
-        // check if this is an abstract definition
-        final String abstractType = tag.getNamedParameter( Constants.COMPONENT_ABSTRACT );
-        if ( abstractType != null )
-        {
-            component.setAbstract( "yes".equalsIgnoreCase( abstractType ) || "true".equalsIgnoreCase( abstractType ) );
-        }
-        else
-        {
-            // default true for abstract classes, false otherwise
-            component.setAbstract( tag.getJavaClassDescription().isAbstract() );
-        }
-
-        // check if this is a definition to ignore
-        final String ds = tag.getNamedParameter( Constants.COMPONENT_DS );
-        component.setDs( ( ds == null ) ? true : ( "yes".equalsIgnoreCase( ds ) || "true".equalsIgnoreCase( ds ) ) );
-
-        String name = tag.getNamedParameter( Constants.COMPONENT_NAME );
-        component.setName( StringUtils.isEmpty( name ) ? component.getImplementation().getClassame() : name );
-
-        component.setEnabled( Boolean.valueOf( getBoolean( tag, Constants.COMPONENT_ENABLED, true ) ) );
-        component.setFactory( tag.getNamedParameter( Constants.COMPONENT_FACTORY ) );
-
-        // FELIX-1703: support explicit SCR version declaration
-        final String dsSpecVersion = tag.getNamedParameter( Constants.COMPONENT_DS_SPEC_VERSION );
-        if ( dsSpecVersion != null )
-        {
-            component.setSpecVersion( toSpecVersionCode( dsSpecVersion, tag ) );
-        }
-
-        // FELIX-593: immediate attribute does not default to true all the
-        // times hence we only set it if declared in the tag
-        if ( tag.getNamedParameter( Constants.COMPONENT_IMMEDIATE ) != null )
-        {
-            component.setImmediate( Boolean.valueOf( getBoolean( tag, Constants.COMPONENT_IMMEDIATE, true ) ) );
-        }
-
-        // check for V1.1 attributes: configuration policy
-        if ( tag.getNamedParameter( Constants.COMPONENT_CONFIG_POLICY ) != null )
-        {
-            component.setSpecVersion( Constants.VERSION_1_1 );
-            component.setConfigurationPolicy( tag.getNamedParameter( Constants.COMPONENT_CONFIG_POLICY ) );
-        }
-        // check for V1.1 attributes: activate, deactivate, modified
-        component.setActivate(this.checkLifecycleMethod(component, Constants.COMPONENT_ACTIVATE, tag, inherit));
-        component.setDeactivate(this.checkLifecycleMethod(component, Constants.COMPONENT_DEACTIVATE, tag, inherit));
-        component.setModified(this.checkLifecycleMethod(component, Constants.COMPONENT_MODIFIED, tag, inherit));
-
-        // whether metatype information is to generated for the component
-        final String metaType = tag.getNamedParameter( Constants.COMPONENT_METATYPE );
-        final boolean hasMetaType = metaType == null || "yes".equalsIgnoreCase( metaType )
-            || "true".equalsIgnoreCase( metaType );
-        if ( !component.isAbstract() && hasMetaType )
-        {
-            // ocd
-            final OCD ocd = new OCD();
+        // Create metatype (if required)
+        final OCD ocd;
+        if ( !componentDesc.isAbstract() && componentDesc.isCreateMetatype() ) {
+            // OCD
+            ocd = new OCD();
             metaData.addOCD( ocd );
-            ocd.setId( component.getName() );
-            String ocdName = tag.getNamedParameter( Constants.COMPONENT_LABEL );
-            if ( ocdName == null )
-            {
-                ocdName = "%" + component.getName() + ".name";
+            ocd.setId( componentDesc.getName() );
+            if ( componentDesc.getLabel() != null ) {
+                ocd.setName( componentDesc.getLabel() );
+            } else {
+                ocd.setName( "%" + componentDesc.getName() + ".name");
             }
-            ocd.setName( ocdName );
-            String ocdDescription = tag.getNamedParameter( Constants.COMPONENT_DESCRIPTION );
-            if ( ocdDescription == null )
-            {
-                ocdDescription = "%" + component.getName() + ".description";
+            if ( componentDesc.getDescription() != null ) {
+                ocd.setDescription( componentDesc.getDescription() );
+            } else {
+                ocd.setDescription( "%" + componentDesc.getName() + ".description");
             }
-            ocd.setDescription( ocdDescription );
-            // designate
+
+            // Designate
             final Designate designate = new Designate();
             metaData.addDesignate( designate );
-            designate.setPid( component.getName() );
+            designate.setPid( componentDesc.getName() );
 
-            // factory pid
-            final String setFactoryPidValue = tag.getNamedParameter( Constants.COMPONENT_SET_METATYPE_FACTORY_PID );
-            final boolean setFactoryPid = setFactoryPidValue != null
-                && ( "yes".equalsIgnoreCase( setFactoryPidValue ) || "true".equalsIgnoreCase( setFactoryPidValue ) );
-            if ( setFactoryPid )
-            {
-                if ( component.getFactory() == null )
-                {
-                    designate.setFactoryPid( component.getName() );
-                }
-                else
-                {
-                    iLog.addWarning( "Component factory " + component.getName()
-                        + " should not set metatype factory pid.", tag.getSourceLocation(), tag.getLineNumber() );
+            // Factory pid
+            if ( componentDesc.isSetMetatypeFactoryPid() ) {
+                if ( componentDesc.getFactory() == null ) {
+                    designate.setFactoryPid( componentDesc.getName() );
+                } else {
+                    iLog.addWarning( "Component factory " + componentDesc.getName()
+                        + " should not set metatype factory pid.", desc.getSource() );
                 }
             }
-            // designate.object
+            // MTObject
             final MTObject mtobject = new MTObject();
             designate.setObject( mtobject );
-            mtobject.setOcdref( component.getName() );
-            return ocd;
+            mtobject.setOcdref( componentDesc.getName() );
+        } else {
+            ocd = null;
         }
-        return null;
-    }
 
-    private String checkLifecycleMethod(final Component component,
-            final String methodTagName,
-            final JavaTag tag,
-            final boolean inherit)
-    throws SCRDescriptorException
-    {
-        String method = null;
-        if ( tag.getNamedParameter( methodTagName ) != null )
-        {
-            method = tag.getNamedParameter( methodTagName );
-        }
-        else if ( inherit )
-        {
-            // check if a super class has the activate method specified
-            JavaClassDescription desc = tag.getJavaClassDescription().getSuperClass();
-            while ( desc != null && method == null )
-            {
-                final JavaTag componentTag = desc.getTagByName( Constants.COMPONENT );
-                if ( componentTag != null && componentTag.getNamedParameter( methodTagName ) != null )
-                {
-                    method = componentTag.getNamedParameter( methodTagName );
+        // Create implementation object
+        final Implementation impl = new Implementation(desc.getDescribedClass().getName());
+        comp.setImplementation(impl);
+
+        final Map<String, Reference> allReferences = new HashMap<String, Reference>();
+        final Map<String, Property> allProperties = new HashMap<String, Property>();
+
+        ClassDescription current = desc;
+        boolean inherit;
+        do {
+            final ComponentDescription cd = current.getDescription(ComponentDescription.class);
+            inherit = (cd == null ? true : cd.isInherit());
+
+            if ( cd != null ) {
+                // handle enabled and immediate
+                if ( comp.isEnabled() == null ) {
+                    comp.setEnabled(cd.getEnabled());
                 }
-                desc = desc.getSuperClass();
+                if ( comp.isImmediate() == null ) {
+                    comp.setImmediate(cd.getImmediate());
+                }
+
+                // lifecycle methods
+                if ( comp.getActivate() == null && cd.getActivate() != null ) {
+                    comp.setActivate(cd.getActivate().getName());
+                }
+                if ( comp.getDeactivate() == null && cd.getDeactivate() != null ) {
+                    comp.setDeactivate(cd.getDeactivate().getName());
+                }
+                if ( comp.getModified() == null && cd.getModified() != null ) {
+                    comp.setModified(cd.getModified().getName());
+                }
+                if ( comp.getActivate() != null || comp.getDeactivate() != null || comp.getModified() != null ) {
+                    // spec version must be at least 1.1
+                    comp.setSpecVersion(SpecVersion.VERSION_1_1);
+                }
             }
+
+            // services, properties, references
+            this.processServices(current, comp);
+            this.processProperties(current, comp, ocd, allProperties);
+            this.processReferences(current, comp, allReferences);
+
+            // go up in the class hierarchy
+            if ( !inherit || current.getDescribedClass().getSuperclass() == null ) {
+                current = null;
+            } else {
+                current = this.scanner.getDescription(current.getDescribedClass().getSuperclass());
+            }
+        } while ( inherit && current != null);
+
+        // PID handling
+        if ( componentDesc.isCreatePid() && !allProperties.containsKey(org.osgi.framework.Constants.SERVICE_PID)) {
+            final Property pid = new Property(null, "scr-generator");
+            pid.setName( org.osgi.framework.Constants.SERVICE_PID );
+            pid.setValue( comp.getName() );
+
+            allProperties.put(org.osgi.framework.Constants.SERVICE_PID, pid);
+            comp.addProperty( pid );
         }
-        if ( method != null )
-        {
-            component.setSpecVersion( Constants.VERSION_1_1 );
-        }
-        return method;
+        this.processGlobalProperties(desc, comp, allProperties);
+
+        return comp;
     }
 
     /**
-     * Process the service annotations
-     * @param services
-     * @param component
-     * @param description
-     * @throws SCRDescriptorException
+     * Process service directives
      */
-    protected void doServices( JavaTag[] services, Component component, JavaClassDescription description )
-        throws SCRDescriptorException
-    {
-        // no services, hence certainly no service factory
-        if ( services == null || services.length == 0 )
-        {
-            return;
-        }
+    private void processServices(final ClassDescription current, final Component component)
+    throws SCRDescriptorException, SCRDescriptorFailureException {
 
-        final Service service = new Service();
-        component.setService( service );
-        boolean serviceFactory = false;
-        for ( int i = 0; i < services.length; i++ )
-        {
-            final String name = services[i].getNamedParameter( Constants.SERVICE_INTERFACE );
-            if ( StringUtils.isEmpty( name ) )
-            {
-
-                this.addInterfaces( service, services[i], description );
+        final ServiceDescription serviceDesc = current.getDescription(ServiceDescription.class);
+        if ( serviceDesc != null ) {
+            Service service = component.getService();
+            if ( service == null ) {
+                service = new Service();
+                service.setServiceFactory(false);
+                component.setService(service);
             }
-            else
-            {
-                String interfaceName = name;
-                // check if the value points to a class/interface
-                // and search through the imports
-                // but only for local services
-                if ( description instanceof QDoxJavaClassDescription )
-                {
-                    final JavaClassDescription serviceClass = description.getReferencedClass( name );
-                    if ( serviceClass == null )
-                    {
-                        throw new SCRDescriptorException( "Interface '" + name + "' in class " + description.getName()
-                            + " does not point to a valid class/interface.", services[i] );
+            if ( serviceDesc.isServiceFactory() ) {
+                service.setServiceFactory(true);
+            }
+            for(final String className : serviceDesc.getInterfaces()) {
+                final Interface interf = new Interface(serviceDesc.getAnnotation(), current.getSource());
+                interf.setInterfaceName(className);
+                service.addInterface(interf);
+            }
+        }
+    }
+
+    /**
+     * Process property directives
+     */
+    private void processProperties(
+                    final ClassDescription current,
+                    final Component component,
+                    final OCD ocd,
+                    final Map<String, Property> allProperties)
+    throws SCRDescriptorException, SCRDescriptorFailureException {
+        for(final PropertyDescription pd : current.getDescriptions(PropertyDescription.class)) {
+            final Property prop = new Property(pd.getAnnotation(), current.getSource());
+            prop.setName(pd.getName());
+            prop.setType(pd.getType());
+            if ( pd.getValue() != null ) {
+                prop.setValue(pd.getValue());
+            } else {
+                prop.setMultiValue(pd.getMultiValue());
+            }
+
+            // metatype - is this property private?
+            final boolean isPrivate;
+            if ( pd.isPrivate() != null ) {
+                isPrivate = pd.isPrivate();
+            } else {
+                final String name = prop.getName();
+                if (org.osgi.framework.Constants.SERVICE_RANKING.equals(name)
+                    || org.osgi.framework.Constants.SERVICE_PID.equals(name)
+                    || org.osgi.framework.Constants.SERVICE_DESCRIPTION.equals(name)
+                    || org.osgi.framework.Constants.SERVICE_ID.equals(name)
+                    || org.osgi.framework.Constants.SERVICE_VENDOR.equals(name)
+                    || ConfigurationAdmin.SERVICE_BUNDLELOCATION.equals(name)
+                    || ConfigurationAdmin.SERVICE_FACTORYPID.equals(name) ) {
+                    isPrivate = true;
+                } else {
+                    isPrivate = false;
+                }
+            }
+            if ( !isPrivate && ocd != null ) {
+                final AttributeDefinition ad = new AttributeDefinition();
+                ocd.getProperties().add(ad);
+                ad.setId(prop.getName());
+                ad.setType(prop.getType().name());
+
+                if (pd.getLabel() != null ) {
+                    ad.setName(pd.getLabel());
+                } else {
+                    ad.setName("%" + prop.getName() + ".name");
+                }
+                if (pd.getDescription() != null ) {
+                    ad.setDescription(pd.getDescription());
+                } else {
+                    ad.setDescription("%" + prop.getName() + ".description");
+                }
+
+                if ( pd.getUnbounded() == PropertyUnbounded.DEFAULT ) {
+                    ad.setCardinality(pd.getCardinality());
+                } else if ( pd.getUnbounded() == PropertyUnbounded.ARRAY ) {
+                    // unlimited array
+                    ad.setCardinality(new Integer(Integer.MAX_VALUE));
+                } else {
+                    // unlimited vector
+                    ad.setCardinality(new Integer(Integer.MIN_VALUE));
+                }
+
+                ad.setDefaultValue(prop.getValue());
+                ad.setDefaultMultiValue(prop.getMultiValue());
+
+                // check options
+                final String[] parameters = pd.getOptions();
+                if ( parameters != null && parameters.length > 0 ) {
+                    final Map<String, String> options = new LinkedHashMap<String, String>();
+                    for (int j=0; j < parameters.length; j=j+2) {
+                        final String optionLabel = parameters[j];
+                        final String optionValue = (j < parameters.length-1) ? parameters[j+1] : null;
+                        if (optionValue != null) {
+                            options.put(optionLabel, optionValue);
+                        }
                     }
-                    interfaceName = serviceClass.getName();
+                    ad.setOptions(options);
                 }
-                final Interface interf = new Interface( services[i] );
-                interf.setInterfacename( interfaceName );
-                service.addInterface( interf );
+
             }
-
-            serviceFactory |= getBoolean( services[i], Constants.SERVICE_FACTORY, false );
+            if ( this.testProperty(current, allProperties, prop, current == component.getClassDescription())) {
+                component.addProperty(prop);
+            }
         }
-
-        service.setServicefactory( serviceFactory );
     }
 
-
     /**
-     * Recursively add interfaces to the service.
+     * Add global properties (if not already defined in the component)
      */
-    protected void addInterfaces( final Service service, final JavaTag serviceTag,
-        final JavaClassDescription description ) throws SCRDescriptorException
-    {
-        if ( description != null )
-        {
-            JavaClassDescription[] interfaces = description.getImplementedInterfaces();
-            for ( int j = 0; j < interfaces.length; j++ )
-            {
-                final Interface interf = new Interface( serviceTag );
-                interf.setInterfacename( interfaces[j].getName() );
-                service.addInterface( interf );
-                // recursivly add interfaces implemented by this interface
-                this.addInterfaces( service, serviceTag, interfaces[j] );
-            }
+    private void processGlobalProperties(final ClassDescription desc,
+                    final Component component,
+                    final Map<String, Property> allProperties) {
+        // apply pre configured global properties
+        if ( this.options.getProperties() != null ) {
+            for(final Map.Entry<String, String> entry : this.options.getProperties().entrySet()) {
+                final String propName = entry.getKey();
+                final String value = entry.getValue();
+                // check if the service already provides this property
+                if ( value != null && !allProperties.containsKey(propName) ) {
 
-            // try super class
-            this.addInterfaces( service, serviceTag, description.getSuperClass() );
+                    final Property p = new Property(null, "scr-generator");
+                    p.setName(propName);
+                    p.setValue(value);
+                    p.setType(PropertyType.String);
+
+                    component.addProperty(p);
+                    allProperties.put(propName, p);
+                }
+            }
         }
     }
 
+    /**
+     * Test a newly found property
+     */
+    private boolean testProperty(final ClassDescription current,
+                    final Map<String, Property> allProperties,
+                    final Property newProperty,
+                    boolean isInspectedClass ) {
+        final String propName = newProperty.getName();
+
+        if ( !StringUtils.isEmpty(propName) ) {
+            if ( allProperties.containsKey(propName) ) {
+                // if the current class is the class we are currently inspecting, we
+                // have found a duplicate definition
+                if ( isInspectedClass ) {
+                    iLog.addError("Duplicate definition for property " + propName + " in class "
+                                    + current.getDescribedClass().getName(), current.getSource() );
+                }
+            } else {
+                allProperties.put(propName, newProperty);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Process reference directives
+     */
+    private void processReferences(final ClassDescription current,
+                    final Component component,
+                    final Map<String, Reference> allReferences)
+    throws SCRDescriptorException, SCRDescriptorFailureException {
+        for(final ReferenceDescription rd : current.getDescriptions(ReferenceDescription.class)) {
+            final Reference ref = new Reference(rd.getAnnotation(), current.getSource());
+            ref.setName(rd.getName());
+            ref.setInterfacename(rd.getInterfaceName());
+            ref.setCardinality(rd.getCardinality());
+            ref.setPolicy(rd.getPolicy());
+            ref.setStrategy(rd.getStrategy());
+            ref.setTarget(rd.getTarget());
+            ref.setField(rd.getField());
+            if ( rd.getBind() != null ) {
+                ref.setBind(rd.getBind().getName());
+            }
+            if ( rd.getUnbind() != null ) {
+                ref.setUnbind(rd.getUnbind().getName());
+            }
+            if ( rd.getUpdated() != null ) {
+                ref.setUpdated(rd.getUpdated().getName());
+            }
+
+            if ( this.testReference(current, allReferences, ref, component.getClassDescription() == current) ) {
+                component.addReference(ref);
+            }
+        }
+    }
 
     /**
      * Test a newly found reference
-     * @param references
-     * @param reference
-     * @param defaultName
-     * @param isInspectedClass
-     * @throws SCRDescriptorException
      */
-    protected void testReference( Map<String, Object[]> references, JavaTag reference, String defaultName,
-        boolean isInspectedClass ) throws SCRDescriptorException
-    {
-        String refName = this.getReferenceName( reference, defaultName );
-
-        boolean setName = refName != null;
-        if ( refName == null)
-        {
-            refName = this.getReferencedInterface(reference, isInspectedClass, null);
+    private boolean testReference(final ClassDescription current,
+                    final Map<String, Reference> allReferences,
+                    final Reference newReference,
+                    boolean isInspectedClass ) {
+        String refName = newReference.getName();
+        if ( refName == null) {
+            refName = newReference.getInterfacename();
         }
 
-        if ( refName != null )
-        {
-            if ( references.containsKey( refName ) )
-            {
+        if ( refName != null ) {
+            if ( allReferences.containsKey( refName ) ) {
                 // if the current class is the class we are currently inspecting, we
                 // have found a duplicate definition
-                if ( isInspectedClass )
-                {
-                    throw new SCRDescriptorException( "Duplicate definition for reference " + refName + " in class "
-                        + reference.getJavaClassDescription().getName(), reference );
+                if ( isInspectedClass ) {
+                    iLog.addError("Duplicate definition for reference " + refName + " in class "
+                        + current.getDescribedClass().getName(), current.getSource() );
                 }
-            }
-            else
-            {
-                // ensure interface
-                final String type = this.getReferencedInterface(reference, isInspectedClass, refName);
-                references.put( refName, new Object[]
-                    { reference, type, (setName ? Boolean.TRUE : Boolean.FALSE) } );
+            } else {
+                allReferences.put(refName, newReference);
+                return true;
             }
         }
-        else
-        {
-            throw new SCRDescriptorException( "No name detectable for reference in class "
-                    + reference.getJavaClassDescription().getName(), reference );
-        }
-    }
-
-    protected String getReferencedInterface(final JavaTag reference,
-                                            final boolean isInspectedClass,
-                                            final String refName) throws SCRDescriptorException
-    {
-        String type = reference.getNamedParameter( Constants.REFERENCE_INTERFACE );
-        if ( StringUtils.isEmpty( type ) )
-        {
-            if ( reference.getField() != null )
-            {
-                type = reference.getField().getType();
-            }
-            else
-            {
-                throw new SCRDescriptorException( "Interface missing for reference " + (refName == null ? "" : refName) + " in class "
-                    + reference.getJavaClassDescription().getName(), reference );
-            }
-        }
-        else if ( isInspectedClass )
-        {
-            // check if the value points to a class/interface
-            // and search through the imports
-            final JavaClassDescription serviceClass = reference.getJavaClassDescription().getReferencedClass(
-                type );
-            if ( serviceClass == null )
-            {
-                throw new SCRDescriptorException( "Interface '" + type + "' in class "
-                    + reference.getJavaClassDescription().getName()
-                    + " does not point to a valid class/interface.", reference );
-            }
-            type = serviceClass.getName();
-        }
-        return type;
-    }
-
-    protected String getReferenceName( final JavaTag reference,
-            final String defaultName) throws SCRDescriptorException
-    {
-        String name = reference.getNamedParameter( Constants.REFERENCE_NAME );
-        if ( !StringUtils.isEmpty( name ) )
-        {
-            return name;
-        }
-        name = reference.getNamedParameter( Constants.REFERENCE_NAME_REF );
-        if ( !StringUtils.isEmpty( name ) )
-        {
-            final JavaField refField = this.getReferencedField( reference, name );
-            final String[] values = refField.getInitializationExpression();
-            if ( values == null || values.length == 0 )
-            {
-                throw new SCRDescriptorException( "Referenced field for " + name
-                    + " has no values for a reference name.", reference );
-            }
-            if ( values.length > 1 )
-            {
-                throw new SCRDescriptorException( "Referenced field " + name
-                    + " has more than one value for a reference name.", reference );
-            }
-            return values[0];
-        }
-
-        return defaultName;
-    }
-
-
-    protected JavaField getReferencedField( final JavaTag tag, String ref ) throws SCRDescriptorException
-    {
-        int classSep = ref.lastIndexOf( '.' );
-        JavaField field = null;
-        if ( classSep == -1 )
-        {
-            // local variable
-            field = tag.getJavaClassDescription().getFieldByName( ref );
-        }
-        if ( field == null )
-        {
-            field = tag.getJavaClassDescription().getExternalFieldByName( ref );
-        }
-        if ( field == null )
-        {
-            throw new SCRDescriptorException( "Reference references unknown field " + ref + " in class "
-                + tag.getJavaClassDescription().getName(), tag );
-        }
-        return field;
-    }
-
-
-    /**
-     * Process a reference
-     * @param reference
-     * @param defaultName
-     * @param component
-     */
-    protected void doReference( JavaTag reference, String name, Component component, String type,
-            final boolean setName)
-        throws SCRDescriptorException
-    {
-        final Reference ref = new Reference( reference, component.getJavaClassDescription() );
-        if ( setName )
-        {
-            ref.setName( name );
-        }
-        ref.setInterfacename( type );
-        ref.setCardinality( reference.getNamedParameter( Constants.REFERENCE_CARDINALITY ) );
-        if ( ref.getCardinality() == null )
-        {
-            ref.setCardinality( "1..1" );
-        }
-        ref.setPolicy( reference.getNamedParameter( Constants.REFERENCE_POLICY ) );
-        if ( ref.getPolicy() == null )
-        {
-            ref.setPolicy( "static" );
-        }
-        ref.setTarget( reference.getNamedParameter( Constants.REFERENCE_TARGET ) );
-        final String bindValue = reference.getNamedParameter( Constants.REFERENCE_BIND );
-        if ( bindValue != null )
-        {
-            ref.setBind( bindValue );
-        }
-        final String unbindValue = reference.getNamedParameter( Constants.REFERENCE_UNDBIND );
-        if ( unbindValue != null )
-        {
-            ref.setUnbind( unbindValue );
-        }
-        final String updatedValue = reference.getNamedParameter( Constants.REFERENCE_UPDATED );
-        if ( updatedValue != null )
-        {
-            ref.setUpdated( updatedValue );
-        }
-        final String isChecked = reference.getNamedParameter( Constants.REFERENCE_CHECKED );
-        if ( isChecked != null )
-        {
-            ref.setChecked( Boolean.valueOf( isChecked ).booleanValue() );
-        }
-        final String strategy = reference.getNamedParameter( Constants.REFERENCE_STRATEGY );
-        if ( strategy != null )
-        {
-            ref.setStrategy( strategy );
-        }
-
-        component.addReference( ref );
-    }
-
-
-    public static boolean getBoolean( JavaTag tag, String name, boolean defaultValue )
-    {
-        String value = tag.getNamedParameter( name );
-        return ( value == null ) ? defaultValue : Boolean.valueOf( value ).booleanValue();
-    }
-
-
-
-    /**
-     * Converts the specification version string to a specification version
-     * code. Currently the following conversions are supported:
-     * <table>
-     * <tr><td><code>null</code></td><td>0</td></tr>
-     * <tr><td>1.0</td><td>0</td></tr>
-     * <tr><td>1.1</td><td>1</td></tr>
-     * <tr><td>1.1-felix</td><td>2</td></tr>
-     * </table>
-     *
-     * @param specVersion The specification version to convert. This may be
-     *      <code>null</code> to assume the default version.
-     *
-     * @return The specification version code.
-     *
-     * @throws SCRDescriptorException if the <code>specVersion</code> parameter
-     *      is not a supported value.
-     */
-    private int toSpecVersionCode( String specVersion, JavaTag tag ) throws SCRDescriptorException
-    {
-        if ( specVersion == null || specVersion.equals( Constants.COMPONENT_DS_SPEC_VERSION_10 ) )
-        {
-            return Constants.VERSION_1_0;
-        }
-        else if ( specVersion.equals( Constants.COMPONENT_DS_SPEC_VERSION_11 ) )
-        {
-            return Constants.VERSION_1_1;
-        }
-        else if ( specVersion.equals( Constants.COMPONENT_DS_SPEC_VERSION_11_FELIX ) )
-        {
-            return Constants.VERSION_1_1_FELIX;
-        }
-
-        // unknown specVersion string
-        throw new SCRDescriptorException( "Unsupported or unknown DS spec version: " + specVersion, tag );
+        return false;
     }
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/AbstractDescription.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/AbstractDescription.java
new file mode 100644
index 0000000..7854d20
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/AbstractDescription.java
@@ -0,0 +1,52 @@
+/*
+ * 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.scrplugin.description;
+
+import org.apache.felix.scrplugin.scanner.ScannedAnnotation;
+
+
+/**
+ * <code>AbstractDescription</code> is the base class for all descriptions.
+ *
+ * @see ComponentDescription
+ * @see ServiceDescription
+ * @see ReferenceDescription
+ * @see PropertyDescription
+ */
+public abstract class AbstractDescription {
+
+    /** The corresponding annotation from the class file. */
+    protected final ScannedAnnotation annotation;
+
+    /**
+     * Create a new abstract description
+     * @param annotation The corresponding annotation.
+     */
+    public AbstractDescription(final ScannedAnnotation annotation) {
+        this.annotation = annotation;
+    }
+
+    /**
+     * Get the annotation.
+     * @return The annotation or <code>null</code>
+     */
+    public ScannedAnnotation getAnnotation() {
+        return this.annotation;
+    }
+}
\ No newline at end of file
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ClassDescription.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ClassDescription.java
new file mode 100644
index 0000000..2d1f70f
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ClassDescription.java
@@ -0,0 +1,113 @@
+/*
+ * 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.scrplugin.description;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A <code>ClassDescription</code> is describing the found annotations
+ * of a class.
+ * Its basically used as a wrapper to hold all the various annotations
+ * found in a class. This description only contains the annotations
+ * found in the current class, but not in any superclass.
+ * The annotations are available as descriptions.
+ * @see ComponentDescription
+ * @see ServiceDescription
+ * @see ReferenceDescription
+ * @see PropertyDescription
+ */
+public class ClassDescription {
+
+    /** All descriptions. */
+    final List<AbstractDescription> descriptions = new ArrayList<AbstractDescription>();
+
+    /** The corresponding class. */
+    private final Class<?> describedClass;
+
+    /** The source (file) of the class or any other location information. */
+    private final String source;
+
+    /**
+     * Create a new class description
+     */
+    public ClassDescription(final Class<?> describedClass, final String source) {
+        this.describedClass = describedClass;
+        this.source = source;
+    }
+
+    /**
+     * Get the associated class.
+     * @return The associated class.
+     */
+    public Class<?> getDescribedClass() {
+        return this.describedClass;
+    }
+
+    /**
+     * Get the location information like the source file etc.
+     * @return The location information.
+     */
+    public String getSource() {
+        return this.source;
+    }
+
+    /**
+     * Add a new description
+     */
+    public void add(final AbstractDescription desc) {
+        this.descriptions.add(desc);
+    }
+
+    /**
+     * Get all descriptions of that type.
+     * @param descType The description class.
+     * @return A list of found descriptions or the empty array.
+     */
+    @SuppressWarnings("unchecked")
+    public <T extends AbstractDescription> List<T> getDescriptions(final Class<T> descType) {
+        final List<T> result = new ArrayList<T>();
+        for(final AbstractDescription desc : descriptions) {
+            if ( descType.isAssignableFrom(desc.getClass()) ) {
+                result.add((T) desc);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Get the first description of that type
+     * @param descType The description class
+     * @return THe first description or <code>null</code>
+     */
+    public <T extends AbstractDescription> T getDescription(final Class<T> descType) {
+        final List<T> result = this.getDescriptions(descType);
+        if ( result.size() > 0 ) {
+            return result.get(0);
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return "ClassDescription [descriptions=" + descriptions
+                        + ", describedClass=" + describedClass + ", source=" + source
+                        + "]";
+    }
+}
\ No newline at end of file
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaParameter.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ComponentConfigurationPolicy.java
similarity index 61%
rename from scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaParameter.java
rename to scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ComponentConfigurationPolicy.java
index daa2427..271d1f4 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaParameter.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ComponentConfigurationPolicy.java
@@ -16,26 +16,26 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.scrplugin.tags.cl;
-
-import org.apache.felix.scrplugin.tags.JavaParameter;
+package org.apache.felix.scrplugin.description;
 
 /**
- * <code>ClassLoaderJavaParameter.java</code>...
- *
+ * Options for {@link ComponentDescription#getConfigurationPolicy()}.
  */
-public class ClassLoaderJavaParameter implements JavaParameter {
-
-    protected final String type;
-
-    public ClassLoaderJavaParameter(String t) {
-        this.type = t;
-    }
+public enum ComponentConfigurationPolicy {
 
     /**
-     * @see org.apache.felix.scrplugin.tags.JavaParameter#getType()
+     * If a configuration is available it will be used, if not the component
+     * will be activated anyway (this is the default).
      */
-    public String getType() {
-        return this.type;
-    }
+    OPTIONAL,
+
+    /**
+     * The configuration admin is not consulted for a configuration for this component.
+     */
+    IGNORE,
+
+    /**
+     * In order to activate this component a configuration is required.
+     */
+    REQUIRE;
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ComponentDescription.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ComponentDescription.java
new file mode 100644
index 0000000..b7a67a8
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ComponentDescription.java
@@ -0,0 +1,260 @@
+/*
+ * 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.scrplugin.description;
+
+import org.apache.felix.scrplugin.scanner.ScannedAnnotation;
+
+/**
+ * <code>ComponentDescription</code> is a described component.
+ *
+ * In general all fields should be set by an annocation scanner,
+ * no default values should be assumed for these fields:
+ * <ul>
+ * <li>name</li>
+ * <li>configurationPolicy</li>
+ * </ul>
+ *
+ * These values have the following default values:
+ * <ul>
+ * <li>label : null - will be handled by the scr generator</li>
+ * <li>description : null - will be handled by the scr generator</li>
+ * <li>isAbstract : false</li>
+ * <li>isInherit : true</li>
+ * <li>createDs : true</li>
+ * <li>createPid : true</li>
+ * <li>createMetatype : false</li>
+ * <li>enabled : null</li>
+ * <li>immediate : null</li>
+ * <li>factory : null</li>
+ * <li>isSetMetatypeFactoryPid : false</li>
+ * <li>activate : null</li>
+ * <li>deactivate : null</li>
+ * <li>modified : null</li>
+ * <li>specVersion : null</li>
+ * </ul>
+ *
+ */
+public class ComponentDescription extends AbstractDescription {
+
+    /** The name of the component. */
+    private String name;
+
+    /** The label of the component. */
+    private String label;
+
+    /** The description of the component. */
+    private String description;
+
+    /** Configuration policy. (V1.1) */
+    private ComponentConfigurationPolicy configurationPolicy;
+
+    /** Is this an abstract description? */
+    private boolean isAbstract = false;
+
+    /** Does this inherit? */
+    private boolean isInherit = true;
+
+    /** Create ds info */
+    private boolean createDs = true;
+
+    /** Create pid */
+    private boolean createPid = true;
+
+    /** Create metatype info. */
+    private boolean createMetatype = false;
+
+    /** Is this component enabled? */
+    private Boolean enabled;
+
+    /** Is this component immediately started. */
+    private Boolean immediate;
+
+    /** The factory. */
+    private String factory;
+
+    /** The set metatype factory pid flag. */
+    private boolean isSetMetatypeFactoryPid = false;
+
+    /** Activation method. (V1.1) */
+    private MethodDescription activate;
+
+    /** Deactivation method. (V1.1) */
+    private MethodDescription deactivate;
+
+    /** Modified method. (V1.1) */
+    private MethodDescription modified;
+
+    /** The spec version. */
+    private SpecVersion specVersion;
+
+    public ComponentDescription(final ScannedAnnotation annotation) {
+        super(annotation);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public void setLabel(String label) {
+        this.label = label;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Boolean getEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(Boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public Boolean getImmediate() {
+        return immediate;
+    }
+
+    public void setImmediate(Boolean immediate) {
+        this.immediate = immediate;
+    }
+
+    public String getFactory() {
+        return factory;
+    }
+
+    public void setFactory(String factory) {
+        this.factory = factory;
+    }
+
+    public boolean isSetMetatypeFactoryPid() {
+        return isSetMetatypeFactoryPid;
+    }
+
+    public void setSetMetatypeFactoryPid(boolean isSetMetatypeFactoryPid) {
+        this.isSetMetatypeFactoryPid = isSetMetatypeFactoryPid;
+    }
+
+    public boolean isAbstract() {
+        return isAbstract;
+    }
+
+    public void setAbstract(boolean isAbstract) {
+        this.isAbstract = isAbstract;
+    }
+
+    public boolean isInherit() {
+        return isInherit;
+    }
+
+    public void setInherit(boolean isInherit) {
+        this.isInherit = isInherit;
+    }
+
+    public boolean isCreateDs() {
+        return createDs;
+    }
+
+    public void setCreateDs(boolean createDs) {
+        this.createDs = createDs;
+    }
+
+    public boolean isCreatePid() {
+        return createPid;
+    }
+
+    public void setCreatePid(boolean createPid) {
+        this.createPid = createPid;
+    }
+
+    public boolean isCreateMetatype() {
+        return createMetatype;
+    }
+
+    public void setCreateMetatype(boolean createMetatype) {
+        this.createMetatype = createMetatype;
+    }
+
+    public ComponentConfigurationPolicy getConfigurationPolicy() {
+        return configurationPolicy;
+    }
+
+    public void setConfigurationPolicy(ComponentConfigurationPolicy configurationPolicy) {
+        this.configurationPolicy = configurationPolicy;
+    }
+
+    public MethodDescription getActivate() {
+        return activate;
+    }
+
+    public void setActivate(MethodDescription activate) {
+        this.activate = activate;
+    }
+
+    public MethodDescription getDeactivate() {
+        return deactivate;
+    }
+
+    public void setDeactivate(MethodDescription deactivate) {
+        this.deactivate = deactivate;
+    }
+
+    public MethodDescription getModified() {
+        return modified;
+    }
+
+    public void setModified(MethodDescription modified) {
+        this.modified = modified;
+    }
+
+    public SpecVersion getSpecVersion() {
+        return specVersion;
+    }
+
+    public void setSpecVersion(SpecVersion specVersion) {
+        this.specVersion = specVersion;
+    }
+
+    @Override
+    public String toString() {
+        return "ComponentDescription [name=" + name + ", label=" + label
+                + ", description=" + description + ", enabled=" + enabled
+                + ", immediate=" + immediate + ", factory=" + factory
+                + ", isSetMetatypeFactoryPid=" + isSetMetatypeFactoryPid
+                + ", isAbstract=" + isAbstract + ", isInherit=" + isInherit
+                + ", createDs=" + createDs + ", createPid=" + createPid
+                + ", createMetatype=" + createMetatype
+                + ", configurationPolicy=" + configurationPolicy
+                + ", activate=" + activate + ", deactivate=" + deactivate
+                + ", modified=" + modified + ", specVersion=" + specVersion
+                + ", annotation=" + annotation + "]";
+    }
+}
\ No newline at end of file
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/MethodDescription.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/MethodDescription.java
new file mode 100644
index 0000000..fbffba8
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/MethodDescription.java
@@ -0,0 +1,55 @@
+/*
+ * 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.scrplugin.description;
+
+import java.lang.reflect.Method;
+
+/**
+ * A method description describes a reference to a method,
+ * this can either just be the name or a real method object.
+ */
+public class MethodDescription {
+
+    private final String name;
+
+    private final Method method;
+
+    public MethodDescription(final String name) {
+        this.name = name;
+        this.method = null;
+    }
+
+    public MethodDescription(final Method method) {
+        this.name = method.getName();
+        this.method = method;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public Method getMethod() {
+        return this.method;
+    }
+
+    @Override
+    public String toString() {
+        return "MethodDescription [name=" + name + ", method=" + method + "]";
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/PropertyDescription.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/PropertyDescription.java
new file mode 100644
index 0000000..9b6ecee
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/PropertyDescription.java
@@ -0,0 +1,159 @@
+/*
+ * 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.scrplugin.description;
+
+import java.util.Arrays;
+
+import org.apache.felix.scrplugin.scanner.ScannedAnnotation;
+
+
+/**
+ * A <code>PropertyDescription</code> describes a property
+ * of a component.
+ *
+ * In general all fields should be set by an annocation scanner,
+ * no default values should be assumed for these fields:
+ * <ul>
+ * <li>name</li>
+ * <li>value</li>
+ * <li>multiValue</li>
+ * <li>type</li>
+ * <li>unbounded</li>
+ * <li>cardinality</li>
+ * </ul>
+ *
+ * These values have the following default values:
+ * <ul>
+ * <li>label : null - will be handled by the scr generator</li>
+ * <li>description : null - will be handled by the scr generator</li>
+ * <li>isPrivate : null - will be be handled by the scr generator</li>
+ * <li>options : null</li>
+ * </ul>
+ *
+ */
+public class PropertyDescription extends AbstractDescription {
+
+    private String name;
+    private String value;
+    private PropertyType type;
+    private String[] multiValue;
+    private PropertyUnbounded unbounded;
+    private int cardinality;
+
+    private Boolean isPrivate;
+    private String label;
+    private String description;
+    private String[] options;
+
+    public PropertyDescription(final ScannedAnnotation annotation) {
+        super(annotation);
+    }
+
+    public PropertyUnbounded getUnbounded() {
+        return unbounded;
+    }
+
+    public void setUnbounded(PropertyUnbounded unbounded) {
+        this.unbounded = unbounded;
+    }
+
+    public String[] getOptions() {
+        return options;
+    }
+
+    public void setOptions(String[] values) {
+        this.options = values;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+        this.multiValue = null;
+    }
+
+    public PropertyType getType() {
+        return this.type;
+    }
+
+    public void setType(PropertyType type) {
+        this.type = type;
+    }
+
+    public String[] getMultiValue() {
+        return this.multiValue;
+    }
+
+    public void setMultiValue(String[] values) {
+        this.multiValue = values;
+        this.value = null;
+    }
+    public Boolean isPrivate() {
+        return isPrivate;
+    }
+
+    public void setPrivate(Boolean isPrivate) {
+        this.isPrivate = isPrivate;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public void setLabel(String label) {
+        this.label = label;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public int getCardinality() {
+        return cardinality;
+    }
+
+    public void setCardinality(int cardinality) {
+        this.cardinality = cardinality;
+    }
+
+    @Override
+    public String toString() {
+        return "PropertyDescription [name=" + name + ", value=" + value
+                + ", type=" + type + ", multiValue="
+                + Arrays.toString(multiValue) + ", isPrivate=" + isPrivate
+                + ", label=" + label + ", description=" + description
+                + ", cardinality=" + cardinality + ", unbounded=" + unbounded
+                + ", options=" + Arrays.toString(options) + ", annotation=" + annotation + "]";
+    }
+
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/PropertyType.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/PropertyType.java
new file mode 100644
index 0000000..5aca421
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/PropertyType.java
@@ -0,0 +1,62 @@
+/*
+ * 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.scrplugin.description;
+
+public enum PropertyType {
+
+    String,
+    Long,
+    Double,
+    Float,
+    Integer,
+    Byte,
+    Char,
+    Character,
+    Boolean,
+    Short;
+
+    public static PropertyType from(final Class<?> javaClass) {
+        if ( javaClass.getName().equals(Long.class.getName())) {
+            return PropertyType.Long;
+        }
+        if ( javaClass.getName().equals(Double.class.getName())) {
+            return PropertyType.Double;
+        }
+        if ( javaClass.getName().equals(Float.class.getName())) {
+            return PropertyType.Float;
+        }
+        if ( javaClass.getName().equals(Integer.class.getName())) {
+            return PropertyType.Integer;
+        }
+        if ( javaClass.getName().equals(Byte.class.getName())) {
+            return PropertyType.Byte;
+        }
+        if ( javaClass.getName().equals(Character.class.getName())) {
+            return PropertyType.Character;
+        }
+        if ( javaClass.getName().equals(Boolean.class.getName())) {
+            return PropertyType.Boolean;
+        }
+        if ( javaClass.getName().equals(Short.class.getName())) {
+            return PropertyType.Short;
+        }
+        // default
+        return PropertyType.String;
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/package-info.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/PropertyUnbounded.java
similarity index 71%
copy from scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/package-info.java
copy to scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/PropertyUnbounded.java
index a00ab18..f73ae8c 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/package-info.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/PropertyUnbounded.java
@@ -16,8 +16,19 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * Extracting SCR tags from source file declared as Java 1.5 annotations.   
- */
-package org.apache.felix.scrplugin.tags.annotation;
+package org.apache.felix.scrplugin.description;
 
+/**
+ * Options for {@link PropertyDescription#getUnbounded()}
+ */
+public enum PropertyUnbounded {
+
+    /** Property is not unbounded. This is the default. */
+    DEFAULT,
+
+    /** Property is an unbounded array. */
+    ARRAY,
+
+    /** Property is an unbounded vector. */
+    VECTOR
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ReferenceCardinality.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ReferenceCardinality.java
new file mode 100644
index 0000000..0f102ed
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ReferenceCardinality.java
@@ -0,0 +1,75 @@
+/*
+ * 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.scrplugin.description;
+
+/**
+ * Options for {@link ReferenceDescription#getCardinality()}
+ */
+public enum ReferenceCardinality {
+
+    /**
+     * Optional, unary reference: No service required to be available for the
+     * refernce to be satisfied. Only a single service is available through this
+     * reference.
+     */
+    OPTIONAL_UNARY("0..1"),
+
+    /**
+     * Mandatory, unary reference: At least one service must be available for
+     * the reference to be satisfied. Only a single service is available through
+     * this reference.
+     */
+    MANDATORY_UNARY("1..1"),
+
+    /**
+     * Optional, multiple reference: No service required to be available for the
+     * refernce to be satisfied. All matching services are available through
+     * this reference.
+     */
+    OPTIONAL_MULTIPLE("0..n"),
+
+    /**
+     * Mandatory, multiple reference: At least one service must be available for
+     * the reference to be satisified. All matching services are available
+     * through this reference.
+     */
+    MANDATORY_MULTIPLE("1..n");
+
+    private final String cardinalityString;
+
+    private ReferenceCardinality(final String cardinalityString) {
+        this.cardinalityString = cardinalityString;
+    }
+
+    /**
+     * @return String representation of cardinality
+     */
+    public String getCardinalityString() {
+        return this.cardinalityString;
+    }
+
+    public static ReferenceCardinality fromValue(final String value) {
+        for(final ReferenceCardinality rd : ReferenceCardinality.values() ) {
+            if ( rd.getCardinalityString().equals(value) ) {
+                return rd;
+            }
+        }
+        return null;
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ReferenceDescription.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ReferenceDescription.java
new file mode 100644
index 0000000..b11e7de
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ReferenceDescription.java
@@ -0,0 +1,156 @@
+/*
+ * 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.scrplugin.description;
+
+import java.lang.reflect.Field;
+
+import org.apache.felix.scrplugin.scanner.ScannedAnnotation;
+
+/**
+ * A <code>ReferenceDescription</code> describes a reference
+ * from a component to another service.
+ *
+ * In general all fields should be set by an annocation scanner,
+ * no default values should be assumed for these fields:
+ * <ul>
+ * <li>name</li>
+ * <li>interfaceName</li>
+ * <li>target</li>
+ * <li>cardinality</li>
+ * <li>policy</li>
+ * <li>strategy</li>
+ * <li>field</li>
+ * </ul>
+ *
+ * These values have the following default values:
+ * <ul>
+ * <li>bind : null</li>
+ * <li>unbind : null</li>
+ * <li>updated : null</li>
+ * </ul>
+ */
+public class ReferenceDescription extends AbstractDescription {
+
+    private String name;
+    private String interfaceName;
+    private String target;
+    private ReferenceCardinality cardinality;
+    private ReferencePolicy policy;
+    private ReferenceStrategy strategy;
+
+    private Field field;
+
+    private MethodDescription bind;
+    private MethodDescription unbind;
+    private MethodDescription updated;
+
+    public ReferenceDescription(final ScannedAnnotation annotation) {
+        super(annotation);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getInterfaceName() {
+        return interfaceName;
+    }
+
+    public void setInterfaceName(String interfacename) {
+        this.interfaceName = interfacename;
+    }
+
+    public String getTarget() {
+        return target;
+    }
+
+    public void setTarget(String target) {
+        this.target = target;
+    }
+
+    public ReferenceCardinality getCardinality() {
+        return cardinality;
+    }
+
+    public void setCardinality(ReferenceCardinality cardinality) {
+        this.cardinality = cardinality;
+    }
+
+    public ReferencePolicy getPolicy() {
+        return policy;
+    }
+
+    public void setPolicy(ReferencePolicy policy) {
+        this.policy = policy;
+    }
+
+    public MethodDescription getBind() {
+        return bind;
+    }
+
+    public void setBind(MethodDescription bind) {
+        this.bind = bind;
+    }
+
+    public MethodDescription getUnbind() {
+        return unbind;
+    }
+
+    public void setUnbind(MethodDescription unbind) {
+        this.unbind = unbind;
+    }
+
+    public MethodDescription getUpdated() {
+        return updated;
+    }
+
+    public void setUpdated(MethodDescription updated) {
+        this.updated = updated;
+    }
+
+    public ReferenceStrategy getStrategy() {
+        return strategy;
+    }
+
+    public void setStrategy(ReferenceStrategy strategy) {
+        this.strategy = strategy;
+    }
+
+    @Override
+    public String toString() {
+        return "ReferenceDescription [name=" + name + ", interfaceName="
+                + interfaceName + ", target=" + target + ", cardinality="
+                + cardinality + ", policy=" + policy + ", bind=" + bind
+                + ", unbind=" + unbind + ", updated=" + updated + ", strategy="
+                + strategy + ", field=" + field + ", annotation=" + annotation
+                + "]";
+    }
+
+    public Field getField() {
+        return field;
+    }
+
+    public void setField(Field field) {
+        this.field = field;
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaMethod.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ReferencePolicy.java
similarity index 68%
copy from scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaMethod.java
copy to scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ReferencePolicy.java
index cf36076..a4429a4 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaMethod.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ReferencePolicy.java
@@ -16,23 +16,21 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.scrplugin.tags;
+package org.apache.felix.scrplugin.description;
 
 /**
- * <code>JavaMethod.java</code>...
- *
+ * Options for {@link ReferenceDescription#getPolicy()}
  */
-public interface JavaMethod {
+public enum ReferencePolicy {
 
-    JavaMethod[] EMPTY_RESULT = new JavaMethod[0];
+    /**
+     * The component will be deactivated and re-activated if the service comes
+     * and/or goes away.
+     */
+    STATIC,
 
-    boolean isPublic();
-
-    boolean isProtected();
-
-    String getName();
-
-    JavaParameter[] getParameters();
-
-    boolean isConstructor();
+    /**
+     * The service will be made available to the component as it comes and goes.
+     */
+    DYNAMIC;
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/package-info.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ReferenceStrategy.java
similarity index 82%
rename from scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/package-info.java
rename to scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ReferenceStrategy.java
index a00ab18..5a158e8 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/package-info.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ReferenceStrategy.java
@@ -16,8 +16,14 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * Extracting SCR tags from source file declared as Java 1.5 annotations.   
- */
-package org.apache.felix.scrplugin.tags.annotation;
+package org.apache.felix.scrplugin.description;
 
+/**
+ * Options for {@link ReferenceDescription#getStrategy()}
+ */
+public enum ReferenceStrategy {
+
+    EVENT,
+
+    LOOKUP;
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ServiceDescription.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ServiceDescription.java
new file mode 100644
index 0000000..7ee3647
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ServiceDescription.java
@@ -0,0 +1,71 @@
+/*
+ * 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.scrplugin.description;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.felix.scrplugin.scanner.ScannedAnnotation;
+
+/**
+ * If a component is a service, the {@link ClassDescription} should
+ * contain a <code>ServiceDescription</code>.
+ *
+ * The service description defines whether this is a service factory
+ * and which interfaces this service implements.
+ */
+public class ServiceDescription extends AbstractDescription {
+
+    /** Flag for service factory. */
+    private boolean isServiceFactory = false;
+
+    /** The list of implemented interfaces. */
+    protected final Set<String> interfaces = new HashSet<String>();
+
+    public ServiceDescription(final ScannedAnnotation annotation) {
+        super(annotation);
+    }
+
+    public boolean isServiceFactory() {
+        return this.isServiceFactory;
+    }
+
+    public void setServiceFactory(boolean flag) {
+        this.isServiceFactory = flag;
+    }
+
+    public Set<String> getInterfaces() {
+        return this.interfaces;
+    }
+
+    /**
+     * Add an interface to the list of interfaces.
+     * @param interf The interface.
+     */
+    public void addInterface(final String interf) {
+        this.interfaces.add(interf);
+    }
+
+    @Override
+    public String toString() {
+        return "ServiceDescription [isServiceFactory=" + isServiceFactory
+                + ", interfaces=" + interfaces + ", annotation=" + annotation
+                + "]";
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/SpecVersion.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/SpecVersion.java
new file mode 100644
index 0000000..1f0d11a
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/SpecVersion.java
@@ -0,0 +1,70 @@
+/*
+ * 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.scrplugin.description;
+
+
+public enum SpecVersion {
+
+    VERSION_1_0("1.0"),              // R4.1
+    VERSION_1_1("1.1"),              // R4.2
+    VERSION_1_1_FELIX("1.1_FELIX");  // R4.2 + FELIX-1893
+
+    /**
+     * internal human readable name
+     */
+    private final String name;
+
+    /**
+     * Create a type
+     *
+     * @param name name
+     */
+    private SpecVersion(final String name) {
+        this.name = name;
+    }
+
+    /**
+     * Returns the human readable type name of this type.
+     *
+     * @return the name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Creates a version for the given name. if the name cannot be mapped
+     * to a enum type or if it's <code>null</code>, <code>null</code> is
+     * returned.
+     *
+     * @param n the name
+     * @return the type or <code>null</code>
+     */
+    public static SpecVersion fromName(final String n) {
+        if (n == null) {
+            return null;
+        }
+        try {
+            return SpecVersion.valueOf(n.toUpperCase());
+        } catch (final IllegalArgumentException e) {
+            // ignore
+        }
+        for(final SpecVersion sv : SpecVersion.values() ) {
+            if ( sv.getName().equals(n)) {
+                return sv;
+            }
+        }
+        return null;
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/AnnotationProcessorManager.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/AnnotationProcessorManager.java
new file mode 100644
index 0000000..913d290
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/AnnotationProcessorManager.java
@@ -0,0 +1,150 @@
+/*
+ * 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.scrplugin.helper;
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.imageio.spi.ServiceRegistry;
+
+import org.apache.felix.scrplugin.AnnotationProcessor;
+import org.apache.felix.scrplugin.SCRDescriptorException;
+import org.apache.felix.scrplugin.SCRDescriptorFailureException;
+import org.apache.felix.scrplugin.description.ClassDescription;
+import org.apache.felix.scrplugin.scanner.ScannedClass;
+
+
+/**
+ * Supports mapping of built-in and custom java annotations to
+ * descriptions.
+ */
+public class AnnotationProcessorManager implements AnnotationProcessor {
+
+    /**
+     * Allows to define additional implementations of the interface
+     * {@linkAnnotationProcessor}
+     * that provide mappings from custom annotations to descriptions.
+     */
+    private final Map<String, AnnotationProcessor> processors = new HashMap<String, AnnotationProcessor>();
+
+    /**
+     * Ordered list of processors
+     */
+    private final List<AnnotationProcessor> cachedProcessors = new ArrayList<AnnotationProcessor>();
+
+    /**
+     * @param annotationProcessorClasses List of classes that implements
+     *            {@link AnnotationProcessor} interface.
+     * @throws SCRDescriptorFailureException
+     */
+    public AnnotationProcessorManager(
+            final String[] annotationProcessorClasses,
+            final ClassLoader classLoader )
+    throws SCRDescriptorFailureException {
+        // search for providers
+        final Iterator<AnnotationProcessor> serviceIter = ServiceRegistry.lookupProviders(AnnotationProcessor.class, classLoader);
+        while ( serviceIter.hasNext() ) {
+            final AnnotationProcessor provider = serviceIter.next();
+            this.addProvider(provider);
+        }
+
+        // add custom processors defined in the tool (maven, ant...)
+        for ( int i = 0; i < annotationProcessorClasses.length; i++ ) {
+            loadProcessor( classLoader, annotationProcessorClasses[i], false );
+        }
+
+        // always add processors supporting built-in SCR default properties (for compatibility with older
+        // annotation versions)
+        loadProcessor( classLoader,
+            "org.apache.felix.scrplugin.SCRAnnotationProcessor", true );
+        loadProcessor( classLoader,
+            "org.apache.felix.scrplugin.SlingAnnotationProcessor", true );
+
+        // create ordered list
+        for(final AnnotationProcessor pro : this.processors.values() ) {
+            this.cachedProcessors.add(pro);
+        }
+        Collections.sort(this.cachedProcessors, new Comparator<AnnotationProcessor>() {
+
+            public int compare(AnnotationProcessor o1, AnnotationProcessor o2) {
+                return Integer.valueOf(o1.getRanking()).compareTo(Integer.valueOf(o2.getRanking()));
+            }
+        });
+    }
+
+    /**
+     * @see org.apache.felix.scrplugin.AnnotationProcessor#process(org.apache.felix.scrplugin.scanner.ScannedClass, org.apache.felix.scrplugin.description.ClassDescription)
+     */
+    public void process(final ScannedClass scannedClass,
+            final ClassDescription describedClass)
+    throws SCRDescriptorException, SCRDescriptorFailureException {
+        for(final AnnotationProcessor ap : this.cachedProcessors) {
+            ap.process(scannedClass, describedClass);
+        }
+    }
+
+    /**
+     * @see org.apache.felix.scrplugin.AnnotationProcessor#getRanking()
+     */
+    public int getRanking() {
+        return 0;
+    }
+
+    /**
+     * Add a processor (if not already available)
+     */
+    private void addProvider(final AnnotationProcessor processor) {
+        // check if this processor is already loaded
+        final String key = processor.getClass().getName();
+        if ( !this.processors.containsKey(key) ) {
+            this.processors.put(key, processor);
+        }
+    }
+
+    private void loadProcessor( final ClassLoader classLoader, final String className, final boolean silent )
+    throws SCRDescriptorFailureException {
+        String failureMessage = null;
+        try {
+            Class<?> clazz = classLoader.loadClass( className );
+            try {
+                addProvider( ( AnnotationProcessor ) clazz.newInstance() );
+            } catch ( final ClassCastException e ) {
+                failureMessage = "Class '" + clazz.getName() + "' " + "does not implement interface '"
+                    + AnnotationProcessor.class.getName() + "'.";
+            } catch ( final InstantiationException e ) {
+                failureMessage = "Unable to instantiate class '" + clazz.getName() + "': " + e.getMessage();
+            } catch ( final IllegalAccessException e ) {
+                failureMessage = "Illegal access to class '" + clazz.getName() + "': " + e.getMessage();
+            }
+        } catch ( final ClassNotFoundException e ) {
+            failureMessage = "Annotation provider class '" + className + "' not found.";
+        }
+
+        // throw an optional exception if not required to remaing silent
+        if ( failureMessage != null && !silent ) {
+            throw new SCRDescriptorFailureException( failureMessage );
+        }
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ClassModifier.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ClassModifier.java
new file mode 100644
index 0000000..aedb87c
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ClassModifier.java
@@ -0,0 +1,98 @@
+package org.apache.felix.scrplugin.helper;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import org.apache.felix.scrplugin.SCRDescriptorException;
+import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.ClassNode;
+
+public class ClassModifier {
+
+    public static void addMethods(final String className,
+                           final String referenceName,
+                           final String fieldName,
+                           final String typeName,
+                           final boolean createBind,
+                           final boolean createUnbind,
+                           final String outputDirectory)
+    throws SCRDescriptorException {
+        // now do byte code manipulation
+        final String fileName = outputDirectory + File.separatorChar +  className.replace('.', File.separatorChar) + ".class";
+        final ClassNode cn = new ClassNode();
+        try {
+            final ClassReader reader = new ClassReader(new FileInputStream(fileName));
+            reader.accept(cn, 0);
+
+            final ClassWriter writer = new ClassWriter(0);
+
+            // remove existing implementation von previous builds
+            final ClassAdapter adapter = new ClassAdapter(writer) {
+
+                protected final String bindMethodName = "bind" + referenceName.substring(0, 1).toUpperCase() + referenceName.substring(1);
+                protected final String unbindMethodName = "unbind" + referenceName.substring(0, 1).toUpperCase() + referenceName.substring(1);
+                protected final String description = "(L" + typeName.replace('.', '/') + ";)V";
+
+                /**
+                 * @see org.objectweb.asm.ClassAdapter#visitMethod(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
+                 */
+                public MethodVisitor visitMethod(final int access,
+                                final String name,
+                                final String desc,
+                                final String signature,
+                                final String[] exceptions) {
+                    if ( createBind && name.equals(bindMethodName) && description.equals(desc) ) {
+                        return null;
+                    }
+                    if ( createUnbind && name.equals(unbindMethodName)  && description.equals(desc) ) {
+                        return null;
+                    }
+                    return super.visitMethod(access, name, desc, signature, exceptions);
+                }
+
+            };
+
+            cn.accept(adapter);
+            if ( createBind ) {
+                createMethod(writer, className, referenceName, fieldName, typeName, true);
+            }
+            if ( createUnbind ) {
+                createMethod(writer, className, referenceName, fieldName, typeName, false);
+            }
+
+            final FileOutputStream fos = new FileOutputStream(fileName);
+            fos.write(writer.toByteArray());
+            fos.close();
+        } catch (final Exception e) {
+            throw new SCRDescriptorException("Unable to add methods to " + className, typeName, 0, e);
+        }
+    }
+
+    private static void createMethod(final ClassWriter cw, final String className, final String referenceName, final String fieldName, final String typeName, boolean bind) {
+        final org.objectweb.asm.Type type = org.objectweb.asm.Type.getType("L" + typeName.replace('.', '/') + ";");
+        final String methodName = (bind ? "" : "un") + "bind" + referenceName.substring(0, 1).toUpperCase() + referenceName.substring(1);
+        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PROTECTED, methodName, "(" + type.toString() + ")V", null, null);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        if ( bind ) {
+            mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), 1);
+            mv.visitFieldInsn(Opcodes.PUTFIELD, className.replace('.', '/'), fieldName, type.toString());
+        } else {
+            mv.visitFieldInsn(Opcodes.GETFIELD, className.replace('.', '/'), fieldName, type.toString());
+            mv.visitVarInsn(Opcodes.ALOAD, 1);
+            final Label jmpLabel = new Label();
+            mv.visitJumpInsn(Opcodes.IF_ACMPNE, jmpLabel);
+            mv.visitVarInsn(Opcodes.ALOAD, 0);
+            mv.visitInsn(Opcodes.ACONST_NULL);
+            mv.visitFieldInsn(Opcodes.PUTFIELD, className.replace('.', '/'), fieldName, type.toString());
+            mv.visitLabel(jmpLabel);
+        }
+        mv.visitInsn(Opcodes.RETURN);
+        mv.visitMaxs(2, 2);
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ClassScanner.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ClassScanner.java
new file mode 100644
index 0000000..fb62805
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ClassScanner.java
@@ -0,0 +1,597 @@
+/*
+ * 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.scrplugin.helper;
+
+import static org.objectweb.asm.ClassReader.SKIP_CODE;
+import static org.objectweb.asm.ClassReader.SKIP_DEBUG;
+import static org.objectweb.asm.ClassReader.SKIP_FRAMES;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import org.apache.felix.scrplugin.AnnotationProcessor;
+import org.apache.felix.scrplugin.Log;
+import org.apache.felix.scrplugin.Project;
+import org.apache.felix.scrplugin.SCRDescriptorException;
+import org.apache.felix.scrplugin.SCRDescriptorFailureException;
+import org.apache.felix.scrplugin.description.ClassDescription;
+import org.apache.felix.scrplugin.description.ComponentDescription;
+import org.apache.felix.scrplugin.scanner.ClassAnnotation;
+import org.apache.felix.scrplugin.scanner.FieldAnnotation;
+import org.apache.felix.scrplugin.scanner.MethodAnnotation;
+import org.apache.felix.scrplugin.scanner.ScannedAnnotation;
+import org.apache.felix.scrplugin.scanner.ScannedClass;
+import org.apache.felix.scrplugin.scanner.Source;
+import org.apache.felix.scrplugin.xml.ComponentDescriptorIO;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AnnotationNode;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.FieldNode;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * The class scanner scans class files for annotations and invokes
+ * the {@link AnnotationProcessor} on each scanned class file.
+ */
+public class ClassScanner {
+
+    /**
+     * The name of the Bundle manifest header providing the list of service
+     * component descriptor files.
+     */
+    private static final String SERVICE_COMPONENT = "Service-Component";
+
+    /**
+     * The name of the file containing the scanned information from older
+     * SCR generator versions.
+     */
+    private static final String ABSTRACT_DESCRIPTOR_ARCHIV_PATH = "OSGI-INF/scr-plugin/scrinfo.xml";
+
+    /** Source for all generated descriptions. */
+    private static final String GENERATED = "<generated>";
+
+    /** Component descriptions loaded from dependencies*/
+    private Map<String, ClassDescription> loadedDependencies;
+
+    /** All used component descriptions. */
+    private final Map<String, ClassDescription> allDescriptions;
+
+    /** The log. */
+    private final Log log;
+
+    /** The issue log. */
+    private final IssueLog iLog;
+
+    /** The project. */
+    private final Project project;
+
+    /** The annotation processor. */
+    private final AnnotationProcessor aProcessor;
+
+    /**
+     * Create a new scanner.
+     */
+    public ClassScanner(final Log log,
+                    final IssueLog iLog,
+                    final Project project,
+                    final AnnotationProcessor aProcessor) {
+        // create map for all descriptions and dummy entry for Object
+        this.allDescriptions = new HashMap<String, ClassDescription>();
+        allDescriptions.put(Object.class.getName(), new ClassDescription(Object.class, GENERATED));
+        this.log = log;
+        this.iLog = iLog;
+        this.project = project;
+        this.aProcessor = aProcessor;
+    }
+
+    /**
+     * Scan all source class files for annotations and process them.
+     */
+    public List<ClassDescription> scanSources()
+    throws SCRDescriptorException, SCRDescriptorFailureException {
+        final List<ClassDescription> result = new ArrayList<ClassDescription>();
+
+        for (final Source src : project.getSources()) {
+            log.debug("Scanning class " + src.getClassName());
+
+            try {
+                // load the class
+                final Class<?> annotatedClass = project.getClassLoader().loadClass(src.getClassName());
+
+                final ClassDescription desc = this.processClass(annotatedClass, src.getFile().toString());
+                if (desc != null) {
+                    result.add(desc);
+                    this.allDescriptions.put(annotatedClass.getName(), desc);
+                } else {
+                    this.allDescriptions.put(annotatedClass.getName(), new ClassDescription(annotatedClass, GENERATED));
+                }
+            } catch (final ClassNotFoundException cnfe) {
+                throw new SCRDescriptorFailureException("Unable to load compiled class: " + src.getClassName(), cnfe);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Scan a single class.
+     */
+    private ClassDescription processClass(final Class<?> annotatedClass, final String location)
+    throws SCRDescriptorFailureException, SCRDescriptorException {
+        try {
+            // get the class file for ASM
+            final String pathToClassFile = annotatedClass.getName().replace('.', '/') + ".class";
+            final InputStream input = project.getClassLoader().getResourceAsStream(pathToClassFile);
+            final ClassReader classReader;
+            try {
+                classReader = new ClassReader(input);
+            } finally {
+                input.close();
+            }
+            final ClassNode classNode = new ClassNode();
+            classReader.accept(classNode, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
+
+            // create descriptions
+            final List<ScannedAnnotation> descriptions = extractAnnotation(classNode, annotatedClass);
+            if (descriptions.size() > 0) {
+                // process descriptions
+                final ClassDescription desc = new ClassDescription(annotatedClass, location);
+                aProcessor.process(new ScannedClass(descriptions, annotatedClass), desc);
+
+                if (desc.getDescriptions(ComponentDescription.class).size() > 0) {
+                    log.debug("Found component description " + desc + " in " + annotatedClass.getName());
+                    return desc;
+                }
+            }
+        } catch (final IOException ioe) {
+            throw new SCRDescriptorFailureException("Unable to scan class files: " + annotatedClass.getName(), ioe);
+        }
+        return null;
+    }
+
+    /**
+     * Extract annotations
+     */
+    private final List<ScannedAnnotation> extractAnnotation(final ClassNode classNode, final Class<?> annotatedClass)
+                    throws SCRDescriptorException {
+        final List<ScannedAnnotation> descriptions = new ArrayList<ScannedAnnotation>();
+        // first parse class annotations
+        @SuppressWarnings("unchecked")
+        final List<AnnotationNode> annotations = classNode.invisibleAnnotations;
+        if (annotations != null) {
+            for (final AnnotationNode annotation : annotations) {
+                this.parseAnnotation(descriptions, annotation, annotatedClass);
+            }
+
+            // second parse method annotations
+            @SuppressWarnings("unchecked")
+            final List<MethodNode> methods = classNode.methods;
+            if (methods != null) {
+                for (final MethodNode method : methods) {
+                    @SuppressWarnings("unchecked")
+                    final List<AnnotationNode> annos = method.invisibleAnnotations;
+                    if (annos != null) {
+                        final String name = method.name;
+                        String signature = method.signature;
+                        if (signature != null) {
+                            // remove generics
+                            int pos;
+                            while ((pos = signature.indexOf('<')) > 0) {
+                                final int lastPos = signature.indexOf('>');
+                                signature = signature.substring(0, pos) + signature.substring(lastPos + 1);
+                            }
+                            // remove everthing after the brackets and replace slash with dot
+                            pos = signature.lastIndexOf(')');
+                            signature = signature.substring(0, pos + 1);
+                            signature = signature.replace('/', '.');
+                        }
+                        final Method[] allMethods = annotatedClass.getDeclaredMethods();
+                        Method found = null;
+                        for (final Method m : allMethods) {
+                            if (m.getName().equals(name)) {
+                                if (m.getParameterTypes().length == 0 && signature == null) {
+                                    found = m;
+                                }
+                                if (m.getParameterTypes().length > 0 && signature != null) {
+                                    final StringBuilder sb = new StringBuilder("(");
+                                    for (final Class<?> c : m.getParameterTypes()) {
+                                        sb.append("L");
+                                        sb.append(c.getName());
+                                        sb.append(";");
+                                    }
+                                    sb.append(")");
+                                    if (sb.toString().equals(signature)) {
+                                        found = m;
+                                    }
+                                }
+                            }
+                        }
+                        if (found == null) {
+                            throw new SCRDescriptorException("Annotated method " + name + " not found.",
+                                            annotatedClass.getName(), -1);
+                        }
+                        for (final AnnotationNode annotation : annos) {
+                            parseAnnotation(descriptions, annotation, found);
+                        }
+                    }
+                }
+            }
+
+            // third parse field annotations
+            @SuppressWarnings("unchecked")
+            final List<FieldNode> fields = classNode.fields;
+            if (fields != null) {
+                for (final FieldNode field : fields) {
+                    @SuppressWarnings("unchecked")
+                    final List<AnnotationNode> annos = field.invisibleAnnotations;
+                    if (annos != null) {
+                        final String name = field.name;
+                        final Field[] allFields = annotatedClass.getDeclaredFields();
+                        Field found = null;
+                        for (final Field f : allFields) {
+                            if (f.getName().equals(name)) {
+                                found = f;
+                            }
+                        }
+                        if (found == null) {
+                            throw new SCRDescriptorException("Annotated field " + name + " not found.",
+                                            annotatedClass.getName(), -1);
+                        }
+                        for (final AnnotationNode annotation : annos) {
+                            parseAnnotation(descriptions, annotation, found);
+                        }
+                    }
+                }
+            }
+        }
+        return descriptions;
+    }
+
+    private <T> T[] convertToArray(final List<?> values, final Class<T> type) {
+        @SuppressWarnings("unchecked")
+        final T[] result = (T[]) Array.newInstance(type, values.size());
+        return values.toArray(result);
+    }
+
+    /**
+     * Parse annotation and create a description.
+     */
+    private void parseAnnotation(final List<ScannedAnnotation> descriptions, final AnnotationNode annotation,
+                    final Object annotatedObject) {
+        // desc has the format 'L' + className.replace('.', '/') + ';'
+        final String name = annotation.desc.substring(1, annotation.desc.length() - 1).replace('/', '.');
+        Map<String, Object> values = null;
+        if (annotation.values != null) {
+            values = new HashMap<String, Object>();
+            final Iterator<?> i = annotation.values.iterator();
+            while (i.hasNext()) {
+                final Object vName = i.next();
+                Object value = i.next();
+
+                // convert type to class name string
+                if (value instanceof Type) {
+                    value = ((Type) value).getClassName();
+                } else if (value instanceof List<?>) {
+                    final List<?> objects = (List<?>) value;
+                    if (objects.size() > 0) {
+                        if (objects.get(0) instanceof Type) {
+                            final String[] classNames = new String[objects.size()];
+                            int index = 0;
+                            for (final Object v : objects) {
+                                classNames[index] = ((Type) v).getClassName();
+                                index++;
+                            }
+                            value = classNames;
+                        } else if (objects.get(0) instanceof AnnotationNode) {
+                            final List<ScannedAnnotation> innerDesc = new ArrayList<ScannedAnnotation>();
+                            for (final Object v : objects) {
+                                parseAnnotation(innerDesc, (AnnotationNode) v, annotatedObject);
+                            }
+                            if (annotatedObject instanceof Method) {
+                                value = innerDesc.toArray(new MethodAnnotation[innerDesc.size()]);
+                            } else if (annotatedObject instanceof Field) {
+                                value = innerDesc.toArray(new FieldAnnotation[innerDesc.size()]);
+                            } else {
+                                value = innerDesc.toArray(new ClassAnnotation[innerDesc.size()]);
+                            }
+                        } else {
+                            value = convertToArray(objects, objects.get(0).getClass());
+                        }
+                    } else {
+                        value = null;
+                    }
+                }
+
+                values.put(vName.toString(), value);
+            }
+        }
+
+        final ScannedAnnotation a;
+        if (annotatedObject instanceof Method) {
+            a = new MethodAnnotation(name, values, (Method) annotatedObject);
+            ((Method) annotatedObject).setAccessible(true);
+        } else if (annotatedObject instanceof Field) {
+            a = new FieldAnnotation(name, values, (Field) annotatedObject);
+            ((Field) annotatedObject).setAccessible(true);
+        } else {
+            a = new ClassAnnotation(name, values);
+        }
+        descriptions.add(a);
+    }
+
+    /**
+     * Get a description for the class
+     */
+    public ClassDescription getDescription(final Class<?> clazz)
+    throws SCRDescriptorException, SCRDescriptorFailureException {
+        final String name = clazz.getName();
+        ClassDescription result = this.allDescriptions.get(name);
+        if ( result == null ) {
+            // use scanner first
+            result = this.processClass(clazz, GENERATED);
+
+            if ( result == null ) {
+                // now check loaded dependencies
+                result = this.getComponentDescriptors().get(name);
+            }
+
+            // not found, create dummy
+            if ( result == null ) {
+                result = new ClassDescription(clazz, GENERATED);
+            }
+
+            // and cache
+            allDescriptions.put(name, result);
+        }
+        return result;
+    }
+
+    /**
+     * Returns a map of component descriptors which may be extended by the java
+     * sources.
+     * <p>
+     * This method calls the {@link #getDependencies()} method and checks for
+     * any Service-Component descriptors in the returned files.
+     * <p>
+     * This method may be overwritten by extensions of this class.
+     *
+     * @throws SCRDescriptorException May be thrown if an error occurrs
+     *             gethering the component descriptors.
+     */
+    private Map<String, ClassDescription> getComponentDescriptors()
+    throws SCRDescriptorException {
+        if ( loadedDependencies == null ) {
+            loadedDependencies = new HashMap<String, ClassDescription>();
+
+            final Collection<File> dependencies = this.project.getDependencies();
+            for ( final File artifact : dependencies ) {
+                try {
+                    this.log.debug( "Trying to get scrinfo from artifact " + artifact );
+                    // First try to read the private scr info file from previous scr generator versions
+                    InputStream scrInfoFile = null;
+                    try {
+                        scrInfoFile = this.getFile( artifact, ABSTRACT_DESCRIPTOR_ARCHIV_PATH );
+                        if ( scrInfoFile != null ) {
+                            final List<ClassDescription> c =  this.parseServiceComponentDescriptor( scrInfoFile, artifact.toString() + ':' + ABSTRACT_DESCRIPTOR_ARCHIV_PATH);
+                            if ( c != null ) {
+                                for(final ClassDescription cd : c) {
+                                    loadedDependencies.put(cd.getDescribedClass().getName(), cd);
+                                }
+                            }
+                            continue;
+                        }
+                        this.log.debug( "Artifact has no scrinfo file (it's optional): " + artifact );
+                    } catch ( final IOException ioe ) {
+                        throw new SCRDescriptorException( "Unable to get scrinfo from artifact", artifact.toString(), 0,
+                            ioe );
+                    } finally {
+                        if ( scrInfoFile != null ) {
+                            try { scrInfoFile.close(); } catch ( final IOException ignore ) {}
+                        }
+                    }
+
+                    this.log.debug( "Trying to get manifest from artifact " + artifact );
+                    final Manifest manifest = this.getManifest( artifact );
+                    if ( manifest != null ) {
+                        // read Service-Component entry
+                        if ( manifest.getMainAttributes().getValue( SERVICE_COMPONENT ) != null ) {
+                            final String serviceComponent = manifest.getMainAttributes().getValue(SERVICE_COMPONENT );
+                            this.log.debug( "Found Service-Component: " + serviceComponent + " in artifact " + artifact );
+                            final StringTokenizer st = new StringTokenizer( serviceComponent, "," );
+                            while ( st.hasMoreTokens() ) {
+                                final String entry = st.nextToken().trim();
+                                if ( entry.length() > 0 ) {
+                                    final List<ClassDescription> c = this.readServiceComponentDescriptor( artifact, entry );
+                                    if ( c != null ) {
+                                        for(final ClassDescription cd : c) {
+                                            loadedDependencies.put(cd.getDescribedClass().getName(), cd);
+                                        }
+                                    }
+                                }
+                            }
+                        } else {
+                            this.log.debug( "Artifact has no service component entry in manifest " + artifact );
+                        }
+                    } else {
+                        this.log.debug( "Unable to get manifest from artifact " + artifact );
+                    }
+                } catch ( IOException ioe ) {
+                    throw new SCRDescriptorException( "Unable to get manifest from artifact", artifact.toString(), 0,
+                        ioe );
+                }
+
+            }
+        }
+        return this.loadedDependencies;
+    }
+
+    /**
+     * Parses the descriptors read from the given input stream. This method may
+     * be called by the {@link #getComponentDescriptors()} method to parse the
+     * descriptors gathered in an implementation dependent way.
+     *
+     * @throws SCRDescriptorException If an error occurrs reading the
+     *             descriptors from the stream.
+     */
+    private List<ClassDescription> parseServiceComponentDescriptor(
+                    final InputStream file, final String location )
+    throws SCRDescriptorException {
+        return ComponentDescriptorIO.read( file, this.project.getClassLoader(), iLog, location );
+    }
+
+    /**
+     * Read the service component description.
+     *
+     * @param artifact
+     * @param entry
+     * @throws IOException
+     * @throws SCRDescriptorException
+     */
+    private List<ClassDescription> readServiceComponentDescriptor( final File artifactFile, String entry ) {
+        this.log.debug( "Reading " + entry + " from " + artifactFile );
+        InputStream xml = null;
+        try {
+            xml = this.getFile( artifactFile, entry );
+            if ( xml == null ) {
+                throw new SCRDescriptorException( "Entry " + entry + " not contained in JAR File ", artifactFile.toString(),
+                    0 );
+            }
+            return this.parseServiceComponentDescriptor( xml, artifactFile.toString() + ':' + entry );
+        } catch ( final IOException mee ) {
+            this.log.warn( "Unable to read SCR descriptor file from JAR File " + artifactFile + " at " + entry );
+            this.log.debug( "Exception occurred during reading: " + mee.getMessage(), mee );
+        } catch ( final SCRDescriptorException mee ) {
+            this.log.warn( "Unable to read SCR descriptor file from JAR File " + artifactFile + " at " + entry );
+            this.log.debug( "Exception occurred during reading: " + mee.getMessage(), mee );
+        } finally {
+            if ( xml != null ) {
+                try { xml.close(); } catch (final IOException ignore) {}
+            }
+        }
+
+        return null;
+    }
+
+
+    /**
+     * Get the manifest from the artifact.
+     * The artifact can either be a jar or a directory.
+     */
+    private Manifest getManifest( final File artifact ) throws IOException {
+        if ( artifact.isDirectory() ) {
+            // this is maybe a classes directory, try to read manifest file directly
+            final File dir = new File(artifact, "META-INF");
+            if ( !dir.exists() || !dir.isDirectory() ) {
+                return null;
+            }
+            final File mf = new File(dir, "MANIFEST.MF");
+            if ( !mf.exists() || !mf.isFile() ) {
+                return null;
+            }
+            final InputStream is = new FileInputStream(mf);
+            try {
+                return new Manifest(is);
+            } finally {
+                try { is.close(); } catch (final IOException ignore) { }
+            }
+        }
+        JarFile file = null;
+        try {
+            file = new JarFile( artifact );
+            return file.getManifest();
+        } finally {
+            if ( file != null ) {
+                try { file.close(); } catch ( final IOException ignore ) {}
+            }
+        }
+    }
+
+    private InputStream getFile( final File artifactFile, final String path ) throws IOException {
+        if ( artifactFile.isDirectory() ) {
+            final String filePath = path.replace('/', File.separatorChar).replace('\\', File.separatorChar);
+            final File file = new File(artifactFile, filePath);
+            if ( file.exists() && file.isFile() ) {
+                return new FileInputStream(file);
+            }
+            return null;
+        }
+        JarFile file = null;
+        try {
+            file = new JarFile( artifactFile );
+            final JarEntry entry = file.getJarEntry( path );
+            if ( entry != null ) {
+                final InputStream stream = new ArtifactFileInputStream( file, entry );
+                file = null; // prevent file from being closed now
+                return stream;
+            }
+            return null;
+        } finally {
+            if ( file != null ) {
+                try { file.close(); } catch ( final IOException ignore ) {}
+            }
+        }
+    }
+
+    private static class ArtifactFileInputStream extends FilterInputStream {
+
+        final JarFile jarFile;
+
+        ArtifactFileInputStream( JarFile jarFile, JarEntry jarEntry ) throws IOException {
+            super( jarFile.getInputStream( jarEntry ) );
+            this.jarFile = jarFile;
+        }
+
+
+        @Override
+        public void close() throws IOException {
+            try {
+                super.close();
+            } catch ( final IOException ioe ) {
+                // ignore
+            }
+            jarFile.close();
+        }
+
+
+        @Override
+        protected void finalize() throws Throwable {
+            try {
+                close();
+            } finally {
+                super.finalize();
+            }
+        }
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/IssueLog.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/IssueLog.java
index 210b42d..8e7819c 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/IssueLog.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/IssueLog.java
@@ -18,7 +18,9 @@
  */
 package org.apache.felix.scrplugin.helper;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
 
 import org.apache.felix.scrplugin.Log;
 
@@ -44,86 +46,72 @@
     }
 
     public boolean hasErrors() {
-        return errors.size() > 0 ||
-               (this.strictMode && (warnings.size() > 0 || this.deprecationWarnings.size() > 0));
+        return errors.size() > 0 || (this.strictMode && (warnings.size() > 0 || this.deprecationWarnings.size() > 0));
     }
 
-    public void addError(final String message, final String location, final int lineNumber) {
-        errors.add( new Entry( message, location, lineNumber ) );
+    public void addError(final String message, final String location) {
+        errors.add(new Entry(message, location));
     }
 
-    public void addWarning(final String message, final String location, final int lineNumber) {
-        warnings.add( new Entry( message, location, lineNumber ) );
+    public void addWarning(final String message, final String location) {
+        warnings.add(new Entry(message, location));
     }
 
-    public void addDeprecationWarning(final String message, final String location, final int lineNumber) {
-        deprecationWarnings.add( new Entry( message, location, lineNumber ) );
+    public void addDeprecationWarning(final String message, final String location) {
+        deprecationWarnings.add(new Entry(message, location));
     }
 
-    public void logMessages( final Log log )
-    {
+    public void logMessages(final Log log) {
         // now log warnings and errors (warnings first)
         // in strict mode everything is an error!
         final Iterator<Entry> depWarnings = this.deprecationWarnings.iterator();
-        while ( depWarnings.hasNext() )
-        {
+        while (depWarnings.hasNext()) {
             final Entry entry = depWarnings.next();
-            if ( strictMode )
-            {
-                log.error( entry.message, entry.location, entry.lineNumber);
-            }
-            else
-            {
-                log.warn( entry.message, entry.location, entry.lineNumber);
+            if (strictMode) {
+                log.error(entry.toString());
+            } else {
+                log.warn(entry.toString());
             }
         }
-        if ( this.deprecationWarnings.size() > 0 ) {
-            final String msg = "It is highly recommended to fix these problems, as future versions might not " +
-             "support these features anymore.";
-            if ( strictMode )
-            {
-                log.error( msg );
-            }
-            else
-            {
-                log.warn( msg );
+        if (this.deprecationWarnings.size() > 0) {
+            final String msg = "It is highly recommended to fix these problems, as future versions might not "
+                            + "support these features anymore.";
+            if (strictMode) {
+                log.error(msg);
+            } else {
+                log.warn(msg);
             }
         }
 
         final Iterator<Entry> warnings = this.warnings.iterator();
-        while ( warnings.hasNext() )
-        {
+        while (warnings.hasNext()) {
             final Entry entry = warnings.next();
-            if ( strictMode )
-            {
-                log.error( entry.message, entry.location, entry.lineNumber);
-            }
-            else
-            {
-                log.warn( entry.message, entry.location, entry.lineNumber);
+            if (strictMode) {
+                log.error(entry.toString());
+            } else {
+                log.warn(entry.toString());
             }
         }
 
         final Iterator<Entry> errors = this.errors.iterator();
-        while ( errors.hasNext() )
-        {
+        while (errors.hasNext()) {
             final Entry entry = errors.next();
-            log.error( entry.message, entry.location, entry.lineNumber);
+            log.error(entry.toString());
         }
     }
 
-    private static class Entry
-    {
+    private static class Entry {
         final String message;
         final String location;
-        final int lineNumber;
 
-
-        Entry( final String message, final String location, final int lineNumber )
-        {
+        Entry(final String message, final String location) {
             this.message = message;
             this.location = location;
-            this.lineNumber = lineNumber;
+        }
+
+        @Override
+        public String toString() {
+            return this.location + " : " + this.message;
         }
     }
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/PropertyHandler.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/PropertyHandler.java
deleted file mode 100644
index 46b02ef..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/PropertyHandler.java
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * 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.scrplugin.helper;
-
-import java.util.*;
-
-import org.apache.felix.scrplugin.*;
-import org.apache.felix.scrplugin.om.Component;
-import org.apache.felix.scrplugin.om.Property;
-import org.apache.felix.scrplugin.om.metatype.AttributeDefinition;
-import org.apache.felix.scrplugin.om.metatype.OCD;
-import org.apache.felix.scrplugin.tags.JavaField;
-import org.apache.felix.scrplugin.tags.JavaTag;
-import org.osgi.service.cm.ConfigurationAdmin;
-
-/**
- * Utility class for handling the properties.
- */
-public class PropertyHandler {
-
-    /**
-     * This is a map using the property name as the key and
-     * {@link PropertyDescription} as values.
-     */
-    final private Map<String, PropertyDescription> properties = new LinkedHashMap<String, PropertyDescription>();
-
-    /** The component. */
-    final private Component component;
-
-    /** The ocd or null. */
-    final private OCD ocd;
-
-    public PropertyHandler(final Component c, OCD o) {
-        this.component = c;
-        this.ocd = o;
-    }
-
-    /**
-     * Process a property.
-     * @param tag       The property tag.
-     * @param name      The name of the property.
-     * @param javaField The corresponding java field or null.
-     */
-    protected void processProperty(JavaTag   tag,
-                                   String    name,
-                                   JavaField javaField,
-                                   final IssueLog iLog)
-    throws SCRDescriptorException {
-        final Property prop = new Property(tag);
-        prop.setName(name);
-        // special handling for service.ranking - FELIX-2333
-        if (name.equals(org.osgi.framework.Constants.SERVICE_RANKING)) {
-            prop.setType(Constants.PROPERTY_TYPE_INTEGER);
-        }
-        if ( tag.getNamedParameter(Constants.PROPERTY_TYPE) != null ) {
-            prop.setType(tag.getNamedParameter(Constants.PROPERTY_TYPE));
-        }
-        // let's first check for a value attribute
-        final String value = tag.getNamedParameter(Constants.PROPERTY_VALUE);
-        if ( value != null ) {
-            prop.setValue(value);
-        } else {
-            // now we check for a value ref attribute
-            final String valueRef = tag.getNamedParameter(Constants.PROPERTY_VALUE_REF);
-            if ( valueRef != null ) {
-                this.setPropertyValueRef(tag, prop, valueRef);
-            } else {
-                // check for multivalue - these can either be values or value refs
-                final List<String> values = new ArrayList<String>();
-                final Map<String, String> valueMap = tag.getNamedParameterMap();
-                for (Iterator<Map.Entry<String, String>> vi = valueMap.entrySet().iterator(); vi.hasNext();) {
-                    final Map.Entry<String, String> entry = vi.next();
-                    final String key = entry.getKey();
-                    if (key.startsWith(Constants.PROPERTY_MULTIVALUE_PREFIX) ) {
-                        values.add(entry.getValue());
-                    } else if ( key.startsWith(Constants.PROPERTY_MULTIVALUE_REF_PREFIX) ) {
-                        final String[] stringValues = this.getPropertyValueRef(tag, prop, entry.getValue());
-                        if ( stringValues != null ) {
-                            for(int i=0; i<stringValues.length; i++) {
-                                values.add(stringValues[i]);
-                            }
-                        }
-                    }
-                }
-                if ( values.size() > 0 ) {
-                    prop.setMultiValue(values.toArray(new String[values.size()]));
-                } else {
-                    // we have no value, valueRef or values so let's try to
-                    // get the value of the field if a name attribute is specified
-                    final boolean isNamedParameter = tag.getNamedParameter(Constants.PROPERTY_NAME) != null
-                                                  || tag.getNamedParameter(Constants.PROPERTY_NAME_REF) != null;
-                    if ( isNamedParameter && javaField != null ) {
-                        this.setPropertyValueRef(tag, prop, javaField.getName());
-                    }
-                }
-            }
-        }
-
-        // property is private if explicitly marked or a well known
-        // service property such as service.pid
-        final boolean isPrivate = isPrivate(name, tag);
-
-        // if this is an abstract component we store the extra info in the property
-        if ( component.isAbstract() ) {
-            prop.setPrivate(isPrivate);
-            prop.setLabel(tag.getNamedParameter(Constants.PROPERTY_LABEL));
-            prop.setDescription(tag.getNamedParameter(Constants.PROPERTY_DESCRIPTION));
-            prop.setCardinality(tag.getNamedParameter(Constants.PROPERTY_CARDINALITY));
-        }
-
-        // if this is a public property and the component is generating metatype info
-        // store the information!
-        if ( !isPrivate && ocd != null ) {
-            final AttributeDefinition ad = new AttributeDefinition();
-            ocd.getProperties().add(ad);
-            ad.setId(prop.getName());
-            ad.setType(prop.getType());
-
-            String adName = tag.getNamedParameter(Constants.PROPERTY_LABEL);
-            if ( adName == null ) {
-                adName = "%" + prop.getName() + ".name";
-            }
-            ad.setName(adName);
-            String adDesc = tag.getNamedParameter(Constants.PROPERTY_DESCRIPTION);
-            if ( adDesc == null ) {
-                adDesc = "%" + prop.getName() + ".description";
-            }
-            ad.setDescription(adDesc);
-            // set optional multivalues, cardinality might be overwritten by setValues !!
-            final String cValue = tag.getNamedParameter(Constants.PROPERTY_CARDINALITY);
-            if (cValue != null) {
-                if ("-".equals(cValue)) {
-                    // unlimited vector
-                    ad.setCardinality(new Integer(Integer.MIN_VALUE));
-                } else if ("+".equals(cValue)) {
-                   // unlimited array
-                    ad.setCardinality(new Integer(Integer.MAX_VALUE));
-                } else {
-                    try {
-                        ad.setCardinality(Integer.valueOf(cValue));
-                    } catch (NumberFormatException nfe) {
-                        // default to scalar in case of conversion problem
-                    }
-                }
-            }
-            ad.setDefaultValue(prop.getValue());
-            ad.setDefaultMultiValue(prop.getMultiValue());
-
-            // check options
-            String[] parameters = tag.getParameters();
-            Map<String, String> options = null;
-            for (int j=0; j < parameters.length; j++) {
-                if (Constants.PROPERTY_OPTIONS.equals(parameters[j])) {
-                    options = new LinkedHashMap<String, String>();
-                } else if (options != null) {
-                    final String option = parameters[j];
-                    final int pos = option.indexOf('=');
-                    if ( pos != -1 )
-                    {
-                        // handle options from javadoc comments
-                        String optionLabel = option.substring(0, pos);
-                        String optionValue = option.substring(pos + 1);
-                        if (optionValue != null && optionValue.length() > 0 ) {
-                            options.put(optionLabel, optionValue);
-                        }
-                    }
-                    else
-                    {
-                        // handle options from java annotations
-                        String optionLabel = parameters[j];
-                        String optionValue = (j < parameters.length-2) ? parameters[j+2] : null;
-                        if (optionValue != null && "=".equals(parameters[j+1]) ) {
-                            options.put(optionLabel, optionValue);
-                        }
-                        j += 2;
-                    }
-                }
-            }
-            ad.setOptions(options);
-        }
-
-        component.addProperty(prop);
-    }
-
-    private boolean isPrivate(String name, JavaTag tag) {
-        if (name.equals(org.osgi.framework.Constants.SERVICE_RANKING)) {
-            return SCRDescriptorGenerator.getBoolean(tag,
-                Constants.PROPERTY_PRIVATE, true);
-        }
-        return SCRDescriptorGenerator.getBoolean(tag,
-            Constants.PROPERTY_PRIVATE, false)
-            || name.equals(org.osgi.framework.Constants.SERVICE_PID)
-            || name.equals(org.osgi.framework.Constants.SERVICE_DESCRIPTION)
-            || name.equals(org.osgi.framework.Constants.SERVICE_ID)
-            || name.equals(org.osgi.framework.Constants.SERVICE_VENDOR)
-            || name.equals(ConfigurationAdmin.SERVICE_BUNDLELOCATION)
-            || name.equals(ConfigurationAdmin.SERVICE_FACTORYPID);
-    }
-
-    /**
-     * Return the name of the property.
-     * The name of the property is derived by:
-     * <ol>
-     *   <li>looking at the attribute {@link Constants.PROPERTY_NAME}</li>
-     *   <li>looking at the attribute {@link Constants.PROPERTY_NAME_REF}</li>
-     *   <li>if the property is specified at a filed and the field is of type string the init value is used.</li>
-     * </ol>
-     *
-     * @param property The property tag.
-     * @param field    The corresponding field if the property is a tag of a field.
-     * @return The name of the property or the defaultName
-     */
-    protected String getPropertyName(JavaTag tag, JavaField field)
-    throws SCRDescriptorException {
-        // check name property
-        String name = tag.getNamedParameter(Constants.PROPERTY_NAME);
-
-        if (StringUtils.isEmpty(name)) {
-            // check name ref propery
-            name = tag.getNamedParameter(Constants.PROPERTY_NAME_REF);
-            if (!StringUtils.isEmpty(name)) {
-                final JavaField refField = this.getReferencedField(tag, name);
-                final String[] values = refField.getInitializationExpression();
-                if ( values == null || values.length == 0 ) {
-                    throw new SCRDescriptorException("Referenced field for " + name + " has no values for a property name.", tag);
-                }
-                if ( values.length > 1 ) {
-                    throw new SCRDescriptorException("Referenced field " + name + " has more than one value for a property name.", tag);
-                }
-                name = values[0];
-            }
-
-            if (StringUtils.isEmpty(name)) {
-                // check field
-                name = null;
-                if ( field != null && "java.lang.String".equals(field.getType()) ) {
-                    final String[] initValues = field.getInitializationExpression();
-                    if ( initValues != null && initValues.length == 1 ) {
-                        name = initValues[0];
-                    }
-                }
-            }
-        }
-        // final empty check
-        if ( StringUtils.isEmpty(name) ) {
-            name = null;
-        }
-        return name;
-    }
-
-    protected void setPropertyValueRef(final JavaTag tag, Property property, String valueRef)
-    throws SCRDescriptorException {
-        final String[] values = this.getPropertyValueRef(tag, property, valueRef);
-        if ( values != null && values.length == 1 ) {
-            property.setValue(values[0]);
-        } else if ( values != null && values.length > 1 ) {
-            property.setMultiValue(values);
-        }
-    }
-
-    protected JavaField getReferencedField(final JavaTag tag, String ref)
-    throws SCRDescriptorException {
-        int classSep = ref.lastIndexOf('.');
-        JavaField field = null;
-        if ( classSep == -1 ) {
-            // local variable
-            field = tag.getJavaClassDescription().getFieldByName(ref);
-        }
-        if ( field == null ) {
-            field = tag.getJavaClassDescription().getExternalFieldByName(ref);
-        }
-        if ( field == null ) {
-            throw new SCRDescriptorException("Property references unknown field " + ref + " in class " + tag.getJavaClassDescription().getName(), tag);
-        }
-        return field;
-    }
-
-    protected String[] getPropertyValueRef(final JavaTag tag, Property prop, String valueRef)
-    throws SCRDescriptorException {
-        final JavaField field = this.getReferencedField(tag, valueRef);
-
-        // determine type (if not set explicitly)
-        if ( prop.getType() == null ) {
-            final String type = field.getType();
-            if ( "java.lang.String".equals(type) ) {
-                prop.setType(Constants.PROPERTY_TYPE_STRING);
-            } else if ("java.lang.Long".equals(type) || "long".equals(type) ) {
-                prop.setType(Constants.PROPERTY_TYPE_LONG);
-            } else if ("java.lang.Double".equals(type) || "double".equals(type) ) {
-                prop.setType(Constants.PROPERTY_TYPE_DOUBLE);
-            } else if ("java.lang.Float".equals(type) || "float".equals(type) ) {
-                prop.setType(Constants.PROPERTY_TYPE_FLOAT);
-            } else if ("java.lang.Integer".equals(type) || "int".equals(type) ) {
-                prop.setType(Constants.PROPERTY_TYPE_INTEGER);
-            } else if ("java.lang.Byte".equals(type) || "byte".equals(type) ) {
-                prop.setType(Constants.PROPERTY_TYPE_BYTE);
-            } else if ("java.lang.Character".equals(type) || "char".equals(type) ) {
-                prop.setType(Constants.PROPERTY_TYPE_CHAR_1_1);
-            } else if ("java.lang.Boolean".equals(type) || "boolean".equals(type) ) {
-                prop.setType(Constants.PROPERTY_TYPE_BOOLEAN);
-            } else if ("java.lang.Short".equals(type) || "short".equals(type) ) {
-                prop.setType(Constants.PROPERTY_TYPE_SHORT);
-            }
-
-        }
-        return field.getInitializationExpression();
-    }
-
-    /**
-     * Test if there is already a property with the same name.
-     * @param property The tag.
-     * @param field
-     * @param isInspectedClass
-     * @throws SCRDescriptorException
-     */
-    public void testProperty(JavaTag   property,
-                             JavaField field,
-                             boolean   isInspectedClass)
-    throws SCRDescriptorException {
-        final String propName = this.getPropertyName(property, field);
-
-        if ( propName != null ) {
-            if ( properties.containsKey(propName) ) {
-                // if the current class is the class we are currently inspecting, we
-                // have found a duplicate definition
-                if ( isInspectedClass ) {
-                    throw new SCRDescriptorException("Duplicate definition for property " + propName + " in class " + property.getJavaClassDescription().getName(), property);
-                }
-            } else {
-                properties.put(propName, new PropertyDescription(property, field));
-            }
-        } else {
-            throw new SCRDescriptorException("Property has no name", property);
-        }
-    }
-
-    public void handleField(JavaField javaField, boolean isInspectedClass)
-    throws SCRDescriptorException {
-        final JavaTag tag = javaField.getTagByName(Constants.PROPERTY);
-        if (tag != null) {
-            this.testProperty(tag, javaField, isInspectedClass);
-        }
-    }
-
-    /**
-     * Process all found properties for the component.
-     * @param globalProperties Global properties are set on all components.
-     * @param iLog The issue log.
-     * @throws SCRDescriptorException
-     */
-    public void processProperties(final Map<String, String> globalProperties,
-                                  final IssueLog iLog)
-    throws SCRDescriptorException {
-        final Iterator<Map.Entry<String, PropertyDescription>> propIter = properties.entrySet().iterator();
-        while ( propIter.hasNext() ) {
-            final Map.Entry<String, PropertyDescription> entry = propIter.next();
-            final String propName = entry.getKey();
-            final PropertyDescription desc = entry.getValue();
-            this.processProperty(desc.propertyTag, propName, desc.field, iLog);
-        }
-        // apply pre configured global properties
-        if ( globalProperties != null ) {
-            final Iterator<Map.Entry<String, String>> globalPropIter = globalProperties.entrySet().iterator();
-            while ( globalPropIter.hasNext() ) {
-                final Map.Entry<String, String> entry = globalPropIter.next();
-                final String name = entry.getKey();
-
-                // check if the service already provides this property
-                if ( !properties.containsKey(name) && entry.getValue() != null ) {
-                    final String value = entry.getValue();
-
-                    final Property p = new Property();
-                    p.setName(name);
-                    p.setValue(value);
-                    p.setType("String");
-                    p.setPrivate(true);
-                    component.addProperty(p);
-
-                }
-            }
-        }
-    }
-
-    protected static final class PropertyDescription {
-        public final JavaTag propertyTag;
-        public final JavaField field;
-
-        public PropertyDescription(final JavaTag p, final JavaField f) {
-            this.propertyTag = p;
-            this.field = f;
-        }
-    }
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/AbstractObject.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/AbstractObject.java
index 425865e..9f7d05c 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/AbstractObject.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/AbstractObject.java
@@ -19,29 +19,27 @@
 package org.apache.felix.scrplugin.om;
 
 import org.apache.felix.scrplugin.helper.IssueLog;
-import org.apache.felix.scrplugin.tags.JavaTag;
+import org.apache.felix.scrplugin.scanner.ScannedAnnotation;
 
 /**
- * The <code>AbstractObject</code>
- * is the base class for the all classes of the scr om.
+ * The <code>AbstractObject</code> is the base class for the all classes of the scr om.
  */
 public abstract class AbstractObject {
 
-    protected final JavaTag tag;
+    private final String annotationName;
 
-    protected AbstractObject(JavaTag tag) {
-        this.tag = tag;
+    private final String sourceLocation;
+
+    protected AbstractObject(final ScannedAnnotation annotation, final String sourceLocation) {
+        this.annotationName = (annotation != null ? annotation.getName() : "<unknown>");
+        this.sourceLocation = sourceLocation;
     }
 
     protected void logWarn(IssueLog iLog, String message) {
-        iLog.addWarning( "@" + this.tag.getSourceName() + ": " + message, tag.getSourceLocation(), tag.getLineNumber() );
+        iLog.addWarning("@" + this.annotationName + ": " + message, sourceLocation);
     }
 
     protected void logError(IssueLog iLog, String message) {
-        iLog.addError( "@" + this.tag.getSourceName() + ": " + message, tag.getSourceLocation(), tag.getLineNumber() );
-    }
-
-    public JavaTag getJavaTag() {
-        return this.tag;
+        iLog.addError("@" + this.annotationName + ": " + message, sourceLocation);
     }
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Component.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Component.java
index 72f1c22..2c18d80 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Component.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Component.java
@@ -18,17 +18,20 @@
  */
 package org.apache.felix.scrplugin.om;
 
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.felix.scrplugin.Constants;
 import org.apache.felix.scrplugin.SCRDescriptorException;
-import org.apache.felix.scrplugin.helper.IssueLog;
-import org.apache.felix.scrplugin.tags.*;
+import org.apache.felix.scrplugin.description.ClassDescription;
+import org.apache.felix.scrplugin.description.ComponentConfigurationPolicy;
+import org.apache.felix.scrplugin.description.SpecVersion;
+import org.apache.felix.scrplugin.scanner.ScannedAnnotation;
 
 /**
- * <code>Component</code>
- * is a described component.
+ * <code>Component</code> is a described component.
  *
  */
 public class Component extends AbstractObject {
@@ -64,7 +67,7 @@
     protected boolean isDs;
 
     /** Configuration policy. (V1.1) */
-    protected String configurationPolicy;
+    protected ComponentConfigurationPolicy configurationPolicy;
 
     /** Activation method. (V1.1) */
     protected String activate;
@@ -76,50 +79,41 @@
     protected String modified;
 
     /** The spec version. */
-    protected int specVersion;
+    protected SpecVersion specVersion;
 
-    /**
-     * Default constructor.
-     */
-    public Component() {
-        this(null);
-    }
+    /** The class description. */
+    private final ClassDescription classDescription;
 
     /**
      * Constructor from java source.
      */
-    public Component(JavaTag t) {
-        super(t);
+    public Component(final ClassDescription cDesc, final ScannedAnnotation annotation, final String sourceLocation) {
+        super(annotation, sourceLocation);
+        this.classDescription = cDesc;
+    }
+
+    public ClassDescription getClassDescription() {
+        return this.classDescription;
     }
 
     /**
      * Get the spec version.
      */
-    public int getSpecVersion() {
+    public SpecVersion getSpecVersion() {
         return this.specVersion;
     }
 
     /**
      * Set the spec version.
      */
-    public void setSpecVersion(int value) {
+    public void setSpecVersion(final SpecVersion value) {
         // only set a higher version, never "downgrade"
-        if (this.specVersion < value) {
+        if (this.specVersion == null || this.specVersion.ordinal() < value.ordinal()) {
             this.specVersion = value;
         }
     }
 
     /**
-     * Return the associated java class description
-     */
-    public JavaClassDescription getJavaClassDescription() {
-        if ( this.tag != null ) {
-            return this.tag.getJavaClassDescription();
-        }
-        return null;
-    }
-
-    /**
      * @return All properties of this component.
      */
     public List<Property> getProperties() {
@@ -253,109 +247,104 @@
     }
 
     /**
-     * Validate the component description.
-     * If errors occur a message is added to the issues list,
-     * warnings can be added to the warnings list.
+     * Validate the component description. If errors occur a message is added to
+     * the issues list, warnings can be added to the warnings list.
      */
-    public void validate(final int specVersion, final IssueLog iLog)
-    throws SCRDescriptorException {
-        final int currentIssueCount = iLog.getNumberOfErrors();
-
+    public void validate(final Context context) throws SCRDescriptorException {
         // nothing to check if this is ignored
         if (!isDs()) {
             return;
         }
 
-        final JavaClassDescription javaClass = this.tag.getJavaClassDescription();
-        if (javaClass == null) {
-            this.logError( iLog, "Tag not declared in a Java Class" );
-        } else {
+        final int currentIssueCount = context.getIssueLog().getNumberOfErrors();
 
-            // if the service is abstract, we do not validate everything
-            if ( !this.isAbstract ) {
-                // ensure non-abstract, public class
-                if (!javaClass.isPublic()) {
-                    this.logError( iLog, "Class must be public: " + javaClass.getName() );
-                }
-                if (javaClass.isAbstract() || javaClass.isInterface()) {
-                    this.logError( iLog, "Class must be concrete class (not abstract or interface) : " + javaClass.getName() );
-                }
-
-                // no errors so far, let's continue
-                if ( iLog.getNumberOfErrors() == currentIssueCount ) {
-                    final String activateName = this.activate == null ? "activate" : this.activate;
-                    final String deactivateName = this.deactivate == null ? "deactivate" : this.deactivate;
-
-                    // check activate and deactivate methods
-                    this.checkLifecycleMethod(specVersion, javaClass, activateName, true, iLog);
-                    this.checkLifecycleMethod(specVersion, javaClass, deactivateName, false, iLog);
-
-                    if ( this.modified != null && specVersion >= Constants.VERSION_1_1 ) {
-                        this.checkLifecycleMethod(specVersion, javaClass, this.modified, true, iLog);
-                    }
-                    // ensure public default constructor
-                    boolean constructorFound = true;
-                    JavaMethod[] methods = javaClass.getMethods();
-                    for (int i = 0; methods != null && i < methods.length; i++) {
-                        if (methods[i].isConstructor()) {
-                            // if public default, succeed
-                            if (methods[i].isPublic()
-                                && (methods[i].getParameters() == null || methods[i].getParameters().length == 0)) {
-                                constructorFound = true;
-                                break;
-                            }
-
-                            // non-public/non-default constructor found, must have explicit
-                            constructorFound = false;
-                        }
-                    }
-                    if (!constructorFound) {
-                        this.logError( iLog, "Class must have public default constructor: " + javaClass.getName() );
-                    }
-
-                    // verify properties
-                    for(final Property prop : this.getProperties()) {
-                        prop.validate(specVersion, iLog);
-                    }
-
-                    // verify service
-                    boolean isServiceFactory = false;
-                    if (this.getService() != null) {
-                        if ( this.getService().getInterfaces().size() == 0 ) {
-                            this.logError( iLog, "Service interface information is missing!" );
-                        }
-                        this.getService().validate(specVersion, iLog);
-                        isServiceFactory = this.getService().isServicefactory();
-                    }
-
-                    // serviceFactory must not be true for immediate of component factory
-                    if (isServiceFactory && this.isImmediate() != null && this.isImmediate().booleanValue() && this.getFactory() != null) {
-                        this.logError( iLog, "Component must not be a ServiceFactory, if immediate and/or component factory: " + javaClass.getName() );
-                    }
-
-                    // immediate must not be true for component factory
-                    if (this.isImmediate() != null && this.isImmediate().booleanValue() && this.getFactory() != null) {
-                        this.logError( iLog, "Component must not be immediate if component factory: " + javaClass.getName() );
-                    }
-                }
+        // if the service is abstract, we do not validate everything
+        if (!this.isAbstract) {
+            // ensure non-abstract, public class
+            if (!Modifier.isPublic(context.getClassDescription().getDescribedClass().getModifiers())) {
+                this.logError(context.getIssueLog(), "Class must be public: "
+                                + context.getClassDescription().getDescribedClass().getName());
             }
-            if ( iLog.getNumberOfErrors() == currentIssueCount ) {
-                // verify references
-                for(final Reference ref : this.getReferences()) {
-                    ref.validate(specVersion, this.isAbstract, iLog);
+            if (Modifier.isAbstract(context.getClassDescription().getDescribedClass().getModifiers())
+                            || context.getClassDescription().getDescribedClass().isInterface()) {
+                this.logError(context.getIssueLog(), "Class must be concrete class (not abstract or interface) : "
+                                + context.getClassDescription().getDescribedClass().getName());
+            }
+
+            // no errors so far, let's continue
+            if (context.getIssueLog().getNumberOfErrors() == currentIssueCount) {
+
+                final String activateName = this.activate == null ? "activate" : this.activate;
+                final String deactivateName = this.deactivate == null ? "deactivate" : this.deactivate;
+
+                // check activate and deactivate methods
+                this.checkLifecycleMethod(context, activateName, true);
+                this.checkLifecycleMethod(context, deactivateName, false);
+
+                if (this.modified != null) {
+                    if ( context.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
+                        this.checkLifecycleMethod(context, this.modified, true);
+                    } else {
+                        this.logError(context.getIssueLog(), "If modified version is specified, spec version must be " +
+                            SpecVersion.VERSION_1_1.name() + " or higher : " + this.modified);
+                    }
+                }
+
+                // ensure public default constructor
+                boolean constructorFound = true;
+                Constructor<?>[] constructors = this.classDescription.getDescribedClass().getDeclaredConstructors();
+                for (int i = 0; constructors != null && i < constructors.length; i++) {
+                    // if public default, succeed
+                    if (Modifier.isPublic(constructors[i].getModifiers())
+                        && (constructors[i].getParameterTypes() == null || constructors[i].getParameterTypes().length == 0)) {
+                        constructorFound = true;
+                        break;
+                    }
+
+                    // non-public/non-default constructor found, must have
+                    // explicit
+                    constructorFound = false;
+                }
+
+                if (!constructorFound) {
+                    this.logError(context.getIssueLog(), "Class must have public default constructor: " + this.classDescription.getDescribedClass().getName());
+                }
+
+                // verify properties
+                for (final Property prop : this.getProperties()) {
+                    prop.validate(context);
+                }
+
+                // verify service
+                boolean isServiceFactory = false;
+                if (this.getService() != null) {
+                    if (this.getService().getInterfaces().size() == 0) {
+                        this.logError(context.getIssueLog(), "Service interface information is missing!");
+                    }
+                    this.getService().validate(context);
+                    isServiceFactory = this.getService().isServiceFactory();
+                }
+
+                // serviceFactory must not be true for immediate of component factory
+                if (isServiceFactory && this.isImmediate() != null && this.isImmediate().booleanValue()
+                    && this.getFactory() != null) {
+                    this.logError(context.getIssueLog(),
+                        "Component must not be a ServiceFactory, if immediate and/or component factory: "
+                        + this.getClassDescription().getDescribedClass().getName());
+                }
+
+                // immediate must not be true for component factory
+                if (this.isImmediate() != null && this.isImmediate().booleanValue() && this.getFactory() != null) {
+                    this.logError(context.getIssueLog(),
+                        "Component must not be immediate if component factory: " + this.getClassDescription().getDescribedClass().getName());
                 }
             }
         }
-        // check additional stuff if version is 1.1
-        if ( specVersion >= Constants.VERSION_1_1 ) {
-            final String cp = this.getConfigurationPolicy();
-            if ( cp != null
-                 && !Constants.COMPONENT_CONFIG_POLICY_IGNORE.equals(cp)
-                 && !Constants.COMPONENT_CONFIG_POLICY_REQUIRE.equals(cp)
-                 && !Constants.COMPONENT_CONFIG_POLICY_OPTIONAL.equals(cp) ) {
-                this.logError( iLog, "Component has an unknown value for configuration policy: " + cp );
+        if (context.getIssueLog().getNumberOfErrors() == currentIssueCount) {
+            // verify references
+            for (final Reference ref : this.getReferences()) {
+                ref.validate(context, this.isAbstract);
             }
-
         }
     }
 
@@ -365,78 +354,114 @@
     private static final String TYPE_INT = "int";
     private static final String TYPE_INTEGER = "java.lang.Integer";
 
+    private Method getMethod(final Context ctx, final String name, final String[] sig)
+    throws SCRDescriptorException {
+        Class<?>[] classSig = (sig == null ? null : new Class<?>[sig.length]);
+        if ( sig != null ) {
+            for(int i = 0; i<sig.length; i++) {
+                try {
+                    if ( sig[i].equals("int") ) {
+                        classSig[i] = int.class;
+                    } else {
+                        classSig[i] = ctx.getProject().getClassLoader().loadClass(sig[i]);
+                    }
+                } catch (final ClassNotFoundException e) {
+                    throw new SCRDescriptorException("Unable to load class.", e);
+                }
+            }
+        }
+        try {
+            return ctx.getClassDescription().getDescribedClass().getDeclaredMethod(name, classSig);
+        } catch (final SecurityException e) {
+            // ignore
+        } catch (final NoSuchMethodException e) {
+            // ignore
+        }
+        return null;
+    }
+
     /**
      * Check for existence of lifecycle methods.
-     * @param specVersion The spec version
-     * @param javaClass The java class to inspect.
-     * @param methodName The method name.
-     * @param warnings The list of warnings used to add new warnings.
+     *
+     * @param specVersion
+     *            The spec version
+     * @param javaClass
+     *            The java class to inspect.
+     * @param methodName
+     *            The method name.
+     * @param warnings
+     *            The list of warnings used to add new warnings.
      */
-    protected void checkLifecycleMethod(final int specVersion,
-                                        final JavaClassDescription javaClass,
-                                        final String methodName,
-                                        final boolean isActivate,
-                                        final IssueLog iLog)
+    private void checkLifecycleMethod(final Context ctx,
+                                      final String methodName,
+                                      final boolean isActivate)
     throws SCRDescriptorException {
         // first candidate is (de)activate(ComponentContext)
-        JavaMethod method = javaClass.getMethodBySignature(methodName, new String[] {TYPE_COMPONENT_CONTEXT});
-        if ( method == null ) {
-            if ( specVersion >= Constants.VERSION_1_1) {
+        Method method = this.getMethod(ctx, methodName, new String[] { TYPE_COMPONENT_CONTEXT });
+        if (method == null) {
+            if (ctx.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
                 // second candidate is (de)activate(BundleContext)
-                method = javaClass.getMethodBySignature(methodName, new String[] {TYPE_BUNDLE_CONTEXT});
-                if ( method == null ) {
+                method = this.getMethod(ctx, methodName, new String[] { TYPE_BUNDLE_CONTEXT });
+                if (method == null) {
                     // third candidate is (de)activate(Map)
-                    method = javaClass.getMethodBySignature(methodName, new String[] {TYPE_MAP});
+                    method = this.getMethod(ctx, methodName, new String[] { TYPE_MAP });
 
-                    if ( method == null ) {
-                        // if this is a deactivate method, we have two additional possibilities
-                        // a method with parameter of type int and one of type Integer
-                        if ( !isActivate ) {
-                            method = javaClass.getMethodBySignature(methodName, new String[] {TYPE_INT});
-                            if ( method == null ) {
-                                method = javaClass.getMethodBySignature(methodName, new String[] {TYPE_INTEGER});
+                    if (method == null) {
+                        // if this is a deactivate method, we have two
+                        // additional possibilities
+                        // a method with parameter of type int and one of type
+                        // Integer
+                        if (!isActivate) {
+                            method = this.getMethod(ctx, methodName, new String[] { TYPE_INT });
+                            if (method == null) {
+                                method = this.getMethod(ctx, methodName, new String[] { TYPE_INTEGER });
                             }
                         }
+                    }
 
-                        // fourth candidate is (de)activate with two or three arguments (type must be BundleContext, ComponentCtx and Map)
-                        // as we have to iterate now and the fifth candidate is zero arguments
+                    if (method == null) {
+                        // fourth candidate is (de)activate with two or three
+                        // arguments (type must be BundleContext, ComponentCtx
+                        // and Map)
+                        // as we have to iterate now and the fifth candidate is
+                        // zero arguments
                         // we already store this option
-                        JavaMethod zeroArgMethod = null;
-                        JavaMethod found = method;
-                        final JavaMethod[] methods = javaClass.getMethods();
+                        Method zeroArgMethod = null;
+                        Method found = method;
+                        final Method[] methods = ctx.getClassDescription().getDescribedClass().getDeclaredMethods();
                         int i = 0;
-                        while ( i < methods.length ) {
-                            if ( methodName.equals(methods[i].getName()) ) {
+                        while (i < methods.length) {
+                            if (methodName.equals(methods[i].getName())) {
 
-                                if ( methods[i].getParameters().length == 0 ) {
+                                if (methods[i].getParameterTypes() == null || methods[i].getParameterTypes().length == 0) {
                                     zeroArgMethod = methods[i];
-                                } else if ( methods[i].getParameters().length >= 2 ) {
+                                } else if (methods[i].getParameterTypes().length >= 2) {
                                     boolean valid = true;
-                                    for(int m=0; m<methods[i].getParameters().length; m++) {
-                                        final String type = methods[i].getParameters()[m].getType();
-                                        if ( !type.equals(TYPE_BUNDLE_CONTEXT)
-                                              && !type.equals(TYPE_COMPONENT_CONTEXT)
-                                              && !type.equals(TYPE_MAP) ) {
-                                            // if this is deactivate, int and integer are possible as well
-                                            if ( isActivate || (!type.equals(TYPE_INT) && !type.equals(TYPE_INTEGER)) ) {
+                                    for (int m = 0; m < methods[i].getParameterTypes().length; m++) {
+                                        final String type = methods[i].getParameterTypes()[m].getName();
+                                        if (!type.equals(TYPE_BUNDLE_CONTEXT) && !type.equals(TYPE_COMPONENT_CONTEXT)
+                                            && !type.equals(TYPE_MAP)) {
+                                            // if this is deactivate, int and
+                                            // integer are possible as well
+                                            if (isActivate || (!type.equals(TYPE_INT) && !type.equals(TYPE_INTEGER))) {
                                                 valid = false;
                                             }
                                         }
                                     }
-                                    if ( valid ) {
-                                        if ( found == null ) {
+                                    if (valid) {
+                                        if (found == null) {
                                             found = methods[i];
                                         } else {
                                             // print warning
-                                            this.logWarn( iLog, "Lifecycle method " + methods[i].getName()
-                                                + " occurs several times with different matching signature." );
+                                            this.logWarn(ctx.getIssueLog(), "Lifecycle method " + methods[i].getName()
+                                                      + " occurs several times with different matching signature.");
                                         }
                                     }
                                 }
                             }
                             i++;
                         }
-                        if ( found != null ) {
+                        if (found != null) {
                             method = found;
                         } else {
                             method = zeroArgMethod;
@@ -444,30 +469,31 @@
                     }
                 }
             }
-            // if no method is found, we check for any method with that name to print some warnings!
-            if ( method == null ) {
-                final JavaMethod[] methods = javaClass.getMethods();
-                for(int i=0; i<methods.length; i++) {
-                    if ( methodName.equals(methods[i].getName()) ) {
-                        if ( methods[i].getParameters().length != 1 ) {
-                            this.logWarn( iLog, "Lifecycle method " + methods[i].getName()
-                                + " has wrong number of arguments" );
-                        } else {
-                            this.logWarn( iLog, "Lifecycle method " + methods[i].getName() + " has wrong argument "
-                                + methods[i].getParameters()[0].getType() );
-                        }
+        }
+        // if no method is found, we check for any method with that name to print some warnings!
+        if (method == null) {
+           final Method[] methods = ctx.getClassDescription().getDescribedClass().getDeclaredMethods();
+            for (int i = 0; i < methods.length; i++) {
+                if (methodName.equals(methods[i].getName())) {
+                    if (methods[i].getParameterTypes() == null || methods[i].getParameterTypes().length != 1) {
+                        this.logWarn(ctx.getIssueLog(), "Lifecycle method " + methods[i].getName() + " has wrong number of arguments");
+                    } else {
+                        this.logWarn(ctx.getIssueLog(),
+                            "Lifecycle method " + methods[i].getName() + " has wrong argument "
+                            + methods[i].getParameterTypes()[0].getName());
                     }
                 }
             }
         }
+
         // method must be protected for version 1.0
-        if ( method != null && specVersion == Constants.VERSION_1_0) {
+        if (method != null && specVersion == SpecVersion.VERSION_1_0) {
             // check protected
-            if (method.isPublic()) {
-                this.logWarn( iLog, "Lifecycle method " + method.getName() + " should be declared protected" );
-            } else if (!method.isProtected()) {
-                this.logWarn( iLog, "Lifecycle method " + method.getName()
-                    + " has wrong qualifier, public or protected required" );
+            if (Modifier.isPublic(method.getModifiers())) {
+                this.logWarn(ctx.getIssueLog(), "Lifecycle method " + method.getName() + " should be declared protected");
+            } else if (!Modifier.isProtected(method.getModifiers())) {
+                this.logWarn(ctx.getIssueLog(), "Lifecycle method " + method.getName() +
+                            " has wrong qualifier, public or protected required");
             }
         }
     }
@@ -475,34 +501,27 @@
     /**
      * Return the configuration policy.
      */
-    public String getConfigurationPolicy() {
+    public ComponentConfigurationPolicy getConfigurationPolicy() {
         return this.configurationPolicy;
     }
 
     /**
      * Set the configuration policy.
      */
-    public void setConfigurationPolicy(final String value) {
+    public void setConfigurationPolicy(final ComponentConfigurationPolicy value) {
         this.configurationPolicy = value;
     }
 
     @Override
     public String toString() {
-        return "Component " + this.name + " (" +
-          "enabled=" + (enabled==null?"<notset>":enabled) +
-          ", immediate=" + (immediate == null?"<notset>":immediate) +
-          ", abstract=" + isAbstract +
-          ", isDS=" + isDs +
-          (factory != null ? ", factory="+factory:"")+
-          (configurationPolicy != null ? ", configurationPolicy=" + configurationPolicy : "") +
-          (activate != null ? ", activate=" + activate : "") +
-          (deactivate != null ? ", deactivate=" + deactivate : "") +
-          (modified != null ? ", modified=" + modified : "") +
-          ", specVersion=" + specVersion +
-          ", implementation=" + implementation +
-          ", service=" + service +
-          ", properties=" + properties +
-          ", references=" + references +
-          ")";
+        return "Component " + this.name + " (" + "enabled=" + (enabled == null ? "<notset>" : enabled) + ", immediate="
+                        + (immediate == null ? "<notset>" : immediate) + ", abstract=" + isAbstract + ", isDS=" + isDs
+                        + (factory != null ? ", factory=" + factory : "")
+                        + (configurationPolicy != null ? ", configurationPolicy=" + configurationPolicy : "")
+                        + (activate != null ? ", activate=" + activate : "")
+                        + (deactivate != null ? ", deactivate=" + deactivate : "")
+                        + (modified != null ? ", modified=" + modified : "") + ", specVersion=" + specVersion
+                        + ", implementation=" + implementation + ", service=" + service + ", properties=" + properties
+                        + ", references=" + references + ")";
     }
 }
\ No newline at end of file
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Components.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Components.java
index 208bdc9..f50adee 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Components.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Components.java
@@ -21,6 +21,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.felix.scrplugin.description.SpecVersion;
+
 /**
  * <code>Components</code>...
  *
@@ -29,10 +31,10 @@
 public class Components {
 
     /** The spec version. */
-    private int specVersion;
+    private SpecVersion specVersion;
 
     /** The list of {@link Component}s. */
-    protected List<Component> components = new ArrayList<Component>();
+    private List<Component> components = new ArrayList<Component>();
 
     /**
      * Return the list of {@link Component}s.
@@ -58,14 +60,14 @@
     /**
      * Get the spec version.
      */
-    public int getSpecVersion() {
+    public SpecVersion getSpecVersion() {
         return this.specVersion;
     }
 
     /**
      * Set the spec version.
      */
-    public void setSpecVersion(int value) {
+    public void setSpecVersion(SpecVersion value) {
         this.specVersion = value;
     }
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Context.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Context.java
new file mode 100644
index 0000000..5654978
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Context.java
@@ -0,0 +1,78 @@
+/*
+ * 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.scrplugin.om;
+
+import org.apache.felix.scrplugin.Options;
+import org.apache.felix.scrplugin.Project;
+import org.apache.felix.scrplugin.description.ClassDescription;
+import org.apache.felix.scrplugin.description.SpecVersion;
+import org.apache.felix.scrplugin.helper.IssueLog;
+
+public class Context {
+
+    private Project project;
+
+    private IssueLog issueLog;
+
+    private SpecVersion specVersion;
+
+    private ClassDescription classDescription;
+
+    private Options options;
+
+    public Project getProject() {
+        return project;
+    }
+
+    public void setProject(Project project) {
+        this.project = project;
+    }
+
+    public IssueLog getIssueLog() {
+        return issueLog;
+    }
+
+    public void setIssueLog(IssueLog issueLog) {
+        this.issueLog = issueLog;
+    }
+
+    public SpecVersion getSpecVersion() {
+        return specVersion;
+    }
+
+    public void setSpecVersion(SpecVersion specVersion) {
+        this.specVersion = specVersion;
+    }
+
+    public ClassDescription getClassDescription() {
+        return classDescription;
+    }
+
+    public void setClassDescription(ClassDescription classDescription) {
+        this.classDescription = classDescription;
+    }
+
+    public Options getOptions() {
+        return options;
+    }
+
+    public void setOptions(Options options) {
+        this.options = options;
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Implementation.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Implementation.java
index 37e78b8..bcbe387 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Implementation.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Implementation.java
@@ -19,30 +19,20 @@
 package org.apache.felix.scrplugin.om;
 
 /**
- * <code>Implementation</code>...
- *
+ * <code>Implementation</code>
+ * 
  * contains the class name implementing the component.
  */
 public class Implementation {
 
     /** The class name. */
-    protected String classname;
+    private final String className;
 
-    public Implementation() {
-        // nothing to do
+    public Implementation(final String name) {
+        this.className = name;
     }
 
-    public Implementation(String name) {
-        this.classname = name;
+    public String getClassName() {
+        return this.className;
     }
-
-    public String getClassame() {
-        return this.classname;
-    }
-
-    public void setClassname(String name) {
-        this.classname = name;
-    }
-
-
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Interface.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Interface.java
index 9f55f6d..d53d80f 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Interface.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Interface.java
@@ -19,38 +19,38 @@
 package org.apache.felix.scrplugin.om;
 
 import org.apache.felix.scrplugin.SCRDescriptorException;
-import org.apache.felix.scrplugin.helper.IssueLog;
-import org.apache.felix.scrplugin.tags.JavaClassDescription;
-import org.apache.felix.scrplugin.tags.JavaTag;
+import org.apache.felix.scrplugin.scanner.ScannedAnnotation;
 
 /**
- * <code>Interface.java</code>...
+ * <code>Interface</code>
  *
+ * contains an interface name the component is implementing
+ * (the interface name can also be a class name)
  */
 public class Interface extends AbstractObject {
 
-    protected String interfacename;
-
-    /**
-     * Default constructor.
-     */
-    public Interface() {
-        this(null);
-    }
+    /** Name of the interface. */
+    private String interfaceName;
 
     /**
      * Constructor from java source.
      */
-    public Interface(JavaTag t) {
-        super(t);
+    public Interface(final ScannedAnnotation annotation, final String sourceLocation) {
+        super(annotation, sourceLocation);
     }
 
-    public String getInterfacename() {
-        return this.interfacename;
+    /**
+     * Get the interface name.
+     */
+    public String getInterfaceName() {
+        return this.interfaceName;
     }
 
-    public void setInterfacename(String name) {
-        this.interfacename = name;
+    /**
+     * Set the interface name.
+     */
+    public void setInterfaceName(final String name) {
+        this.interfaceName = name;
     }
 
     /**
@@ -58,16 +58,18 @@
      * If errors occur a message is added to the issues list,
      * warnings can be added to the warnings list.
      */
-    public void validate(final int specVersion, final IssueLog iLog)
-    throws SCRDescriptorException {
-        final JavaClassDescription javaClass = this.tag.getJavaClassDescription();
-        if (javaClass == null) {
-            this.logError( iLog, "Must be declared in a Java class" );
+    public void validate(final Context context) throws SCRDescriptorException {
+        if (context.getClassDescription().getDescribedClass().isInterface()) {
+            this.logError(context.getIssueLog(), "Must be declared in a Java class - not an interface");
         } else {
-
-            if ( !javaClass.isA(this.getInterfacename()) ) {
-               // interface not implemented
-                this.logError( iLog, "Class must implement provided interface " + this.getInterfacename() );
+            try {
+                final Class<?> interfaceClass = context.getProject().getClassLoader().loadClass(this.interfaceName);
+                if (!interfaceClass.isAssignableFrom(context.getClassDescription().getDescribedClass())) {
+                    // interface not implemented
+                    this.logError(context.getIssueLog(), "Class must implement provided interface " + this.interfaceName);
+                }
+            } catch (final ClassNotFoundException cnfe) {
+                throw new SCRDescriptorException("Unable to load interface class.", cnfe);
             }
         }
     }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Property.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Property.java
index 7ccd04d..a26c5a4 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Property.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Property.java
@@ -18,9 +18,9 @@
  */
 package org.apache.felix.scrplugin.om;
 
-import org.apache.felix.scrplugin.Constants;
-import org.apache.felix.scrplugin.helper.IssueLog;
-import org.apache.felix.scrplugin.tags.JavaTag;
+import org.apache.felix.scrplugin.description.PropertyType;
+import org.apache.felix.scrplugin.description.SpecVersion;
+import org.apache.felix.scrplugin.scanner.ScannedAnnotation;
 
 /**
  * <code>Property.java</code>...
@@ -30,26 +30,14 @@
 
     protected String name;
     protected String value;
-    protected String type;
+    protected PropertyType type;
     protected String[] multiValue;
 
-    protected boolean isPrivate;
-    protected String label;
-    protected String description;
-    protected String cardinality;
-
-    /**
-     * Default constructor.
-     */
-    public Property() {
-        this(null);
-    }
-
     /**
      * Constructor from java source.
      */
-    public Property(JavaTag t) {
-        super(t);
+    public Property(final ScannedAnnotation annotation, final String sourceLocation) {
+        super(annotation, sourceLocation);
     }
 
     public String getName() {
@@ -69,11 +57,11 @@
         this.multiValue = null;
     }
 
-    public String getType() {
+    public PropertyType getType() {
         return this.type;
     }
 
-    public void setType(String type) {
+    public void setType(PropertyType type) {
         this.type = type;
     }
 
@@ -91,64 +79,20 @@
      * If errors occur a message is added to the issues list,
      * warnings can be added to the warnings list.
      */
-    public void validate(final int specVersion, final IssueLog iLog) {
-        if ( name == null || name.trim().length() == 0 ) {
-            this.logError( iLog, "Property name can not be empty." );
+    public void validate(final Context context) {
+        if (name == null || name.trim().length() == 0) {
+            this.logError(context.getIssueLog(), "Property name can not be empty.");
         }
-        if ( type != null ) {
-            if ( !type.equals(Constants.PROPERTY_TYPE_BOOLEAN)
-                 && !type.equals(Constants.PROPERTY_TYPE_BYTE )
-                 && !type.equals(Constants.PROPERTY_TYPE_CHAR )
-                 && !type.equals(Constants.PROPERTY_TYPE_CHAR_1_1 )
-                 && !type.equals(Constants.PROPERTY_TYPE_DOUBLE )
-                 && !type.equals(Constants.PROPERTY_TYPE_FLOAT )
-                 && !type.equals(Constants.PROPERTY_TYPE_INTEGER )
-                 && !type.equals(Constants.PROPERTY_TYPE_LONG )
-                 && !type.equals(Constants.PROPERTY_TYPE_STRING )
-                 && !type.equals(Constants.PROPERTY_TYPE_SHORT ) ) {
-                this.logError( iLog, "Property " + name + " has unknown type: " + type );
-            }
+        if (type != null) {
             // now check for old and new char
-            if ( specVersion == Constants.VERSION_1_0 && type.equals(Constants.PROPERTY_TYPE_CHAR_1_1) ) {
-                type = Constants.PROPERTY_TYPE_CHAR;
+            if (context.getSpecVersion() == SpecVersion.VERSION_1_0 && type == PropertyType.Character) {
+                type = PropertyType.Char;
             }
-            if ( specVersion >= Constants.VERSION_1_1 && type.equals(Constants.PROPERTY_TYPE_CHAR) ) {
-                type = Constants.PROPERTY_TYPE_CHAR_1_1;
+            if (context.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal()
+                            && type == PropertyType.Char) {
+                type = PropertyType.Character;
             }
         }
         // TODO might want to check value
     }
-
-    public boolean isPrivate() {
-        return isPrivate;
-    }
-
-    public void setPrivate(boolean isPrivate) {
-        this.isPrivate = isPrivate;
-    }
-
-    public String getLabel() {
-        return label;
-    }
-
-    public void setLabel(String label) {
-        this.label = label;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    public String getCardinality() {
-        return cardinality;
-    }
-
-    public void setCardinality(String cardinality) {
-        this.cardinality = cardinality;
-    }
-
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Reference.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Reference.java
index 2186ece..4cff9a4 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Reference.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Reference.java
@@ -18,11 +18,18 @@
  */
 package org.apache.felix.scrplugin.om;
 
-import org.apache.felix.scrplugin.Constants;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Map;
+
 import org.apache.felix.scrplugin.SCRDescriptorException;
-import org.apache.felix.scrplugin.helper.IssueLog;
+import org.apache.felix.scrplugin.description.ReferenceCardinality;
+import org.apache.felix.scrplugin.description.ReferencePolicy;
+import org.apache.felix.scrplugin.description.ReferenceStrategy;
+import org.apache.felix.scrplugin.description.SpecVersion;
 import org.apache.felix.scrplugin.helper.StringUtils;
-import org.apache.felix.scrplugin.tags.*;
+import org.apache.felix.scrplugin.scanner.ScannedAnnotation;
 
 /**
  * <code>Reference.java</code>...
@@ -33,34 +40,22 @@
     protected String name;
     protected String interfacename;
     protected String target;
-    protected String cardinality;
-    protected String policy;
+    protected ReferenceCardinality cardinality;
+    protected ReferencePolicy policy;
     protected String bind;
     protected String unbind;
     protected String updated;
 
     /** @since 1.0.9 */
-    protected String strategy;
+    protected ReferenceStrategy strategy;
 
-    /** Is this reference already checked? */
-    protected boolean checked = false;
-
-    /** The class description containing this reference. */
-    protected final JavaClassDescription javaClassDescription;
-
-    /**
-     * Default constructor.
-     */
-    public Reference() {
-        this(null, null);
-    }
+    private Field field;
 
     /**
      * Constructor from java source.
      */
-    public Reference(JavaTag t, JavaClassDescription desc) {
-        super(t);
-        this.javaClassDescription = desc;
+    public Reference(final ScannedAnnotation annotation, final String sourceLocation) {
+        super(annotation, sourceLocation);
     }
 
     public String getName() {
@@ -71,6 +66,14 @@
         this.name = name;
     }
 
+    public Field getField() {
+        return this.field;
+    }
+
+    public void setField(Field field) {
+        this.field = field;
+    }
+
     public String getInterfacename() {
         return this.interfacename;
     }
@@ -87,19 +90,19 @@
         this.target = target;
     }
 
-    public String getCardinality() {
+    public ReferenceCardinality getCardinality() {
         return this.cardinality;
     }
 
-    public void setCardinality(String cardinality) {
+    public void setCardinality(ReferenceCardinality cardinality) {
         this.cardinality = cardinality;
     }
 
-    public String getPolicy() {
+    public ReferencePolicy getPolicy() {
         return this.policy;
     }
 
-    public void setPolicy(String policy) {
+    public void setPolicy(ReferencePolicy policy) {
         this.policy = policy;
     }
 
@@ -127,27 +130,19 @@
         this.updated = updated;
     }
 
-    public boolean isChecked() {
-        return checked;
-    }
-
-    public void setChecked(boolean checked) {
-        this.checked = checked;
-    }
-
     /** @since 1.0.9 */
-    public String getStrategy() {
+    public ReferenceStrategy getStrategy() {
         return strategy;
     }
 
     /** @since 1.0.9 */
-    public void setStrategy(String strategy) {
+    public void setStrategy(ReferenceStrategy strategy) {
         this.strategy = strategy;
     }
 
     /** @since 1.0.9 */
     public boolean isLookupStrategy() {
-        return Constants.REFERENCE_STRATEGY_LOOKUP.equals(getStrategy());
+        return this.getStrategy() == ReferenceStrategy.LOOKUP;
     }
 
     /**
@@ -155,76 +150,71 @@
      * If errors occur a message is added to the issues list,
      * warnings can be added to the warnings list.
      */
-    public void validate(final int specVersion,
-                         final boolean componentIsAbstract,
-                         final IssueLog iLog)
+    public void validate(final Context context, final boolean componentIsAbstract)
     throws SCRDescriptorException {
-        // if this reference is already checked, return immediately
-        if ( this.checked ) {
-            return;
-        }
-        final int currentIssueCount = iLog.getNumberOfErrors();
+        final int currentIssueCount = context.getIssueLog().getNumberOfErrors();
 
         // validate name
         if (StringUtils.isEmpty(this.name)) {
-            if ( specVersion < Constants.VERSION_1_1 ) {
-                this.logError( iLog, "Reference has no name" );
+            if (context.getSpecVersion().ordinal() < SpecVersion.VERSION_1_1.ordinal() ) {
+                this.logError(context.getIssueLog(), "Reference has no name");
             }
         }
 
         // validate interface
         if (StringUtils.isEmpty(this.interfacename)) {
-            this.logError( iLog, "Missing interface name" );
+            this.logError(context.getIssueLog(), "Missing interface name");
+        }
+        try {
+            context.getProject().getClassLoader().loadClass(this.interfacename);
+        } catch (final ClassNotFoundException e) {
+            this.logError(context.getIssueLog(), "Interface class can't be loaded: " + this.interfacename);
         }
 
         // validate cardinality
         if (this.cardinality == null) {
-            this.cardinality = "1..1";
-        } else if (!"0..1".equals(this.cardinality) && !"1..1".equals(this.cardinality)
-            && !"0..n".equals(this.cardinality) && !"1..n".equals(this.cardinality)) {
-            this.logError( iLog, "Invalid Cardinality specification " + this.cardinality );
+            this.cardinality = ReferenceCardinality.MANDATORY_UNARY;
         }
 
         // validate policy
         if (this.policy == null) {
-            this.policy = "static";
-        } else if (!"static".equals(this.policy) && !"dynamic".equals(this.policy)) {
-            this.logError( iLog, "Invalid Policy specification " + this.policy );
+            this.policy = ReferencePolicy.STATIC;
         }
 
         // validate strategy
         if (this.strategy == null) {
-            this.strategy = Constants.REFERENCE_STRATEGY_EVENT;
-        } else if (!Constants.REFERENCE_STRATEGY_EVENT.equals(this.strategy)
-                   && !Constants.REFERENCE_STRATEGY_LOOKUP.equals(this.strategy)) {
-            this.logError( iLog, "Invalid strategy type " + this.strategy );
+            this.strategy = ReferenceStrategy.EVENT;
         }
 
         // validate bind and unbind methods
         if (!isLookupStrategy()) {
-            // set default values
-            if ( this.bind == null ) {
-                this.setBind("bind");
+            String bindName = this.bind;
+            String unbindName = this.unbind;
+
+            final boolean canGenerate = context.getOptions().isGenerateAccessors() &&
+                            !this.isLookupStrategy() && this.getField() != null
+                            && (this.getCardinality() == ReferenceCardinality.OPTIONAL_UNARY || this.getCardinality() == ReferenceCardinality.MANDATORY_UNARY);
+            if (bindName == null && !canGenerate ) {
+                bindName = "bind";
             }
-            if ( this.unbind == null ) {
-                this.setUnbind("unbind");
+            if (unbindName == null && !canGenerate ) {
+                unbindName = "unbind";
             }
-            final String oldBind = this.bind;
-            final String oldUnbind = this.unbind;
-            this.bind = this.validateMethod(specVersion, this.bind, componentIsAbstract, iLog);
-            this.unbind = this.validateMethod(specVersion, this.unbind, componentIsAbstract, iLog);
-            if ( iLog.getNumberOfErrors() == currentIssueCount ) {
-                if ( this.bind != null && this.unbind != null ) {
-                    // no errors, so we're checked
-                    this.checked = true;
-                } else {
-                    if ( this.bind == null ) {
-                        this.bind = oldBind;
-                    }
-                    if ( this.unbind == null ) {
-                        this.unbind = oldUnbind;
-                    }
-                }
+
+            if ( bindName != null ) {
+                bindName = this.validateMethod(context, bindName, componentIsAbstract);
+            } else {
+                bindName = "bind" + Character.toUpperCase(this.name.charAt(0)) + this.name.substring(1);
+            }
+            if ( unbindName != null ) {
+                unbindName = this.validateMethod(context, unbindName, componentIsAbstract);
+            } else {
+                unbindName = "unbind" + Character.toUpperCase(this.name.charAt(0)) + this.name.substring(1);
+            }
+
+            if (context.getIssueLog().getNumberOfErrors() == currentIssueCount) {
+                this.bind = bindName;
+                this.unbind = unbindName;
             }
         } else {
             this.bind = null;
@@ -232,33 +222,33 @@
         }
 
         // validate updated method
-        if ( this.updated != null ) {
-            if ( specVersion < Constants.VERSION_1_1_FELIX ) {
-                this.logError( iLog, "Updated method declaration requires namespace "
-                    + Constants.COMPONENT_DS_SPEC_VERSION_11_FELIX + " or newer" );
+        if (this.updated != null) {
+            if (context.getSpecVersion().ordinal() < SpecVersion.VERSION_1_1_FELIX.ordinal()) {
+                this.logError(context.getIssueLog(), "Updated method declaration requires version "
+                                + SpecVersion.VERSION_1_1_FELIX.getName() + " or newer");
             }
         }
+
     }
 
-    protected String validateMethod(final int      specVersion,
-                                    final String   methodName,
-                                    final boolean  componentIsAbstract,
-                                    final IssueLog iLog)
+    private String validateMethod(final Context ctx, final String methodName, final boolean componentIsAbstract)
     throws SCRDescriptorException {
-        final JavaMethod method = this.findMethod(specVersion, methodName);
+        final Method method = this.findMethod(ctx, methodName);
         if (method == null) {
-            if ( !componentIsAbstract ) {
-                this.logError( iLog, "Missing method " + methodName + " for reference " + (this.getName() == null ? "" : this.getName()));
+            if (!componentIsAbstract) {
+                this.logError(ctx.getIssueLog(),
+                                "Missing method " + methodName + " for reference "
+                                                + (this.getName() == null ? "" : this.getName()));
             }
             return null;
         }
 
         // method needs to be protected for 1.0
-        if ( specVersion == Constants.VERSION_1_0 ) {
-            if (method.isPublic()) {
-                this.logWarn( iLog, "Method " + method.getName() + " should be declared protected" );
-            } else if (!method.isProtected()) {
-                this.logError( iLog, "Method " + method.getName() + " has wrong qualifier, public or protected required" );
+        if (ctx.getSpecVersion() == SpecVersion.VERSION_1_0) {
+            if (Modifier.isPublic(method.getModifiers())) {
+                this.logWarn(ctx.getIssueLog(), "Method " + method.getName() + " should be declared protected");
+            } else if (!Modifier.isProtected(method.getModifiers())) {
+                this.logError(ctx.getIssueLog(), "Method " + method.getName() + " has wrong qualifier, public or protected required");
                 return null;
             }
         }
@@ -266,61 +256,73 @@
     }
 
     private static final String TYPE_SERVICE_REFERENCE = "org.osgi.framework.ServiceReference";
-    private static final String TYPE_MAP = "java.util.Map";
 
-    public JavaMethod findMethod(final int    specVersion,
-                                 final String methodName)
+    private Method getMethod(final Context ctx, final String name, final Class<?>[] sig) {
+        try {
+            return ctx.getClassDescription().getDescribedClass().getDeclaredMethod(name, sig);
+        } catch (final SecurityException e) {
+            // ignore
+        } catch (final NoSuchMethodException e) {
+            // ignore
+        }
+        return null;
+    }
+
+    public Method findMethod(final Context ctx, final String methodName)
     throws SCRDescriptorException {
-        final String[] sig = new String[]{ TYPE_SERVICE_REFERENCE };
-        final String[] sig2 = new String[]{ this.getInterfacename() };
-        final String[] sig3 = new String[]{ this.getInterfacename(), TYPE_MAP};
+        try {
+            final Class<?>[] sig = new Class<?>[] { ctx.getProject().getClassLoader().loadClass(TYPE_SERVICE_REFERENCE) };
+            final Class<?>[] sig2 = new Class<?>[] {ctx.getProject().getClassLoader().loadClass(this.interfacename) };
+            final Class<?>[] sig3 = new Class<?>[] { ctx.getProject().getClassLoader().loadClass(this.interfacename), Map.class };
 
-        // service interface or ServiceReference first
-        String realMethodName = methodName;
-        JavaMethod method = this.javaClassDescription.getMethodBySignature(realMethodName, sig);
-        if (method == null) {
-            method = this.javaClassDescription.getMethodBySignature(realMethodName, sig2);
-            if ( specVersion >= Constants.VERSION_1_1 && method == null ) {
-                method = this.javaClassDescription.getMethodBySignature(realMethodName, sig3);
+            // service interface or ServiceReference first
+            String realMethodName = methodName;
+            Method method = getMethod(ctx, realMethodName, sig);
+            if (method == null) {
+                method = getMethod(ctx, realMethodName, sig2);
+                if (method == null && ctx.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
+                    method = getMethod(ctx, realMethodName, sig3);
+                }
             }
-        }
 
-        // append reference name with service interface and ServiceReference
-        if (method == null) {
-            final String info;
-            if (StringUtils.isEmpty(this.name)) {
-                final String interfaceName = this.getInterfacename();
-                final int pos = interfaceName.lastIndexOf('.');
-                info = interfaceName.substring(pos + 1);
-            } else {
-                info = this.name;
+            // append reference name with service interface and ServiceReference
+            if (method == null) {
+                final String info;
+                if (StringUtils.isEmpty(this.name)) {
+                    final String interfaceName = this.getInterfacename();
+                    final int pos = interfaceName.lastIndexOf('.');
+                    info = interfaceName.substring(pos + 1);
+                } else {
+                    info = this.name;
+                }
+                realMethodName = methodName + Character.toUpperCase(info.charAt(0)) + info.substring(1);
+
+                method = getMethod(ctx, realMethodName, sig);
             }
-            realMethodName = methodName + Character.toUpperCase(info.charAt(0)) + info.substring(1);
-
-            method = this.javaClassDescription.getMethodBySignature(realMethodName, sig);
-        }
-        if (method == null) {
-            method = this.javaClassDescription.getMethodBySignature(realMethodName, sig2);
-            if ( specVersion >= Constants.VERSION_1_1 && method == null ) {
-                method = this.javaClassDescription.getMethodBySignature(realMethodName, sig3);
+            if (method == null) {
+                method = getMethod(ctx, realMethodName, sig2);
+                if (method == null && ctx.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
+                    method = getMethod(ctx, realMethodName, sig3);
+                }
             }
-        }
 
-        // append type name with service interface and ServiceReference
-        if (method == null) {
-            int lastDot = this.getInterfacename().lastIndexOf('.');
-            realMethodName = methodName
-                + this.getInterfacename().substring(lastDot + 1);
-            method = this.javaClassDescription.getMethodBySignature(realMethodName, sig);
-        }
-        if (method == null) {
-            method = this.javaClassDescription.getMethodBySignature(realMethodName, sig2);
-            if ( specVersion >= Constants.VERSION_1_1 && method == null ) {
-                method = this.javaClassDescription.getMethodBySignature(realMethodName, sig3);
+            // append type name with service interface and ServiceReference
+            if (method == null) {
+                int lastDot = this.getInterfacename().lastIndexOf('.');
+                realMethodName = methodName + this.getInterfacename().substring(lastDot + 1);
+                method = getMethod(ctx, realMethodName, sig);
             }
-        }
+            if (method == null) {
+                method = getMethod(ctx, realMethodName, sig2);
+                if (method == null && ctx.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
+                    method = getMethod(ctx, realMethodName, sig3);
+                }
+            }
 
-        return method;
+            return method;
+        } catch (final ClassNotFoundException cnfe) {
+            throw new SCRDescriptorException("Unable to load class!", cnfe);
+        }
     }
 
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Service.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Service.java
index 49354ac..216d445 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Service.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Service.java
@@ -23,54 +23,53 @@
 import java.util.List;
 
 import org.apache.felix.scrplugin.SCRDescriptorException;
-import org.apache.felix.scrplugin.helper.IssueLog;
 
 /**
- * <code>Service</code>...
- *
+ * <code>Service</code>
+ * 
+ * contains all service information of a component.
  */
 public class Service {
 
-    protected boolean isServicefactory;
+    /** Flag for the service factory. */
+    private boolean isServiceFactory;
 
     /** The list of implemented interfaces. */
-    protected final List<Interface> interfaces = new ArrayList<Interface>();
+    private final List<Interface> interfaces = new ArrayList<Interface>();
 
     /**
-     * Default constructor.
+     * Is this a service factory?
      */
-    public Service() {
-        // nothing to do
+    public boolean isServiceFactory() {
+        return this.isServiceFactory;
     }
 
-    public boolean isServicefactory() {
-        return this.isServicefactory;
+    /**
+     * Set the service factory flag.
+     */
+    public void setServiceFactory(final boolean flag) {
+        this.isServiceFactory = flag;
     }
 
-    public void setServicefactory(String servicefactory) {
-        if ( servicefactory != null ) {
-            this.isServicefactory = Boolean.valueOf(servicefactory).booleanValue();
-        }
-    }
-
-    public void setServicefactory(boolean flag) {
-        this.isServicefactory = flag;
-    }
-
+    /**
+     * Return the list of interfaces.
+     */
     public List<Interface> getInterfaces() {
         return this.interfaces;
     }
 
     /**
      * Search for an implemented interface.
-     * @param name The name of the interface.
+     * 
+     * @param name
+     *            The name of the interface.
      * @return The interface if it is implemented by this service or null.
      */
-    public Interface findInterface(String name) {
+    public Interface findInterface(final String name) {
         final Iterator<Interface> i = this.getInterfaces().iterator();
-        while ( i.hasNext() ) {
+        while (i.hasNext()) {
             final Interface current = i.next();
-            if ( current.getInterfacename().equals(name) ) {
+            if (current.getInterfaceName().equals(name)) {
                 return current;
             }
         }
@@ -79,11 +78,13 @@
 
     /**
      * Add an interface to the list of interfaces.
-     * @param interf The interface.
+     * 
+     * @param interf
+     *            The interface.
      */
-    public void addInterface(Interface interf) {
+    public void addInterface(final Interface interf) {
         // add interface only once
-        if ( this.findInterface(interf.getInterfacename()) == null ) {
+        if (this.findInterface(interf.getInterfaceName()) == null) {
             this.interfaces.add(interf);
         }
     }
@@ -93,11 +94,9 @@
      * If errors occur a message is added to the issues list,
      * warnings can be added to the warnings list.
      */
-    public void validate(final int specVersion, final IssueLog iLog)
-    throws SCRDescriptorException {
-        for(final Interface interf : this.getInterfaces()) {
-            interf.validate(specVersion, iLog);
+    public void validate(final Context context) throws SCRDescriptorException {
+        for (final Interface interf : this.getInterfaces()) {
+            interf.validate(context);
         }
     }
-
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/package-info.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/ClassAnnotation.java
similarity index 66%
copy from scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/package-info.java
copy to scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/ClassAnnotation.java
index a00ab18..176db6a 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/package-info.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/ClassAnnotation.java
@@ -16,8 +16,19 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * Extracting SCR tags from source file declared as Java 1.5 annotations.   
- */
-package org.apache.felix.scrplugin.tags.annotation;
+package org.apache.felix.scrplugin.scanner;
 
+import java.util.Map;
+
+public class ClassAnnotation extends ScannedAnnotation {
+
+    public ClassAnnotation(final String name, final Map<String, Object> values) {
+        super(name, values);
+    }
+
+    @Override
+    public String toString() {
+        return "ClassAnnotationDescription [name=" + name + ", values="
+                + values + "]";
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/FieldAnnotation.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/FieldAnnotation.java
new file mode 100644
index 0000000..79c7b87
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/FieldAnnotation.java
@@ -0,0 +1,61 @@
+/*
+ * 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.scrplugin.scanner;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Map;
+
+import org.apache.felix.scrplugin.SCRDescriptorException;
+import org.apache.felix.scrplugin.SCRDescriptorFailureException;
+
+public class FieldAnnotation extends ScannedAnnotation {
+
+    private final Field annotatedField;
+
+    public FieldAnnotation(final String name, final Map<String, Object> values, final Field f) {
+        super(name, values);
+        this.annotatedField = f;
+    }
+
+    public Field getAnnotatedField() {
+        return this.annotatedField;
+    }
+
+    public Object getAnnotatedFieldValue()
+    throws SCRDescriptorFailureException, SCRDescriptorException {
+        if ( Modifier.isStatic(annotatedField.getModifiers()) ) {
+            try {
+                final Object value = annotatedField.get(null);
+                return value;
+            } catch (final IllegalArgumentException e) {
+                throw new SCRDescriptorFailureException("Unable to get initial field value from: " + annotatedField, e);
+            } catch (final IllegalAccessException e) {
+                throw new SCRDescriptorFailureException("Unable to get initial field value from: " + annotatedField, e);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return "FieldAnnotationDescription [name=" + name + ", values="
+                + values + ", annotatedField=" + annotatedField + "]";
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/MethodAnnotation.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/MethodAnnotation.java
new file mode 100644
index 0000000..5f25a13
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/MethodAnnotation.java
@@ -0,0 +1,42 @@
+/*
+ * 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.scrplugin.scanner;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+public class MethodAnnotation extends ScannedAnnotation {
+
+    private final Method method;
+
+    public MethodAnnotation(final String name, final Map<String, Object> values, final Method m) {
+        super(name, values);
+        this.method = m;
+    }
+
+    public Method getAnnotatedMethod() {
+        return this.method;
+    }
+
+    @Override
+    public String toString() {
+        return "MethodAnnotationDescription [name=" + name + ", values="
+                + values + ", method=" + method + "]";
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/ScannedAnnotation.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/ScannedAnnotation.java
new file mode 100644
index 0000000..72ac56e
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/ScannedAnnotation.java
@@ -0,0 +1,109 @@
+/*
+ * 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.scrplugin.scanner;
+
+import java.util.Map;
+
+/**
+ * Base class for all annotation.
+ */
+public abstract class ScannedAnnotation {
+
+    /** The fully qualified class name */
+    protected final String name;
+
+    /** The annotation values. */
+    protected final Map<String, Object> values;
+
+    /**
+     * Create a new description
+     * @param name   The fully qualified class name of the annotation
+     * @param values The properties of the annotation (optional)
+     */
+    public ScannedAnnotation(final String name, final Map<String, Object> values) {
+        this.name = name;
+        this.values = values;
+    }
+
+    /**
+     * Get the fully qualified class name of the annotation.
+     * @return The fully qualified class name of the annotation.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Get a property value of the annotation.
+     * @param paramName The property name.
+     * @return The value of the property or <code>null</code>
+     */
+    public Object getValue(final String paramName) {
+        if ( values != null ) {
+            return values.get(paramName);
+        }
+        return null;
+    }
+
+    public boolean getBooleanValue(final String name, final boolean defaultValue) {
+        final Object val = this.getValue(name);
+        if ( val != null ) {
+            return ((Boolean) val).booleanValue();
+        }
+        return defaultValue;
+    }
+
+    public int getIntegerValue(final String name, final int defaultValue) {
+        final Object val = this.getValue(name);
+        if ( val != null ) {
+            return ((Integer) val).intValue();
+        }
+        return defaultValue;
+    }
+
+    public long getLongValue(final String name, final long defaultValue) {
+        final Object val = this.getValue(name);
+        if ( val != null ) {
+            return ((Long) val).intValue();
+        }
+        return defaultValue;
+    }
+
+    public String getStringValue(final String name, final String defaultValue) {
+        final Object val = this.getValue(name);
+        if ( val != null && val.toString().trim().length() > 0 ) {
+            return val.toString().trim();
+        }
+        return defaultValue;
+    }
+
+    public String getEnumValue(final String name, final String defaultValue) {
+        final Object val = this.getValue(name);
+        if ( val != null ) {
+            return ((String[])val)[1];
+        }
+        return defaultValue;
+    }
+
+    @Override
+    public String toString() {
+        return "AnnotationDescription [name=" + name + ", values=" + values
+                + "]";
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/ScannedClass.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/ScannedClass.java
new file mode 100644
index 0000000..93f1b1b
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/ScannedClass.java
@@ -0,0 +1,93 @@
+/*
+ * 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.scrplugin.scanner;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * A scanned class contains all scanned information
+ * like the found annotations.
+ */
+public class ScannedClass {
+
+    /** All found annotations .*/
+    private final List<ScannedAnnotation> descriptions = new ArrayList<ScannedAnnotation>();
+
+    /** The scanned class. */
+    private final Class<?> scannedClass;
+
+    public ScannedClass(final List<ScannedAnnotation> desc, final Class<?> scannedClass) {
+        this.descriptions.addAll(desc);
+        this.scannedClass = scannedClass;
+    }
+
+    /**
+     * Get the scanned class.
+     * @return The scanned class.
+     */
+    public Class<?> getScannedClass() {
+        return this.scannedClass;
+    }
+
+    public void processed(final ScannedAnnotation desc) {
+        this.descriptions.remove(desc);
+    }
+
+    public void processed(final Collection<? extends ScannedAnnotation> desc) {
+        this.descriptions.removeAll(desc);
+    }
+
+    public List<ClassAnnotation> getClassAnnotations(final String name) {
+        final List<ClassAnnotation> list = new ArrayList<ClassAnnotation>();
+        for(final ScannedAnnotation desc : descriptions ) {
+            if ( desc instanceof ClassAnnotation ) {
+                if ( name == null || desc.getName().equals(name) ) {
+                    list.add( (ClassAnnotation)desc);
+                }
+            }
+        }
+        return list;
+    }
+
+    public List<FieldAnnotation> getFieldAnnotations(final String name) {
+        final List<FieldAnnotation> list = new ArrayList<FieldAnnotation>();
+        for(final ScannedAnnotation desc : descriptions ) {
+            if ( desc instanceof FieldAnnotation ) {
+                if ( name == null || desc.getName().equals(name) ) {
+                    list.add( (FieldAnnotation)desc);
+                }
+            }
+        }
+        return list;
+    }
+
+    public List<MethodAnnotation> getMethodAnnotations(final String name) {
+        final List<MethodAnnotation> list = new ArrayList<MethodAnnotation>();
+        for(final ScannedAnnotation desc : descriptions ) {
+            if ( desc instanceof MethodAnnotation ) {
+                if ( name == null || desc.getName().equals(name) ) {
+                    list.add( (MethodAnnotation)desc);
+                }
+            }
+        }
+        return list;
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaMethod.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/Source.java
similarity index 69%
rename from scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaMethod.java
rename to scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/Source.java
index cf36076..166b55c 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaMethod.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/scanner/Source.java
@@ -16,23 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.scrplugin.tags;
+package org.apache.felix.scrplugin.scanner;
+
+import java.io.File;
 
 /**
- * <code>JavaMethod.java</code>...
- *
+ * Description of a source to be parsed.
  */
-public interface JavaMethod {
+public interface Source {
 
-    JavaMethod[] EMPTY_RESULT = new JavaMethod[0];
+    /**
+     * The main class name.
+     * @return The main class name.
+     */
+    String getClassName();
 
-    boolean isPublic();
-
-    boolean isProtected();
-
-    String getName();
-
-    JavaParameter[] getParameters();
-
-    boolean isConstructor();
+    /**
+     * The file containing the class.
+     * @return The file containing the class.
+     */
+    File getFile();
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/ClassUtil.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/ClassUtil.java
deleted file mode 100644
index 3860364..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/ClassUtil.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.scrplugin.tags;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
-
-/**
- * Utility class.
- */
-public class ClassUtil {
-
-    /**
-     * Try to get the initial value of a static field
-     * @param clazz     The class.
-     * @param fieldName The name of the field.
-     * @return The initial value or null.
-     */
-    public static String[] getInitializationExpression(final Class<?> clazz, final String fieldName)
-    {
-        try
-        {
-            final Field field = clazz.getDeclaredField(fieldName);
-            field.setAccessible(true);
-            final Object value = field.get(null);
-            if ( value != null )
-            {
-                if ( value.getClass().isArray() )
-                {
-                    final String[] values = new String[Array.getLength(value)];
-                    for(int i=0; i<values.length; i++)
-                    {
-                        values[i] = Array.get(value, i).toString();
-                    }
-                    return values;
-                }
-                return new String[] {value.toString()};
-            }
-            return null;
-        }
-        catch (final NoClassDefFoundError ncdfe)
-        {
-            throw new IllegalArgumentException("A class could not be found while parsing class " + clazz.getName() +
-                        ". Please check this stracktrace and add a dependency with the missing class to your project.", ncdfe);
-        }
-        catch (final Exception e)
-        {
-            // ignore and just return null
-        }
-        return null;
-    }
-
-    /**
-     * Get the compiled class.
-     */
-    public static Class<?> getClass(final ClassLoader classLoader, String name) {
-        if ( classLoader == null ) {
-            return null;
-        }
-        try {
-            if ( name.endsWith(".class") ) {
-                name = name.substring(0, name.length() - 6);
-            }
-            return classLoader.loadClass(name);
-        } catch (ClassNotFoundException e) {
-            return null;
-        }
-    }
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaClassDescription.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaClassDescription.java
deleted file mode 100644
index db299d1..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaClassDescription.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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.scrplugin.tags;
-
-import org.apache.felix.scrplugin.SCRDescriptorException;
-
-/**
- * <code>JavaClassDescription.java</code>...
- * Description of a java class
- *
- */
-public interface JavaClassDescription {
-
-    JavaClassDescription[] EMPTY_RESULT = new JavaClassDescription[0];
-
-    /**
-     * Get the java class tag with the name.
-     * @param name
-     * @return the tag or null.
-     */
-    JavaTag getTagByName(String name);
-
-    /**
-     * Get all class tags with this name.
-     * @param name
-     * @param inherited If true, parent classes are searched as well.
-     * @return An array of tags or the empty array.
-     * @throws SCRDescriptorException
-     */
-    JavaTag[] getTagsByName(String name, boolean inherited)
-    throws SCRDescriptorException;
-
-    /**
-     * Get the description for the parent class.
-     * @return The description or <code>null</code> if this class is the
-     *         Object class.
-     * @throws SCRDescriptorException
-     */
-    JavaClassDescription getSuperClass() throws SCRDescriptorException;
-
-    /**
-     * Get the name of the described class.
-     * @return The name of the described class.
-     */
-    String getName();
-
-    /**
-     * Get the fields of this class
-     * @return All fields or an empty array
-     */
-    JavaField[] getFields();
-
-    /**
-     * Get the field with the name.
-     * @param name The name of the field
-     * @return The field with the name or null.
-     * @throws SCRDescriptorException
-     */
-    JavaField getFieldByName(String name) throws SCRDescriptorException;
-
-    JavaField getExternalFieldByName(String name) throws SCRDescriptorException;
-
-    /**
-     * Returns an array of the implemented interfaces of this class.
-     * @return An array containing the interfaces or an empty array
-     *         if this class does not implement any interface.
-     * @throws SCRDescriptorException
-     */
-    JavaClassDescription[] getImplementedInterfaces() throws SCRDescriptorException;
-
-    /**
-     * Search for a method with the given signature.
-     * @param name
-     * @param parameters
-     * @return A descriptor for the method or <code>null</code>
-     * @throws SCRDescriptorException
-     */
-    JavaMethod getMethodBySignature(String name, String[] parameters)
-    throws SCRDescriptorException;
-
-    /**
-     * Is this class public?
-     * @return True if this class is public.
-     */
-    boolean isPublic();
-
-    /**
-     * Is this class abstract?
-     * @return True if this class is abstract.
-     */
-    boolean isAbstract();
-
-    /**
-     * Is this class an interface?
-     * @return True if this is an interface.
-     */
-    boolean isInterface();
-
-    /**
-     * Return all methods of this class
-     * @return An array of methods or an empty array.
-     */
-    JavaMethod[] getMethods();
-
-    /**
-     * Is this class of the type?
-     * @param type
-     * @return True if this class is of the type.
-     * @throws SCRDescriptorException
-     */
-    boolean isA(String type) throws SCRDescriptorException;
-
-    /**
-     * Search for the class.
-     * If the referenced name is not fully qualified, the imports
-     * of the class are searched.
-     * @param referencedName
-     * @return The java class description or null
-     * @throws SCRDescriptorException
-     */
-    JavaClassDescription getReferencedClass(String referencedName)
-    throws SCRDescriptorException;
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaClassDescriptionInheritanceComparator.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaClassDescriptionInheritanceComparator.java
deleted file mode 100644
index e48cacd..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaClassDescriptionInheritanceComparator.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.scrplugin.tags;
-
-
-import java.util.Comparator;
-
-import org.apache.felix.scrplugin.SCRDescriptorException;
-
-
-/**
- * The <code>JavaClassDescriptionInheritanceComparator</code> orders
- * {@link JavaClassDescription} objects by their inheritance:
- * <ol>
- * <li>If the descriptors are the same, zero is returned
- * <li>If the first descriptor is an extension of the second, 1 is returned
- * <li>If the second descriptor is an extension of the first, -1 is returned
- * <li>Otherwise if the first descriptor is nested deeper in the hierarchy 1 is
- * returned, else if the second descriptor is nested deeper in the hierarchy -1
- * is returned.
- * <li>Finally, the natural order of the class names is returned
- * </ol>
- */
-public class JavaClassDescriptionInheritanceComparator implements Comparator<JavaClassDescription>
-{
-
-    public int compare( JavaClassDescription cd1, JavaClassDescription cd2 )
-    {
-        // the descriptors are the same
-        if ( equals( cd1, cd2 ) )
-        {
-            return 0;
-        }
-
-        try
-        {
-
-            int level1 = 0;
-            int level2 = 0;
-
-            // if cd1 is an extension of cd2
-            JavaClassDescription super1 = cd1.getSuperClass();
-            while ( super1 != null )
-            {
-                if ( equals( super1, cd2 ) )
-                {
-                    return 1;
-                }
-                super1 = super1.getSuperClass();
-                level1++;
-            }
-
-            // if cd2 is an extension of cd1
-            JavaClassDescription super2 = cd2.getSuperClass();
-            while ( super2 != null )
-            {
-                if ( equals( super2, cd1 ) )
-                {
-                    return -1;
-                }
-                super2 = super2.getSuperClass();
-                level2++;
-            }
-
-            // class do not share the hierarchy, order by hierarchy level
-            if ( level1 < level2 )
-            {
-                return -1;
-            }
-            else if ( level1 > level2 )
-            {
-                return 1;
-            }
-        }
-        catch ( SCRDescriptorException mee )
-        {
-            // what shall we do ??
-        }
-
-        // last ressort: order by class name
-        return cd1.getName().compareTo( cd2.getName() );
-    }
-
-
-    // compare for equality: returns true if both descriptors have the same name
-    private boolean equals( JavaClassDescription cd1, JavaClassDescription cd2 )
-    {
-        return cd1.getName().equals( cd2.getName() );
-    }
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaField.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaField.java
deleted file mode 100644
index cbadb04..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaField.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.scrplugin.tags;
-
-/**
- * <code>JavaField.java</code>...
- *
- */
-public interface JavaField {
-
-    /** The name of the field. */
-    String getName();
-
-    /** The type of the field. */
-    String getType();
-
-    /**
-     * Return the given tag.
-     * @param name The tag name.
-     * @return The tag or null.
-     */
-    JavaTag getTagByName(String name);
-
-    /**
-     * Return the initial value if this is a static constant.
-     * If this field is not an array, an array of length 1 is
-     * returned with the value. If this field is an array,
-     * the array of values is returned.
-     * @return The initial value of the field.
-     */
-    String[] getInitializationExpression();
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaParameter.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaParameter.java
deleted file mode 100644
index 02cf536..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaParameter.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.scrplugin.tags;
-
-/**
- * <code>JavaParameter.java</code>...
- *
- */
-public interface JavaParameter {
-
-    String getType();
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaTag.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaTag.java
deleted file mode 100644
index e4fc755..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/JavaTag.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.scrplugin.tags;
-
-import java.util.Map;
-
-/**
- * <code>JavaTag.java</code>...
- *
- */
-public interface JavaTag {
-
-    /**
-     * The name of the tag, e.g. scr.component etc.
-     */
-    String getName();
-
-    /**
-     * The name of the tag as used in the source code.
-     * For javadoc tags this is like {@link #getName()}, for annoations this is different.
-     */
-    String getSourceName();
-
-    String[] getParameters();
-
-    String getNamedParameter(String arg0);
-
-    String getSourceLocation();
-
-    int getLineNumber();
-
-    JavaClassDescription getJavaClassDescription();
-
-    JavaField getField();
-
-    Map<String, String> getNamedParameterMap();
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/ModifiableJavaClassDescription.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/ModifiableJavaClassDescription.java
deleted file mode 100644
index a3f5a79..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/ModifiableJavaClassDescription.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.scrplugin.tags;
-
-import org.apache.felix.scrplugin.SCRDescriptorException;
-
-
-public interface ModifiableJavaClassDescription {
-
-    void addMethods(String propertyName, String className, boolean createBind, boolean createUnbind)
-    throws SCRDescriptorException;
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AbstractTag.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AbstractTag.java
deleted file mode 100644
index e54d445..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AbstractTag.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.scrplugin.tags.annotation;
-
-import java.util.Map;
-
-import org.apache.felix.scrplugin.tags.*;
-
-import com.thoughtworks.qdox.model.Annotation;
-
-/**
- * Description of a java tag for components.
- */
-public abstract class AbstractTag implements JavaTag {
-
-    protected final JavaClassDescription description;
-
-    protected final JavaField field;
-
-    protected final Annotation sourceAnnotation;
-
-    protected Map<String, String> parameters;
-
-    /**
-     * @param desc Description
-     * @param field Field
-     */
-    public AbstractTag(Annotation sourceAnnotation, JavaClassDescription desc, JavaField field) {
-        this.sourceAnnotation = sourceAnnotation;
-        this.description = desc;
-        this.field = field;
-    }
-
-    /**
-     * @see JavaTag#getNamedParameter(String)
-     */
-    public String getNamedParameter(String name) {
-        final Map<String, String> map = this.getNamedParameterMap();
-        if (map != null) {
-            return map.get(name);
-        }
-        return null;
-    }
-
-    /**
-     * @see JavaTag#getParameters()
-     */
-    public String[] getParameters() {
-        final Map<?, ?> map = this.getNamedParameterMap();
-        if (map != null) {
-            return map.keySet().toArray(new String[5]);
-        }
-        return new String[0];
-    }
-
-    /**
-     * @see JavaTag#getSourceLocation()
-     */
-    public String getSourceLocation() {
-        return "Java annotations in " + this.description.getName();
-    }
-
-    /**
-     * @see JavaTag#getLineNumber()
-     */
-    public int getLineNumber() {
-        return sourceAnnotation.getLineNumber();
-    }
-
-    /**
-     * @see JavaTag#getJavaClassDescription()
-     */
-    public JavaClassDescription getJavaClassDescription() {
-        return this.description;
-    }
-
-    /**
-     * @see JavaTag#getField()
-     */
-    public JavaField getField() {
-        return this.field;
-    }
-
-    /**
-     * Maps an empty or null string value to null
-     * @param value String value
-     * @return Non-empty string value or null
-     */
-    protected String emptyToNull(String value) {
-        if (value == null || value.length() == 0) {
-            return null;
-        }
-        return value;
-    }
-
-    /**
-     * @see JavaTag#getName()
-     */
-    public abstract String getName();
-
-    /**
-     * @see JavaTag#getSourceName()
-     */
-    public abstract String getSourceName();
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getNamedParameterMap()
-     */
-    public Map<String, String> getNamedParameterMap() {
-        if ( this.parameters == null ) {
-            this.parameters = this.createNamedParameterMap();
-        }
-        return this.parameters;
-    }
-
-    /**
-     * Create the parameter map.
-     * @see JavaTag#getNamedParameterMap()
-     */
-    protected abstract Map<String, String> createNamedParameterMap();
-
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationJavaClassDescription.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationJavaClassDescription.java
deleted file mode 100644
index 85563e9..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationJavaClassDescription.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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.scrplugin.tags.annotation;
-
-import java.util.*;
-
-import org.apache.felix.scrplugin.JavaClassDescriptorManager;
-import org.apache.felix.scrplugin.SCRDescriptorException;
-import org.apache.felix.scrplugin.tags.*;
-import org.apache.felix.scrplugin.tags.qdox.QDoxJavaClassDescription;
-
-import com.thoughtworks.qdox.model.JavaClass;
-
-/**
- * Reading class description based on java annotations. This extends
- * {@link QDoxJavaClassDescription} to re-use annotation-independent logic and
- * automatic generation of bind/unbind methods.
- */
-public class AnnotationJavaClassDescription extends QDoxJavaClassDescription {
-
-    /**
-     * @param clazz Java class
-     * @param javaClass QDox source
-     * @param manager description manager
-     */
-    public AnnotationJavaClassDescription(Class<?> clazz, JavaClass javaClass, JavaClassDescriptorManager manager) {
-        super(clazz, javaClass, manager);
-    }
-
-    public ClassLoader getClassLoader() {
-        return this.manager.getClassLoader();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getTagByName(String)
-     */
-    @Override
-    public JavaTag getTagByName(String name) {
-        for(com.thoughtworks.qdox.model.Annotation annotation : this.javaClass.getAnnotations()) {
-            List<JavaTag> tags = manager.getAnnotationTagProviderManager().getTags(annotation, this);
-            for (JavaTag tag : tags) {
-                if (tag.getName().equals(name)) {
-                    return tag;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getTagsByName(String, boolean)
-     */
-    @Override
-    public JavaTag[] getTagsByName(String name, boolean inherited) throws SCRDescriptorException {
-
-        List<JavaTag> tags = new ArrayList<JavaTag>();
-        for(com.thoughtworks.qdox.model.Annotation annotation : this.javaClass.getAnnotations()) {
-            List<JavaTag> annotationTags = manager.getAnnotationTagProviderManager().getTags(annotation, this);
-            for (JavaTag tag : annotationTags) {
-                if (tag.getName().equals(name)) {
-                    tags.add(tag);
-                }
-            }
-        }
-
-        if (inherited && this.getSuperClass() != null) {
-            final JavaTag[] superTags = this.getSuperClass().getTagsByName(name, inherited);
-            if (superTags.length > 0) {
-                tags.addAll(Arrays.asList(superTags));
-            }
-        }
-
-        return tags.toArray(new JavaTag[tags.size()]);
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getFields()
-     */
-    @Override
-    public JavaField[] getFields() {
-        final com.thoughtworks.qdox.model.JavaField fields[] = this.javaClass.getFields();
-        if ( fields == null || fields.length == 0 ) {
-            return new JavaField[0];
-        }
-        final JavaField[] javaFields = new JavaField[fields.length];
-        for (int i = 0; i < fields.length; i++) {
-            javaFields[i] = new AnnotationJavaField(fields[i], this);
-        }
-        return javaFields;
-    }
-
-    /**
-     * @see JavaClassDescription#getFieldByName(String)
-     */
-    @Override
-    public JavaField getFieldByName(String name) throws SCRDescriptorException {
-        final com.thoughtworks.qdox.model.JavaField field = this.javaClass.getFieldByName(name);
-        if (field != null) {
-            return new AnnotationJavaField(field, this);
-        }
-        if (this.getSuperClass() != null) {
-            this.getSuperClass().getFieldByName(name);
-        }
-        return null;
-    }
-
-    protected JavaClassDescriptorManager getManager() {
-        return this.manager;
-    }
-
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationJavaField.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationJavaField.java
deleted file mode 100644
index d4d40ea..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationJavaField.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.scrplugin.tags.annotation;
-
-import java.util.List;
-
-import org.apache.felix.scrplugin.tags.*;
-
-/**
- * Description of a java field
- */
-public class AnnotationJavaField implements JavaField {
-
-    protected final com.thoughtworks.qdox.model.JavaField field;
-
-    protected final AnnotationJavaClassDescription description;
-
-    /**
-     * @param field Field
-     * @param description description
-     */
-    public AnnotationJavaField(com.thoughtworks.qdox.model.JavaField field, AnnotationJavaClassDescription description) {
-        this.field = field;
-        this.description = description;
-    }
-
-    /**
-     * @see JavaField#getInitializationExpression()
-     */
-    public String[] getInitializationExpression() {
-        return ClassUtil.getInitializationExpression(this.description.getCompiledClass(), this.getName());
-    }
-
-    /**
-     * @see JavaField#getName()
-     */
-    public String getName() {
-        return this.field.getName();
-    }
-
-    /**
-     * @see JavaField#getTagByName(String)
-     */
-    public JavaTag getTagByName(String name) {
-        for(com.thoughtworks.qdox.model.Annotation annotation : this.field.getAnnotations()) {
-            List<JavaTag> tags =  description.getManager().getAnnotationTagProviderManager().getTags(annotation, this.description, this);
-            for (JavaTag tag : tags) {
-                if (tag.getName().equals(name)) {
-                    return tag;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * @see JavaField#getType()
-     */
-    public String getType() {
-        return this.field.getType().getValue();
-    }
-
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProvider.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProvider.java
deleted file mode 100644
index 078019a..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProvider.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.scrplugin.tags.annotation;
-
-import java.util.List;
-
-import org.apache.felix.scrplugin.tags.JavaField;
-import org.apache.felix.scrplugin.tags.JavaTag;
-
-import com.thoughtworks.qdox.model.Annotation;
-
-/**
- * Interface for provider classes, that map java annotations to {@link JavaTag}
- * implementations.
- */
-public interface AnnotationTagProvider {
-
-    /**
-     * Maps a annotation to one or many {@link JavaTag} implementations.
-     * @param pAnnotation Java annotation
-     * @param description Annotations-based java class description
-     * @param field Reference to field (set on field-level annotations, null on
-     *            other annotations)
-     * @return List of tag implementations. Return empty list if this provider
-     *         cannot map the annotation to any tag instance.
-     */
-    List<JavaTag> getTags(Annotation pAnnotation, AnnotationJavaClassDescription description, JavaField field);
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProviderManager.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProviderManager.java
deleted file mode 100644
index 3ca4818..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProviderManager.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * 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.scrplugin.tags.annotation;
-
-
-import java.util.*;
-
-import javax.imageio.spi.ServiceRegistry;
-
-import org.apache.felix.scrplugin.SCRDescriptorFailureException;
-import org.apache.felix.scrplugin.tags.JavaField;
-import org.apache.felix.scrplugin.tags.JavaTag;
-
-import com.thoughtworks.qdox.model.Annotation;
-import com.thoughtworks.qdox.model.JavaClass;
-
-
-/**
- * Supports mapping of built-in and custom java anntoations to {@link JavaTag}
- * implementations.
- */
-public class AnnotationTagProviderManager
-{
-
-    /**
-     * Allows to define additional implementations of the interface
-     * {@link org.apache.felix.scrplugin.tags.annotation.AnnotationTagProvider}
-     * that provide mappings from custom annotations to
-     * {@link org.apache.felix.scrplugin.tags.JavaTag} implementations.
-     */
-    private final Map<String, AnnotationTagProvider> annotationTagProviders = new LinkedHashMap<String, AnnotationTagProvider>();
-
-    /**
-     * @param annotationTagProviderClasses List of classes that implements
-     *            {@link AnnotationTagProvider} interface.
-     * @throws SCRDescriptorFailureException
-     */
-    public AnnotationTagProviderManager(
-            final String[] annotationTagProviderClasses,
-            final ClassLoader classLoader )
-    throws SCRDescriptorFailureException
-    {
-        // search for providers
-        final Iterator<AnnotationTagProvider> serviceIter = ServiceRegistry.lookupProviders(AnnotationTagProvider.class, classLoader);
-        while ( serviceIter.hasNext() )
-        {
-            final AnnotationTagProvider provider = serviceIter.next();
-            this.addProvider(provider);
-        }
-
-        // add custom providers defined in pom
-        for ( int i = 0; i < annotationTagProviderClasses.length; i++ )
-        {
-            loadProvider( classLoader, annotationTagProviderClasses[i], false );
-        }
-
-        // always add provider supporting built-in SCR default properties (for compatibility with older
-        // annotation versions)
-        loadProvider( classLoader,
-            "org.apache.felix.scrplugin.tags.annotation.defaulttag.DefaultAnnotationTagProvider", true );
-        loadProvider( classLoader,
-            "org.apache.felix.scrplugin.tags.annotation.sling.SlingAnnotationTagProvider", true );
-    }
-
-    /**
-     * Add a provider (if not already available)
-     */
-    private void addProvider(final AnnotationTagProvider provider)
-    {
-        // check if this provider is already loaded
-        final String key = provider.getClass().getName();
-        if ( !this.annotationTagProviders.containsKey(key) )
-        {
-            this.annotationTagProviders.put(key, provider);
-        }
-    }
-
-    private void loadProvider( final ClassLoader classLoader, final String className, final boolean silent )
-        throws SCRDescriptorFailureException
-    {
-        String failureMessage = null;
-        try
-        {
-            Class<?> clazz = classLoader.loadClass( className );
-            try
-            {
-                addProvider( ( AnnotationTagProvider ) clazz.newInstance() );
-            }
-            catch ( ClassCastException e )
-            {
-                failureMessage = "Class '" + clazz.getName() + "' " + "does not implement interface '"
-                    + AnnotationTagProvider.class.getName() + "'.";
-            }
-            catch ( InstantiationException e )
-            {
-                failureMessage = "Unable to instantiate class '" + clazz.getName() + "': " + e.getMessage();
-            }
-            catch ( IllegalAccessException e )
-            {
-                failureMessage = "Illegal access to class '" + clazz.getName() + "': " + e.getMessage();
-            }
-        }
-        catch ( ClassNotFoundException e )
-        {
-            failureMessage = "Annotation provider class '" + className + "' not found.";
-        }
-
-        // throw an optional exception if not required to remaing silent
-        if ( failureMessage != null && !silent )
-        {
-            throw new SCRDescriptorFailureException( failureMessage );
-        }
-    }
-
-
-    /**
-     * Converts a java annotation to {@link JavaTag} if a mapping can be found.
-     *
-     * @param annotation Java annotation
-     * @param description Description
-     * @return Tag declaration or null if no mapping found
-     */
-    public List<JavaTag> getTags( Annotation annotation, AnnotationJavaClassDescription description )
-    {
-        return getTags( annotation, description, null );
-    }
-
-
-    /**
-     * Converts a java annotation to {@link JavaTag} if a mapping can be found.
-     *
-     * @param annotation Java annotation
-     * @param description Description
-     * @param field Field
-     * @return Tag declaration or null if no mapping found
-     */
-    public List<JavaTag> getTags( Annotation annotation, AnnotationJavaClassDescription description, JavaField field )
-    {
-        List<JavaTag> tags = new ArrayList<JavaTag>();
-
-        for ( AnnotationTagProvider provider : this.annotationTagProviders.values() )
-        {
-            tags.addAll( provider.getTags( annotation, description, field ) );
-        }
-
-        return tags;
-    }
-
-
-    /**
-     * Checks if the given class has any SCR plugin java annotations defined.
-     *
-     * @param pClass Class
-     * @return true if SCR plugin java annotation found
-     */
-    public boolean hasScrPluginAnnotation( final JavaClass pClass, final AnnotationJavaClassDescription description )
-    {
-        for ( com.thoughtworks.qdox.model.Annotation annotation : pClass.getAnnotations() )
-        {
-            if ( getTags( annotation, description ).size() > 0 )
-            {
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/Util.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/Util.java
deleted file mode 100644
index 61eef89..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/Util.java
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * 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.scrplugin.tags.annotation;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.felix.scrplugin.SCRDescriptorException;
-import org.apache.felix.scrplugin.tags.*;
-
-import com.thoughtworks.qdox.model.Annotation;
-import com.thoughtworks.qdox.model.annotation.AnnotationFieldRef;
-import com.thoughtworks.qdox.model.annotation.EvaluatingVisitor;
-
-/**
- * Helper class for getting values from annotations.
- */
-public abstract class Util {
-
-    /**
-     * Get a boolean value from an annotation.
-     * @param annotation The annotation.
-     * @param name The name of the attribute.
-     * @param clazz The annotation class.
-     * @return The boolean value.
-     */
-    public static boolean getBooleanValue(final Annotation annotation, final JavaClassDescription desc, final String name, final Class<?> clazz) {
-        final String[] sValues = getAnnotationValues(annotation, name, desc);
-        if ( sValues != null )
-        {
-            return Boolean.valueOf(sValues[0]);
-        }
-        try
-        {
-            return (Boolean) clazz.getMethod(name).getDefaultValue();
-        }
-        catch( final NoSuchMethodException mnfe)
-        {
-            // we ignore this
-            return true;
-        }
-    }
-
-    public static int getIntValue(final Annotation annotation, final JavaClassDescription desc, final String name, final Class<?> clazz) {
-        final String[] sValues = getAnnotationValues(annotation, name, desc);
-        if ( sValues != null )
-        {
-            return Integer.valueOf(sValues[0]);
-
-        }
-        try
-        {
-            return (Integer) clazz.getMethod(name).getDefaultValue();
-        }
-        catch(final NoSuchMethodException mnfe)
-        {
-            // we ignore this
-            return 0;
-        }
-    }
-
-    /**
-     * Helper method to get the values of an annotation as string values.
-     * @param annotation The annotation.
-     * @param desc The java class description.
-     * @param name The attribute name from the annotation.
-     * @return The array of string values or null.
-     */
-    public static String[] getStringValues(Annotation annotation, JavaClassDescription desc, String name)
-    {
-        final String[] sValues = getAnnotationValues(annotation, name, desc);
-        return sValues;
-    }
-
-    /**
-     * Helper method to get the values of an annotation as long values.
-     * @param annotation The annotation.
-     * @param desc The java class description.
-     * @param name The attribute name from the annotation.
-     * @return The array of long values or null.
-     */
-    public static long[] getLongValues(Annotation annotation, JavaClassDescription desc, String name)
-    {
-        final String[] sValues = getAnnotationValues(annotation, name, desc);
-        if ( sValues != null && sValues.length > 0 )
-        {
-            final long[] values = new long[sValues.length];
-            for (int i=0; i<values.length; i++)
-            {
-                values[i] = Long.valueOf(sValues[i]);
-            }
-            return values;
-
-        }
-        return null;
-    }
-
-    /**
-     * Helper method to get the values of an annotation as long values.
-     * @param annotation The annotation.
-     * @param desc The java class description.
-     * @param name The attribute name from the annotation.
-     * @return The array of long values or null.
-     */
-    public static int[] getIntValues(Annotation annotation, JavaClassDescription desc, String name)
-    {
-        final String[] sValues = getAnnotationValues(annotation, name, desc);
-        if ( sValues != null && sValues.length > 0 )
-        {
-            final int[] values = new int[sValues.length];
-            for (int i=0; i<values.length; i++)
-            {
-                values[i] = Integer.valueOf(sValues[i]);
-            }
-            return values;
-
-        }
-        return null;
-    }
-
-    /**
-     * Helper method to get the values of an annotation as float values.
-     * @param annotation The annotation.
-     * @param desc The java class description.
-     * @param name The attribute name from the annotation.
-     * @return The array of float values or null.
-     */
-    public static float[] getFloatValues(Annotation annotation, JavaClassDescription desc, String name)
-    {
-        final String[] sValues = getAnnotationValues(annotation, name, desc);
-        if ( sValues != null && sValues.length > 0 )
-        {
-            final float[] values = new float[sValues.length];
-            for (int i=0; i<values.length; i++)
-            {
-                values[i] = Float.valueOf(sValues[i]);
-            }
-            return values;
-
-        }
-        return null;
-    }
-
-    /**
-     * Helper method to get the values of an annotation as double values.
-     * @param annotation The annotation.
-     * @param desc The java class description.
-     * @param name The attribute name from the annotation.
-     * @return The array of double values or null.
-     */
-    public static double[] getDoubleValues(Annotation annotation, JavaClassDescription desc, String name)
-    {
-        final String[] sValues = getAnnotationValues(annotation, name, desc);
-        if ( sValues != null && sValues.length > 0 )
-        {
-            final double[] values = new double[sValues.length];
-            for (int i=0; i<values.length; i++)
-            {
-                values[i] = Double.valueOf(sValues[i]);
-            }
-            return values;
-
-        }
-        return null;
-    }
-
-    /**
-     * Helper method to get the values of an annotation as char values.
-     * @param annotation The annotation.
-     * @param desc The java class description.
-     * @param name The attribute name from the annotation.
-     * @return The array of char values or null.
-     */
-    public static char[] getCharValues(Annotation annotation, JavaClassDescription desc, String name) {
-        final String[] sValues = getAnnotationValues(annotation, name, desc);
-        if ( sValues != null && sValues.length > 0 )
-        {
-            final char[] values = new char[sValues.length];
-            for (int i=0; i<values.length; i++)
-            {
-                values[i] = sValues[i].charAt(0);
-            }
-            return values;
-
-        }
-        return null;
-    }
-
-    /**
-     * Helper method to get the values of an annotation as short values.
-     * @param annotation The annotation.
-     * @param desc The java class description.
-     * @param name The attribute name from the annotation.
-     * @return The array of short values or null.
-     */
-   public static short[] getShortValues(Annotation annotation, JavaClassDescription desc, String name)
-   {
-       final String[] sValues = getAnnotationValues(annotation, name, desc);
-       if ( sValues != null && sValues.length > 0 )
-       {
-           final short[] values = new short[sValues.length];
-           for (int i=0; i<values.length; i++)
-           {
-               values[i] = Short.valueOf(sValues[i]);
-           }
-           return values;
-
-       }
-       return null;
-    }
-
-    /**
-     * Helper method to get the values of an annotation as byte values.
-     * @param annotation The annotation.
-     * @param desc The java class description.
-     * @param name The attribute name from the annotation.
-     * @return The array of byte values or null.
-     */
-   public static byte[] getByteValues(Annotation annotation, JavaClassDescription desc, String name)
-   {
-       final String[] sValues = getAnnotationValues(annotation, name, desc);
-       if ( sValues != null && sValues.length > 0 )
-       {
-           final byte[] values = new byte[sValues.length];
-           for (int i=0; i<values.length; i++)
-           {
-               values[i] = Byte.valueOf(sValues[i]);
-           }
-           return values;
-
-       }
-       return null;
-    }
-
-    /**
-     * Helper method to get the values of an annotation as boolean values.
-     * @param annotation The annotation.
-     * @param desc The java class description.
-     * @param name The attribute name from the annotation.
-     * @return The array of boolean values or null.
-     */
-    public static boolean[] getBooleanValues(Annotation annotation, JavaClassDescription desc, String name)
-    {
-        final String[] sValues = getAnnotationValues(annotation, name, desc);
-        if ( sValues != null && sValues.length > 0 )
-        {
-            final boolean[] values = new boolean[sValues.length];
-            for (int i=0; i<values.length; i++)
-            {
-                values[i] = Boolean.valueOf(sValues[i]);
-            }
-            return values;
-
-        }
-        return null;
-    }
-
-    /**
-     * Get a single annotation value
-     * @param annotation The annotation
-     * @param desc The class description
-     * @param name The name of the annotation
-     * @param clazz The class of the annotation
-     * @return The value
-     */
-    public static String getStringValue(Annotation annotation, JavaClassDescription desc, String name, final Class<?> clazz) {
-        final String values[] = getAnnotationValues(annotation, name, desc);
-        if ( values != null && values.length > 0 ) {
-            return values[0];
-        }
-        // try to get the default value
-        try {
-            return (String) clazz.getMethod(name).getDefaultValue();
-        } catch( NoSuchMethodException mnfe) {
-            // we ignore this
-            return "";
-        }
-    }
-
-    public static Class<?> getClassValue(Annotation annotation, String name, final Class<?> clazz, final ClassLoader classLoader) {
-        final Object obj = annotation.getNamedParameter(name);
-        if ( obj != null ) {
-            if ( obj instanceof Class<?> ) {
-                return (Class<?>)obj;
-            }
-            return ClassUtil.getClass(classLoader, obj.toString());
-        }
-        try {
-            return (Class<?>) clazz.getMethod(name).getDefaultValue();
-        } catch( NoSuchMethodException mnfe) {
-            // we ignore this
-            return null;
-        }
-    }
-
-    public static Class<?>[] getClassArrayValue(Annotation annotation, String name, final Class<?> clazz, final ClassLoader classLoader) {
-        Object obj = annotation.getNamedParameter(name);
-        if ( obj != null ) {
-            if ( obj instanceof Class<?> ) {
-                return new Class<?>[] {(Class<?>)obj};
-            }
-            if ( obj instanceof Collection<?> ) {
-                obj = ((Collection<?>)obj).toArray();
-            }
-            if ( obj.getClass().isArray() ) {
-                final Object[] objArray = (Object[])obj;
-                final Class<?>[] result = new Class<?>[objArray.length];
-                for(int i=0; i<objArray.length;i++) {
-                    if ( objArray[i] instanceof Class<?>) {
-                        result[i] = (Class<?>)objArray[i];
-                    } else {
-                        result[i] = ClassUtil.getClass(classLoader, objArray[i].toString());
-                    }
-                }
-                return result;
-            }
-            return new Class<?>[] {ClassUtil.getClass(classLoader, obj.toString())};
-        }
-        try {
-            final Object val = clazz.getMethod(name).getDefaultValue();
-            if ( val instanceof Class<?> ) {
-                return new Class<?>[] {(Class<?>)val};
-            }
-            return (Class<?>[])val;
-        } catch( NoSuchMethodException mnfe) {
-            // we ignore this
-            return null;
-        }
-    }
-
-    public static <T extends Enum<T>> T getEnumValue(Annotation annotation,
-                                                  String name,
-                                                  final Class<T> enumClass,
-                                                  final Class<?> clazz,
-                                                  final boolean returnDefault) {
-        Object obj = annotation.getNamedParameter(name);
-        if (obj == null) {
-            if ( returnDefault ) {
-                try {
-                    obj = clazz.getMethod(name).getDefaultValue();
-                } catch( NoSuchMethodException mnfe) {
-                    // we ignore this
-                }
-            }
-        }
-        if ( obj != null ) {
-            if (enumClass.isAssignableFrom(obj.getClass())) {
-                return (T)obj;
-            }
-            else if ( obj instanceof String ) {
-                String enumName = (String)obj;
-                int dotPos = enumName.lastIndexOf('.');
-                if (dotPos >= 0) {
-                    enumName = enumName.substring(dotPos+1);
-                }
-                return Enum.valueOf(enumClass, enumName);
-            }
-        }
-        return null;
-    }
-
-    public static <T extends Enum<T>> T getEnumValue(Annotation annotation,
-            String name,
-            final Class<T> enumClass,
-            final Class<?> clazz) {
-        return getEnumValue(annotation, name, enumClass, clazz, true);
-    }
-
-    @SuppressWarnings("unchecked")
-    public static String[] getAnnotationValues(final Annotation annotation, final String name, final JavaClassDescription desc)
-    throws IllegalArgumentException
-    {
-        final EvaluatingVisitor evaluatingVisitor = new EvaluatingVisitor() {
-
-            public Object visitAnnotationFieldRef( AnnotationFieldRef fieldRef ) {
-                // during prescan of AnnotationTagProviderManager#hasScrPluginAnnotation this method is called without desc attribute
-                // avoid NPE in this case and just skip value resolving
-                // FELIX-1629
-                if ( desc == null)
-                {
-                    return "";
-                }
-
-                // getField throws AIOOBE
-                // return ((AnnotationFieldRef)av).getField().getInitializationExpression();
-                final String s = fieldRef.getParameterValue().toString().trim();
-                try
-                {
-                    int classSep = s.lastIndexOf('.');
-                    JavaField field = null;
-                    if ( classSep == -1 ) {
-                        // local variable
-                        field = desc.getFieldByName(s);
-                    }
-                    if ( field == null ) {
-                        field = desc.getExternalFieldByName(s);
-                    }
-                    if ( field == null ) {
-                        throw new IllegalArgumentException("Property references unknown field " + s + " in class " + desc.getName());
-                    }
-                    String[] values = field.getInitializationExpression();
-                    if ( values != null && values.length == 1 ) {
-                        return values[0];
-                    }
-                    throw new IllegalArgumentException("Something is wrong: " + s);
-                }
-                catch (NoClassDefFoundError ncdfe)
-                {
-                    throw new IllegalArgumentException("A class could not be found while parsing class " + desc.getName() +
-                            ". Please check this stracktrace and add a dependency with the missing class to your project.", ncdfe);
-                }
-                catch (SCRDescriptorException mee)
-                {
-                    throw new IllegalArgumentException(mee);
-                }
-            }
-
-            @Override
-            protected Object getFieldReferenceValue(com.thoughtworks.qdox.model.JavaField javaField) {
-                // is never called because visitAnnotationFieldRef is overridden as well
-                return null;
-            }
-
-        };
-        final List<Object> valueList = evaluatingVisitor.getListValue(annotation, name);
-        if (valueList == null || valueList.size() == 0)
-        {
-            return null;
-        }
-        String[] values = new String[valueList.size()];
-        for (int i=0; i<values.length; i++) {
-            Object value = valueList.get(i);
-            if (value!=null) {
-                values[i] = value.toString();
-            }
-        }
-        return values;
-    }
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaClassDescription.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaClassDescription.java
deleted file mode 100644
index 53b5110..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaClassDescription.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * 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.scrplugin.tags.cl;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import org.apache.felix.scrplugin.*;
-import org.apache.felix.scrplugin.om.Component;
-import org.apache.felix.scrplugin.tags.*;
-
-/**
- * <code>ClassLoaderJavaClassDescription.java</code>...
- *
- */
-public class ClassLoaderJavaClassDescription implements JavaClassDescription {
-
-    protected static final JavaTag[] EMPTY_TAGS = new JavaTag[0];
-
-    protected final Class<?> clazz;
-
-    protected final JavaClassDescriptorManager manager;
-
-    protected final Component component;
-
-    public ClassLoaderJavaClassDescription(Class<?> c, Component comp, JavaClassDescriptorManager m) {
-        this.clazz = c;
-        this.manager = m;
-        this.component = comp;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getFields()
-     */
-    public JavaField[] getFields() {
-        final Field[] fields = this.clazz.getFields();
-        final JavaField[] javaFields = new JavaField[fields.length];
-        for (int i=0; i < fields.length; i++ ) {
-            javaFields[i] = new ClassLoaderJavaField(fields[i], this);
-        }
-        return javaFields;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getFieldByName(java.lang.String)
-     */
-    public JavaField getFieldByName(String name) throws SCRDescriptorException {
-        Field field = null;
-        try {
-            field = this.clazz.getField(name);
-        } catch (SecurityException e) {
-            // ignore
-        } catch (NoSuchFieldException e) {
-            // ignore
-        }
-        if ( field != null ) {
-            return new ClassLoaderJavaField(field, this);
-        }
-        if ( this.getSuperClass() != null ) {
-            this.getSuperClass().getFieldByName(name);
-        }
-        return null;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getExternalFieldByName(java.lang.String)
-     */
-    public JavaField getExternalFieldByName(String name)
-    throws SCRDescriptorException {
-        throw new SCRDescriptorException("getExternalFieldByName not supported for this class.", getName(), 0);
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getReferencedClass(java.lang.String)
-     */
-    public JavaClassDescription getReferencedClass(String referencedName)
-    throws SCRDescriptorException {
-        throw new SCRDescriptorException("getReferencedClass not supported for this class.", getName(), 0);
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getImplementedInterfaces()
-     */
-    public JavaClassDescription[] getImplementedInterfaces() throws SCRDescriptorException {
-        Class<?>[] implemented = clazz.getInterfaces();
-        if (implemented.length == 0) {
-            return JavaClassDescription.EMPTY_RESULT;
-        }
-
-        JavaClassDescription[] jcd = new JavaClassDescription[implemented.length];
-        for (int i=0; i < jcd.length; i++) {
-            jcd[i] = manager.getJavaClassDescription(implemented[i].getName());
-        }
-        return jcd;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getMethodBySignature(java.lang.String, java.lang.String[])
-     */
-    public JavaMethod getMethodBySignature(String name, String[] parameters)
-    throws SCRDescriptorException {
-        Class<?>[] classParameters = null;
-        if ( parameters != null ) {
-            classParameters = new Class[parameters.length];
-            for(int i=0; i<parameters.length; i++) {
-                try {
-                    classParameters[i] = this.manager.getClassLoader().loadClass(parameters[i]);
-                } catch (ClassNotFoundException cnfe) {
-                    return null;
-                }
-            }
-        }
-        Method m = null;
-        try {
-            m = this.clazz.getDeclaredMethod(name, classParameters);
-        } catch (NoClassDefFoundError ncdfe) {
-            // if this occurs it usually means that a problem with the maven
-            // scopes exists.
-            throw new SCRDescriptorException("Class loading error. This error usually occurs if you have a " +
-                    "service inheriting from a class coming from another bundle and that class using a " +
-                    "third library and all dependencies are specified with scope 'provided'.", getName(), 0, ncdfe);
-        } catch (NoSuchMethodException e) {
-            // ignore this
-        }
-        if ( m != null ) {
-            return new ClassLoaderJavaMethod(m);
-        }
-        // try super class
-        if ( this.getSuperClass() != null ) {
-            return this.getSuperClass().getMethodBySignature(name, parameters);
-        }
-        return null;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getMethods()
-     */
-    public JavaMethod[] getMethods() {
-        return JavaMethod.EMPTY_RESULT;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getName()
-     */
-    public String getName() {
-        return this.clazz.getName();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getSuperClass()
-     */
-    public JavaClassDescription getSuperClass() throws SCRDescriptorException {
-        if ( this.clazz.getSuperclass() != null ) {
-            return this.manager.getJavaClassDescription(this.clazz.getSuperclass().getName());
-        }
-        return null;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getTagByName(java.lang.String)
-     */
-    public JavaTag getTagByName(String name) {
-        // this is only used to retrieve the component tag, so we just support this
-        if ( this.component != null && name.equals(Constants.COMPONENT) ) {
-            return new ClassLoaderJavaTag(this, this.component);
-        }
-        return null;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getTagsByName(java.lang.String, boolean)
-     */
-    public JavaTag[] getTagsByName(String name, boolean inherited)
-    throws SCRDescriptorException {
-        JavaTag[] javaTags = EMPTY_TAGS;
-        if ( this.component != null ) {
-            if ( Constants.SERVICE.equals(name) ) {
-                if ( this.component.getService() != null &&
-                     this.component.getService().getInterfaces().size() > 0 ) {
-                    javaTags = new JavaTag[this.component.getService().getInterfaces().size()];
-                    for(int i=0; i<this.component.getService().getInterfaces().size(); i++) {
-                        javaTags[i] = new ClassLoaderJavaTag(this, this.component.getService().getInterfaces().get(i),
-                                                             this.component.getService().isServicefactory());
-                    }
-                }
-            } else if ( Constants.PROPERTY.equals(name) ) {
-                if ( this.component.getProperties().size() > 0 ) {
-                    javaTags = new JavaTag[this.component.getProperties().size()];
-                    for(int i=0; i<this.component.getProperties().size(); i++) {
-                        javaTags[i] = new ClassLoaderJavaTag(this, this.component.getProperties().get(i));
-                    }
-                }
-            } else if ( Constants.REFERENCE.equals(name) ) {
-                if ( this.component.getReferences().size() > 0 ) {
-                    javaTags = new JavaTag[this.component.getReferences().size()];
-                    for(int i=0; i<this.component.getReferences().size(); i++) {
-                        javaTags[i] = new ClassLoaderJavaTag(this, this.component.getReferences().get(i));
-                    }
-                }
-            }
-        }
-        if ( inherited && this.getSuperClass() != null ) {
-            final JavaTag[] superTags = this.getSuperClass().getTagsByName(name, inherited);
-            if ( superTags.length > 0 ) {
-                final List<JavaTag> list = new ArrayList<JavaTag>(Arrays.asList(javaTags));
-                list.addAll(Arrays.asList(superTags));
-                javaTags = list.toArray(new JavaTag[list.size()]);
-            }
-        }
-        return javaTags;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#isA(java.lang.String)
-     */
-    public boolean isA(String type) {
-        if ( this.clazz.getName().equals(type) ) {
-            return true;
-        }
-
-        if ( this.clazz.getClassLoader() != null ) {
-            try {
-                Class<?> typeClass = this.clazz.getClassLoader().loadClass( type );
-                return typeClass.isAssignableFrom( this.clazz );
-            } catch (ClassNotFoundException cnfe) {
-                // cannot load the check type through the class' class loader
-                // thus we assume clazz is not a type
-            }
-        }
-        return false;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#isAbstract()
-     */
-    public boolean isAbstract() {
-        return Modifier.isAbstract(this.clazz.getModifiers());
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#isInterface()
-     */
-    public boolean isInterface() {
-        return Modifier.isInterface(this.clazz.getModifiers());
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#isPublic()
-     */
-    public boolean isPublic() {
-        return Modifier.isPublic(this.clazz.getModifiers());
-    }
-
-    public String toString() {
-        return getName();
-    }
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaField.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaField.java
deleted file mode 100644
index 37ab90b..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaField.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.scrplugin.tags.cl;
-
-import java.lang.reflect.Field;
-
-import org.apache.felix.scrplugin.tags.*;
-
-/**
- * <code>ClassLoaderJavaField.java</code>...
- *
- */
-public class ClassLoaderJavaField implements JavaField {
-
-    protected final Field field;
-
-    protected final JavaClassDescription description;
-
-    public ClassLoaderJavaField(Field f, JavaClassDescription d) {
-        this.field = f;
-        this.description = d;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaField#getInitializationExpression()
-     */
-    public String[] getInitializationExpression() {
-        return ClassUtil.getInitializationExpression(this.field.getDeclaringClass(), this.field.getName());
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaField#getName()
-     */
-    public String getName() {
-        return this.field.getName();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaField#getTagByName(java.lang.String)
-     */
-    public JavaTag getTagByName(String name) {
-        // TODO
-        return null;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaField#getType()
-     */
-    public String getType() {
-        return this.field.getType().getName();
-    }
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaMethod.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaMethod.java
deleted file mode 100644
index d7c5dde..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaMethod.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.scrplugin.tags.cl;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-import org.apache.felix.scrplugin.tags.JavaMethod;
-import org.apache.felix.scrplugin.tags.JavaParameter;
-
-/**
- * <code>ClassLoaderJavaMethod.java</code>...
- *
- */
-public class ClassLoaderJavaMethod implements JavaMethod {
-
-    protected final Method method;
-
-    protected boolean isConstructor = false;
-
-    public ClassLoaderJavaMethod(Method m) {
-        this.method = m;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaMethod#getName()
-     */
-    public String getName() {
-        return this.method.getName();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaMethod#getParameters()
-     */
-    public JavaParameter[] getParameters() {
-        final JavaParameter[] params = new JavaParameter[this.method.getParameterTypes().length];
-        for(int i=0; i<this.method.getParameterTypes().length; i++) {
-            params[i] = new ClassLoaderJavaParameter(this.method.getParameterTypes()[i].getName());
-        }
-        return params;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaMethod#isConstructor()
-     */
-    public boolean isConstructor() {
-        return this.isConstructor;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaMethod#isProtected()
-     */
-    public boolean isProtected() {
-        return Modifier.isProtected(this.method.getModifiers());
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaMethod#isPublic()
-     */
-    public boolean isPublic() {
-        return Modifier.isPublic(this.method.getModifiers());
-    }
-
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaTag.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaTag.java
deleted file mode 100644
index c9e8e88..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaTag.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * 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.scrplugin.tags.cl;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.felix.scrplugin.Constants;
-import org.apache.felix.scrplugin.om.*;
-import org.apache.felix.scrplugin.tags.*;
-
-/**
- * <code>ClassLoaderJavaTag.java</code>...
- *
- */
-public class ClassLoaderJavaTag implements JavaTag {
-
-    protected final JavaClassDescription description;
-    protected final Component component;
-    protected final Reference reference;
-    protected final Property property;
-    protected final Interface interf;
-    protected boolean isServiceFactory;
-
-    public ClassLoaderJavaTag(final JavaClassDescription desc, final Component component) {
-        this.description = desc;
-        this.reference = null;
-        this.interf = null;
-        this.property = null;
-        this.component = component;
-    }
-
-    public ClassLoaderJavaTag(final JavaClassDescription desc, final Reference reference) {
-        this.description = desc;
-        this.reference = reference;
-        this.interf = null;
-        this.property = null;
-        this.component = null;
-    }
-
-    public ClassLoaderJavaTag(final JavaClassDescription desc, final Property property) {
-        this.description = desc;
-        this.property = property;
-        this.reference = null;
-        this.interf = null;
-        this.component = null;
-    }
-
-    public ClassLoaderJavaTag(final JavaClassDescription desc, final Interface i, final boolean isSF) {
-        this.interf = i;
-        this.description = desc;
-        this.property = null;
-        this.reference = null;
-        this.isServiceFactory = isSF;
-        this.component = null;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getField()
-     */
-    public JavaField getField() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getJavaClassDescription()
-     */
-    public JavaClassDescription getJavaClassDescription() {
-        return this.description;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getName()
-     */
-    public String getName() {
-        if ( this.reference != null ) {
-            return Constants.REFERENCE;
-        } else if ( this.property != null ) {
-            return Constants.PROPERTY;
-        } else if ( this.interf != null ) {
-            return Constants.SERVICE;
-        } else if ( this.component != null ) {
-            return Constants.COMPONENT;
-        }
-        return null;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getSourceName()
-     */
-    public String getSourceName() {
-        return this.getName();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getNamedParameter(java.lang.String)
-     */
-    public String getNamedParameter(String name) {
-        final Map<String, String> map = this.getNamedParameterMap();
-        if ( map != null ) {
-            return map.get(name);
-        }
-        return null;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getNamedParameterMap()
-     */
-    public Map<String, String> getNamedParameterMap() {
-        if ( this.reference != null ) {
-            final Map<String, String> map = new HashMap<String, String>();
-            map.put(Constants.REFERENCE_BIND, this.reference.getBind());
-            map.put(Constants.REFERENCE_CARDINALITY, this.reference.getCardinality());
-            map.put(Constants.REFERENCE_INTERFACE, this.reference.getInterfacename());
-            map.put(Constants.REFERENCE_NAME, this.reference.getName());
-            map.put(Constants.REFERENCE_POLICY, this.reference.getPolicy());
-            map.put(Constants.REFERENCE_TARGET, this.reference.getTarget());
-            map.put(Constants.REFERENCE_UNDBIND, this.reference.getUnbind());
-            map.put(Constants.REFERENCE_UPDATED, this.reference.getUpdated());
-            map.put(Constants.REFERENCE_CHECKED, String.valueOf(this.reference.isChecked()));
-            map.put(Constants.REFERENCE_STRATEGY, this.reference.getStrategy());
-            return map;
-        } else if ( this.property != null ) {
-            final Map<String, String> map = new HashMap<String, String>();
-            map.put(Constants.PROPERTY_TYPE, this.property.getType());
-            map.put(Constants.PROPERTY_NAME, this.property.getName());
-            final String[] values = this.property.getMultiValue();
-            if ( values != null ) {
-                for(int i=0; i<values.length;i++) {
-                    map.put(Constants.PROPERTY_MULTIVALUE_PREFIX + '.' + i, values[i]);
-                }
-            } else {
-                map.put(Constants.PROPERTY_VALUE, this.property.getValue());
-            }
-            map.put(Constants.PROPERTY_PRIVATE, String.valueOf(property.isPrivate()));
-            if ( this.property.getLabel() != null ) {
-                map.put(Constants.PROPERTY_LABEL, this.property.getLabel());
-            }
-            if ( this.property.getDescription() != null ) {
-                map.put(Constants.PROPERTY_DESCRIPTION, this.property.getDescription());
-            }
-            if ( this.property.getCardinality() != null ) {
-                map.put(Constants.PROPERTY_CARDINALITY, this.property.getCardinality());
-            }
-            return map;
-        } else if ( this.interf != null ) {
-            final Map<String, String> map = new HashMap<String, String>();
-            map.put(Constants.SERVICE_INTERFACE, this.interf.getInterfacename());
-            if ( this.isServiceFactory ) {
-                map.put(Constants.SERVICE_FACTORY, "true");
-            }
-            return map;
-        } else if ( this.component != null ) {
-            final Map<String, String> map = new HashMap<String, String>();
-            if ( this.component.getActivate() != null ) {
-                map.put(Constants.COMPONENT_ACTIVATE, this.component.getActivate());
-            }
-            if ( this.component.getDeactivate() != null ) {
-                map.put(Constants.COMPONENT_DEACTIVATE, this.component.getDeactivate());
-            }
-            if ( this.component.getModified() != null ) {
-                map.put(Constants.COMPONENT_MODIFIED, this.component.getModified());
-            }
-            return map;
-        }
-        return null;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getParameters()
-     */
-    public String[] getParameters() {
-        final Map<String, String> map = this.getNamedParameterMap();
-        if ( map != null ) {
-            return map.keySet().toArray(new String[5]);
-        }
-        return new String[0];
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getSourceLocation()
-     */
-    public String getSourceLocation() {
-        return "Compiled class: " + this.description.getName();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getLineNumber()
-     */
-    public int getLineNumber()
-    {
-        // we don't know the exact line number of a tag in a compiled class
-        return 0;
-    }
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaClassDescription.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaClassDescription.java
deleted file mode 100644
index 6ac0f60..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaClassDescription.java
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * 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.scrplugin.tags.qdox;
-
-import java.io.*;
-import java.util.*;
-
-import org.apache.felix.scrplugin.JavaClassDescriptorManager;
-import org.apache.felix.scrplugin.SCRDescriptorException;
-import org.apache.felix.scrplugin.tags.*;
-import org.apache.felix.scrplugin.tags.JavaField;
-import org.apache.felix.scrplugin.tags.JavaMethod;
-import org.objectweb.asm.*;
-import org.objectweb.asm.tree.ClassNode;
-
-import com.thoughtworks.qdox.model.*;
-import com.thoughtworks.qdox.model.JavaParameter;
-import com.thoughtworks.qdox.model.Type;
-
-/**
- * <code>QDoxJavaClassDescription.java</code>...
- *
- */
-public class QDoxJavaClassDescription
-    implements JavaClassDescription, ModifiableJavaClassDescription {
-
-    protected final JavaClass javaClass;
-
-    protected final JavaClassDescriptorManager manager;
-
-    /** The compiled class. */
-    protected final Class<?> clazz;
-
-    public QDoxJavaClassDescription(Class<?> clazz, JavaClass javaClass, JavaClassDescriptorManager m) {
-        this.javaClass = javaClass;
-        this.manager = m;
-        this.clazz = clazz;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getSuperClass()
-     */
-    public JavaClassDescription getSuperClass() throws SCRDescriptorException {
-        final JavaClass parent = this.javaClass.getSuperJavaClass();
-        if ( parent != null ) {
-            return this.manager.getJavaClassDescription(parent.getFullyQualifiedName());
-        }
-        return null;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getTagByName(java.lang.String)
-     */
-    public JavaTag getTagByName(String name) {
-        final DocletTag tag = this.javaClass.getTagByName(name);
-        if ( tag == null ) {
-            return null;
-        }
-        return new QDoxJavaTag(tag, this);
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getName()
-     */
-    public String getName() {
-        return this.javaClass.getFullyQualifiedName();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getTagsByName(java.lang.String, boolean)
-     */
-    public JavaTag[] getTagsByName(String name, boolean inherited)
-    throws SCRDescriptorException {
-        final DocletTag[] tags = this.javaClass.getTagsByName(name, false);
-        JavaTag[] javaTags;
-        if ( tags == null || tags.length == 0 ) {
-            javaTags = new JavaTag[0];
-        } else {
-            javaTags = new JavaTag[tags.length];
-            for(int i=0; i<tags.length;i++) {
-                javaTags[i] = new QDoxJavaTag(tags[i], this);
-            }
-        }
-        if ( inherited && this.getSuperClass() != null ) {
-            final JavaTag[] superTags = this.getSuperClass().getTagsByName(name, inherited);
-            if ( superTags.length > 0 ) {
-                final List<JavaTag> list = new ArrayList<JavaTag>(Arrays.asList(javaTags));
-                list.addAll(Arrays.asList(superTags));
-                javaTags = list.toArray(new JavaTag[list.size()]);
-            }
-        }
-        return javaTags;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getFields()
-     */
-    public JavaField[] getFields() {
-        final com.thoughtworks.qdox.model.JavaField fields[] = this.javaClass.getFields();
-        if ( fields == null || fields.length == 0 ) {
-            return new JavaField[0];
-        }
-        final JavaField[] f = new JavaField[fields.length];
-        for(int i=0; i<fields.length; i++) {
-            f[i] = new QDoxJavaField(fields[i], this);
-        }
-        return f;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getFieldByName(java.lang.String)
-     */
-    public JavaField getFieldByName(String name)
-    throws SCRDescriptorException {
-        final com.thoughtworks.qdox.model.JavaField field = this.javaClass.getFieldByName(name);
-        if ( field != null ) {
-            return new QDoxJavaField(field, this);
-        }
-        if ( this.getSuperClass() != null ) {
-            return this.getSuperClass().getFieldByName(name);
-        }
-        return null;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getExternalFieldByName(java.lang.String)
-     */
-    public JavaField getExternalFieldByName(String name)
-    throws SCRDescriptorException {
-        int lastDot = name.lastIndexOf('.');
-        // if there is no dot, this should be a static import
-        if ( lastDot == -1 ) {
-            final String importDef = this.searchImport('.' + name);
-            if ( importDef != null ) {
-                int sep = importDef.lastIndexOf('.');
-                final String className = importDef.substring(0, sep);
-                final String constantName = importDef.substring(sep+1);
-                final JavaClassDescription jcd = this.manager.getJavaClassDescription(className);
-                if ( jcd != null ) {
-                    return jcd.getFieldByName(constantName);
-                }
-            }
-        } else {
-            // check for fully qualified
-            int firstDot = name.indexOf('.');
-            if ( firstDot == lastDot ) {
-                // we only have one dot, so either the class is imported or in the same package or in the default package (java.lang)
-                final String className = name.substring(0, lastDot);
-                final String constantName = name.substring(lastDot+1);
-                final String importDef = this.searchImport('.' + className);
-                if ( importDef != null ) {
-                    final JavaClassDescription jcd = this.manager.getJavaClassDescription(importDef);
-                    if ( jcd != null ) {
-                        return jcd.getFieldByName(constantName);
-                    }
-                }
-                try {
-                    final JavaClassDescription jcd = this.manager.getJavaClassDescription(this.javaClass.getSource().getPackage().getName() + '.' + className);
-                    if ( jcd != null ) {
-                        return jcd.getFieldByName(constantName);
-                    }
-                } catch (final SCRDescriptorException sde) {
-                    // try java.lang (FELIX-2906)
-                    try {
-                        final JavaClassDescription jcd = this.manager.getJavaClassDescription("java.lang." + className);
-                        if ( jcd != null ) {
-                            return jcd.getFieldByName(constantName);
-                        }
-                    } catch (final SCRDescriptorException ignore) {
-                        // ignore
-                    }
-                    throw sde;
-                }
-            } else {
-                // we have more than one dot, so this is a fully qualified class
-                final String className = name.substring(0, lastDot);
-                final String constantName = name.substring(lastDot+1);
-                final JavaClassDescription jcd = this.manager.getJavaClassDescription(className);
-                if ( jcd != null ) {
-                    return jcd.getFieldByName(constantName);
-                }
-            }
-        }
-        return null;
-    }
-
-    protected String searchImport(String name) {
-        final String[] imports = this.javaClass.getSource().getImports();
-        if ( imports != null ) {
-            for(int i=0; i<imports.length; i++ ) {
-                if ( imports[i].endsWith(name) ) {
-                    return imports[i];
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getReferencedClass(java.lang.String)
-     */
-    public JavaClassDescription getReferencedClass(final String referencedName) {
-        String className = referencedName;
-        int pos = className.indexOf('.');
-        if ( pos == -1 ) {
-            className = this.searchImport('.' + referencedName);
-        }
-        if ( className == null ) {
-            if ( pos != -1 ) {
-                return null;
-            }
-            className = this.javaClass.getSource().getPackage().getName() + '.' + referencedName;
-        }
-        try {
-            return this.manager.getJavaClassDescription(className);
-        } catch (SCRDescriptorException mee) {
-            return null;
-        }
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getImplementedInterfaces()
-     */
-    public JavaClassDescription[] getImplementedInterfaces()
-    throws SCRDescriptorException {
-        final JavaClass[] interfaces = this.javaClass.getImplementedInterfaces();
-        if ( interfaces == null || interfaces.length == 0 ) {
-            return JavaClassDescription.EMPTY_RESULT;
-        }
-        final JavaClassDescription[] descs = new JavaClassDescription[interfaces.length];
-        for(int i=0;i<interfaces.length; i++) {
-            descs[i] = this.manager.getJavaClassDescription(interfaces[i].getFullyQualifiedName());
-        }
-        return descs;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getMethodBySignature(java.lang.String, java.lang.String[])
-     */
-    public JavaMethod getMethodBySignature(String name, String[] parameters)
-    throws SCRDescriptorException {
-        Type[] types = null;
-        if ( parameters == null || parameters.length == 0 ) {
-            types = new Type[0];
-        } else {
-            types = new Type[parameters.length];
-            for(int i=0;i<parameters.length;i++) {
-                types[i] = new Type(parameters[i]);
-            }
-        }
-        final com.thoughtworks.qdox.model.JavaMethod m = this.javaClass.getMethodBySignature(name, types);
-        if ( m == null ) {
-            if ( this.getSuperClass() != null ) {
-                return this.getSuperClass().getMethodBySignature(name, parameters);
-            }
-            return null;
-        }
-        return new QDoxJavaMethod(m);
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#getMethods()
-     */
-    public JavaMethod[] getMethods() {
-        final com.thoughtworks.qdox.model.JavaMethod[] methods = this.javaClass.getMethods();
-        if ( methods == null || methods.length == 0) {
-            return JavaMethod.EMPTY_RESULT;
-        }
-        final JavaMethod[] m = new JavaMethod[methods.length];
-        for(int i=0;i<methods.length;i++) {
-            m[i] = new QDoxJavaMethod(methods[i]);
-        }
-        return m;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#isA(java.lang.String)
-     */
-    public boolean isA(String type) throws SCRDescriptorException {
-        final Type qType = new Type(type);
-        if ( this.javaClass.isA(type) ) {
-            return true;
-        }
-        final Type[] interfaces = this.javaClass.getImplements();
-        if ( interfaces != null ) {
-            for(int i=0; i<interfaces.length; i++) {
-                if ( interfaces[i].isA(qType) ) {
-                    return true;
-                }
-            }
-        }
-        if ( this.getSuperClass() != null ) {
-            return this.getSuperClass().isA(type);
-        }
-        return false;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#isAbstract()
-     */
-    public boolean isAbstract() {
-        return this.javaClass.isAbstract();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#isInterface()
-     */
-    public boolean isInterface() {
-        return this.javaClass.isInterface();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaClassDescription#isPublic()
-     */
-    public boolean isPublic() {
-        return this.javaClass.isPublic();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.ModifiableJavaClassDescription#addMethods(java.lang.String, java.lang.String, boolean, boolean)
-     */
-    public void addMethods(final String propertyName,
-                           final String className,
-                           final boolean createBind,
-                           final boolean createUnbind)
-    throws SCRDescriptorException {
-        // now do byte code manipulation
-        final String targetDirectory = this.manager.getOutputDirectory();
-        final String fileName = targetDirectory + File.separatorChar +  this.getName().replace('.', File.separatorChar) + ".class";
-        final ClassNode cn = new ClassNode();
-        try {
-            final ClassReader reader = new ClassReader(new FileInputStream(fileName));
-            reader.accept(cn, 0);
-
-            final ClassWriter writer = new ClassWriter(0);
-
-            // remove existing implementation von previous builds
-            final ClassAdapter adapter = new ClassAdapter(writer) {
-
-                protected final String bindMethodName = "bind" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
-                protected final String unbindMethodName = "unbind" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
-                protected final String description = "(L" + className.replace('.', '/') + ";)V";
-
-                /**
-                 * @see org.objectweb.asm.ClassAdapter#visitMethod(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
-                 */
-                public MethodVisitor visitMethod(int access,
-                                                 String name,
-                                                 String desc,
-                                                 String signature,
-                                                 String[] exceptions) {
-                    if ( createBind && name.equals(bindMethodName) && description.equals(desc) ) {
-                        return null;
-                    }
-                    if ( createUnbind && name.equals(unbindMethodName)  && description.equals(desc) ) {
-                        return null;
-                    }
-                    return super.visitMethod(access, name, desc, signature, exceptions);
-                }
-
-            };
-
-            cn.accept(adapter);
-            if ( createBind ) {
-                this.createMethod(writer, propertyName, className, true);
-            }
-            if ( createUnbind ) {
-                this.createMethod(writer, propertyName, className, false);
-            }
-
-            final FileOutputStream fos = new FileOutputStream(fileName);
-            fos.write(writer.toByteArray());
-            fos.close();
-        } catch (Exception e) {
-            throw new SCRDescriptorException("Unable to add methods to " + this.getName(), className, 0, e);
-        }
-    }
-
-    protected void createMethod(ClassWriter cw, String propertyName, String typeName, boolean bind) {
-        final org.objectweb.asm.Type type = org.objectweb.asm.Type.getType("L" + typeName.replace('.', '/') + ";");
-        final String methodName = (bind ? "" : "un") + "bind" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
-        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PROTECTED, methodName, "(" + type.toString() + ")V", null, null);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        if ( bind ) {
-            mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), 1);
-            mv.visitFieldInsn(Opcodes.PUTFIELD, this.getName().replace('.', '/'), propertyName, type.toString());
-        } else {
-            mv.visitFieldInsn(Opcodes.GETFIELD, this.getName().replace('.', '/'), propertyName, type.toString());
-            mv.visitVarInsn(Opcodes.ALOAD, 1);
-            final Label jmpLabel = new Label();
-            mv.visitJumpInsn(Opcodes.IF_ACMPNE, jmpLabel);
-            mv.visitVarInsn(Opcodes.ALOAD, 0);
-            mv.visitInsn(Opcodes.ACONST_NULL);
-            mv.visitFieldInsn(Opcodes.PUTFIELD, this.getName().replace('.', '/'), propertyName, type.toString());
-            mv.visitLabel(jmpLabel);
-        }
-        mv.visitInsn(Opcodes.RETURN);
-        mv.visitMaxs(2, 2);
-        // add to qdox
-        final JavaParameter param = new JavaParameter(new Type(typeName), "param");
-        final JavaParameter[] params = new JavaParameter[] {param};
-        final com.thoughtworks.qdox.model.JavaMethod meth = new com.thoughtworks.qdox.model.JavaMethod();
-        meth.setName(methodName);
-        for(int i=0;i<params.length;i++) {
-            meth.addParameter(params[i]);
-        }
-        meth.setModifiers(new String[] {"protected"});
-        this.javaClass.addMethod(meth);
-    }
-
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString() {
-        return getName();
-    }
-
-    public Class<?> getCompiledClass() {
-        return this.clazz;
-    }
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaField.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaField.java
deleted file mode 100644
index 5719e73..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaField.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.scrplugin.tags.qdox;
-
-import org.apache.felix.scrplugin.tags.*;
-
-import com.thoughtworks.qdox.model.DocletTag;
-
-/**
- * <code>QDoxJavaField.java</code>...
- *
- */
-public class QDoxJavaField implements JavaField {
-
-    protected final com.thoughtworks.qdox.model.JavaField field;
-
-    protected final QDoxJavaClassDescription description;
-
-    public QDoxJavaField(com.thoughtworks.qdox.model.JavaField f, QDoxJavaClassDescription d) {
-        this.field = f;
-        this.description = d;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaField#getInitializationExpression()
-     */
-    public String[] getInitializationExpression() {
-        String[] values = ClassUtil.getInitializationExpression(this.description.getCompiledClass(), this.getName());
-        if ( values == null ) {
-            // try qdox
-            String value = this.field.getInitializationExpression();
-            if ( value != null ) {
-                int pos = value.indexOf("\"");
-                if ( pos != -1 ) {
-                    try {
-                        value = value.substring(pos + 1);
-                        value = value.substring(0, value.lastIndexOf("\""));
-                    } catch (ArrayIndexOutOfBoundsException aioobe) {
-                        // ignore this as this is a qdox problem
-                        value = this.field.getInitializationExpression();
-                    }
-                }
-                values = new String[] {value};
-            }
-        }
-        return values;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaField#getName()
-     */
-    public String getName() {
-        return this.field.getName();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaField#getTagByName(java.lang.String)
-     */
-    public JavaTag getTagByName(String name) {
-        final DocletTag tag = this.field.getTagByName(name);
-        if ( tag == null ) {
-            return null;
-        }
-        return new QDoxJavaTag(tag, this.description, this);
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaField#getType()
-     */
-    public String getType() {
-        return this.field.getType().getValue();
-    }
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaMethod.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaMethod.java
deleted file mode 100644
index eaf3565..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaMethod.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.scrplugin.tags.qdox;
-
-import org.apache.felix.scrplugin.tags.JavaMethod;
-import org.apache.felix.scrplugin.tags.JavaParameter;
-
-/**
- * <code>QDoxJavaMethod.java</code>...
- *
- */
-public class QDoxJavaMethod implements JavaMethod {
-
-    protected final com.thoughtworks.qdox.model.JavaMethod method;
-
-    public QDoxJavaMethod(com.thoughtworks.qdox.model.JavaMethod m) {
-        this.method = m;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaMethod#getName()
-     */
-    public String getName() {
-        return this.method.getName();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaMethod#getParameters()
-     */
-    public JavaParameter[] getParameters() {
-        final com.thoughtworks.qdox.model.JavaParameter[] params = this.method.getParameters();
-        if ( params == null || params.length == 0) {
-            return new JavaParameter[0];
-        }
-        final JavaParameter[] p = new JavaParameter[params.length];
-        for(int i=0; i<params.length; i++) {
-            p[i] = new QDoxJavaParameter(params[i]);
-        }
-        return p;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaMethod#isConstructor()
-     */
-    public boolean isConstructor() {
-        return this.method.isConstructor();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaMethod#isProtected()
-     */
-    public boolean isProtected() {
-        return this.method.isProtected();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaMethod#isPublic()
-     */
-    public boolean isPublic() {
-        return this.method.isPublic();
-    }
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaParameter.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaParameter.java
deleted file mode 100644
index 3ba6ccb..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaParameter.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.scrplugin.tags.qdox;
-
-import org.apache.felix.scrplugin.tags.JavaParameter;
-
-/**
- * <code>QDoxJavaParameter.java</code>...
- *
- */
-public class QDoxJavaParameter implements JavaParameter {
-
-    protected final com.thoughtworks.qdox.model.JavaParameter parameter;
-
-    public QDoxJavaParameter(com.thoughtworks.qdox.model.JavaParameter p) {
-        this.parameter = p;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaParameter#getType()
-     */
-    public String getType() {
-        return this.parameter.getType().getValue();
-    }
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaTag.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaTag.java
deleted file mode 100644
index 3ccf010..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaTag.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.scrplugin.tags.qdox;
-
-import java.util.Map;
-
-import org.apache.felix.scrplugin.tags.*;
-
-import com.thoughtworks.qdox.model.DocletTag;
-
-/**
- * <code>QDoxJavaTag.java</code>...
- *
- */
-public class QDoxJavaTag implements JavaTag {
-
-    protected final DocletTag docletTag;
-
-    protected final JavaClassDescription description;
-
-    protected final JavaField field;
-
-    public QDoxJavaTag(DocletTag t, JavaClassDescription desc) {
-        this(t, desc, null);
-    }
-
-    public QDoxJavaTag(DocletTag t, JavaClassDescription desc, JavaField field) {
-        this.docletTag = t;
-        this.description = desc;
-        this.field = field;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getName()
-     */
-    public String getName() {
-        return this.docletTag.getName();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getSourceName()
-     */
-    public String getSourceName() {
-        return this.getName();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getNamedParameter(java.lang.String)
-     */
-    public String getNamedParameter(String arg0) {
-        return this.docletTag.getNamedParameter(arg0);
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getParameters()
-     */
-    public String[] getParameters() {
-        return this.docletTag.getParameters();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getSourceLocation()
-     */
-    public String getSourceLocation() {
-        if ( this.docletTag.getContext().getParent() != null ) {
-            return String.valueOf(this.docletTag.getContext().getParent().getParentSource().getURL());
-        }
-        return String.valueOf(this.docletTag.getContext().getParentClass().getSource().getURL());
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getLineNumber()
-     */
-    public int getLineNumber() {
-        return this.docletTag.getLineNumber();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getJavaClassDescription()
-     */
-    public JavaClassDescription getJavaClassDescription() {
-        return this.description;
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getNamedParameterMap()
-     */
-    @SuppressWarnings("unchecked")
-    public Map<String, String> getNamedParameterMap() {
-        return this.docletTag.getNamedParameterMap();
-    }
-
-    /**
-     * @see org.apache.felix.scrplugin.tags.JavaTag#getField()
-     */
-    public JavaField getField() {
-        return this.field;
-    }
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/ComponentDescriptorIO.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/ComponentDescriptorIO.java
index 1f7be91..32d6db5 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/ComponentDescriptorIO.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/ComponentDescriptorIO.java
@@ -18,15 +18,39 @@
  */
 package org.apache.felix.scrplugin.xml;
 
-import java.io.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.StringTokenizer;
 
 import javax.xml.transform.TransformerException;
 
-import org.apache.felix.scrplugin.Constants;
 import org.apache.felix.scrplugin.SCRDescriptorException;
-import org.apache.felix.scrplugin.om.*;
-import org.xml.sax.*;
+import org.apache.felix.scrplugin.description.ClassDescription;
+import org.apache.felix.scrplugin.description.ComponentConfigurationPolicy;
+import org.apache.felix.scrplugin.description.ComponentDescription;
+import org.apache.felix.scrplugin.description.MethodDescription;
+import org.apache.felix.scrplugin.description.PropertyDescription;
+import org.apache.felix.scrplugin.description.PropertyType;
+import org.apache.felix.scrplugin.description.ReferenceCardinality;
+import org.apache.felix.scrplugin.description.ReferenceDescription;
+import org.apache.felix.scrplugin.description.ReferencePolicy;
+import org.apache.felix.scrplugin.description.ReferenceStrategy;
+import org.apache.felix.scrplugin.description.ServiceDescription;
+import org.apache.felix.scrplugin.description.SpecVersion;
+import org.apache.felix.scrplugin.helper.IssueLog;
+import org.apache.felix.scrplugin.om.Component;
+import org.apache.felix.scrplugin.om.Components;
+import org.apache.felix.scrplugin.om.Implementation;
+import org.apache.felix.scrplugin.om.Interface;
+import org.apache.felix.scrplugin.om.Property;
+import org.apache.felix.scrplugin.om.Reference;
+import org.apache.felix.scrplugin.om.Service;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
 import org.xml.sax.helpers.AttributesImpl;
 import org.xml.sax.helpers.DefaultHandler;
 
@@ -106,27 +130,28 @@
 
     private static final String INTERFACE_QNAME = INTERFACE;
 
-    public static Components read(InputStream file)
-    throws SCRDescriptorException {
+    public static List<ClassDescription> read(final InputStream file,
+                    final ClassLoader classLoader,
+                    final IssueLog iLog, final String location) throws SCRDescriptorException {
         try {
-            final XmlHandler xmlHandler = new XmlHandler();
+            final XmlHandler xmlHandler = new XmlHandler(classLoader, iLog, location);
             IOUtils.parse(file, xmlHandler);
             return xmlHandler.components;
-        } catch (TransformerException e) {
-            throw new SCRDescriptorException( "Unable to read xml", "[stream]", 0, e );
+        } catch (final TransformerException e) {
+            throw new SCRDescriptorException("Unable to read xml", "[stream]", 0, e);
         }
     }
 
     /**
      * Write the component descriptors to the file.
+     *
      * @param components
      * @param file
      * @throws SCRDescriptorException
      */
-    public static void write(Components components, File file, boolean isScrPrivateFile)
-    throws SCRDescriptorException {
+    public static void write(Components components, File file) throws SCRDescriptorException {
         try {
-            generateXML(components, IOUtils.getSerializer(file), isScrPrivateFile);
+            generateXML(components, IOUtils.getSerializer(file));
         } catch (TransformerException e) {
             throw new SCRDescriptorException("Unable to write xml", file.toString(), 0, e);
         } catch (SAXException e) {
@@ -139,17 +164,17 @@
     /**
      * Generate the xml top level element and start streaming
      * the components.
+     *
      * @param components
      * @param contentHandler
      * @throws SAXException
      */
-    protected static void generateXML(Components components, ContentHandler contentHandler, boolean isScrPrivateFile)
-    throws SAXException {
+    protected static void generateXML(Components components, ContentHandler contentHandler) throws SAXException {
         // detect namespace to use
         final String namespace;
-        if ( components.getSpecVersion() == Constants.VERSION_1_0 ) {
+        if (components.getSpecVersion() == SpecVersion.VERSION_1_0) {
             namespace = NAMESPACE_URI_1_0;
-        } else if ( components.getSpecVersion() == Constants.VERSION_1_1 ) {
+        } else if (components.getSpecVersion() == SpecVersion.VERSION_1_1) {
             namespace = NAMESPACE_URI_1_1;
         } else {
             namespace = NAMESPACE_URI_1_1_FELIX;
@@ -161,9 +186,9 @@
         contentHandler.startElement("", ComponentDescriptorIO.COMPONENTS, ComponentDescriptorIO.COMPONENTS, new AttributesImpl());
         IOUtils.newline(contentHandler);
 
-        for(final Component component : components.getComponents()) {
-            if ( component.isDs() ) {
-                generateXML(namespace, component, contentHandler, isScrPrivateFile);
+        for (final Component component : components.getComponents()) {
+            if (component.isDs()) {
+                generateXML(namespace, component, contentHandler);
             }
         }
         // end wrapper element
@@ -175,24 +200,24 @@
 
     /**
      * Write the xml for a {@link Component}.
+     *
      * @param component
      * @param contentHandler
      * @throws SAXException
      */
-    protected static void generateXML(final String namespace,
-                                      final Component component,
-                                      final ContentHandler contentHandler,
-                                      final boolean isScrPrivateFile)
-    throws SAXException {
+    protected static void generateXML(final String namespace, final Component component, final ContentHandler contentHandler)
+                    throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
         IOUtils.addAttribute(ai, COMPONENT_ATTR_ENABLED, component.isEnabled());
-        IOUtils.addAttribute(ai, COMPONENT_ATTR_IMMEDIATE,component.isImmediate());
+        IOUtils.addAttribute(ai, COMPONENT_ATTR_IMMEDIATE, component.isImmediate());
         IOUtils.addAttribute(ai, COMPONENT_ATTR_NAME, component.getName());
         IOUtils.addAttribute(ai, COMPONENT_ATTR_FACTORY, component.getFactory());
 
         // attributes new in 1.1
-        if ( NAMESPACE_URI_1_1.equals( namespace ) || NAMESPACE_URI_1_1_FELIX.equals( namespace ) ) {
-            IOUtils.addAttribute(ai, COMPONENT_ATTR_POLICY, component.getConfigurationPolicy());
+        if (NAMESPACE_URI_1_1.equals(namespace) || NAMESPACE_URI_1_1_FELIX.equals(namespace)) {
+            if ( component.getConfigurationPolicy() != ComponentConfigurationPolicy.OPTIONAL ) {
+                IOUtils.addAttribute(ai, COMPONENT_ATTR_POLICY, component.getConfigurationPolicy().name());
+            }
             IOUtils.addAttribute(ai, COMPONENT_ATTR_ACTIVATE, component.getActivate());
             IOUtils.addAttribute(ai, COMPONENT_ATTR_DEACTIVATE, component.getDeactivate());
             IOUtils.addAttribute(ai, COMPONENT_ATTR_MODIFIED, component.getModified());
@@ -202,17 +227,17 @@
         contentHandler.startElement(namespace, ComponentDescriptorIO.COMPONENT, ComponentDescriptorIO.COMPONENT_QNAME, ai);
         IOUtils.newline(contentHandler);
         generateXML(component.getImplementation(), contentHandler);
-        if ( component.getService() != null ) {
+        if (component.getService() != null) {
             generateXML(component.getService(), contentHandler);
         }
-        if ( component.getProperties() != null ) {
-            for(final Property property : component.getProperties()) {
-                generateXML(property, contentHandler, isScrPrivateFile);
+        if (component.getProperties() != null) {
+            for (final Property property : component.getProperties()) {
+                generateXML(property, contentHandler);
             }
         }
-        if ( component.getReferences() != null ) {
-            for(final Reference reference : component.getReferences()) {
-                generateXML(namespace, reference, contentHandler, isScrPrivateFile);
+        if (component.getReferences() != null) {
+            for (final Reference reference : component.getReferences()) {
+                generateXML(namespace, reference, contentHandler);
             }
         }
         IOUtils.indent(contentHandler, 1);
@@ -222,35 +247,37 @@
 
     /**
      * Write the xml for a {@link Implementation}.
+     *
      * @param implementation
      * @param contentHandler
      * @throws SAXException
      */
-    protected static void generateXML(Implementation implementation, ContentHandler contentHandler)
-    throws SAXException {
+    protected static void generateXML(Implementation implementation, ContentHandler contentHandler) throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
-        IOUtils.addAttribute(ai, "class", implementation.getClassame());
+        IOUtils.addAttribute(ai, "class", implementation.getClassName());
         IOUtils.indent(contentHandler, 2);
-        contentHandler.startElement(INNER_NAMESPACE_URI, ComponentDescriptorIO.IMPLEMENTATION, ComponentDescriptorIO.IMPLEMENTATION_QNAME, ai);
-        contentHandler.endElement(INNER_NAMESPACE_URI, ComponentDescriptorIO.IMPLEMENTATION, ComponentDescriptorIO.IMPLEMENTATION_QNAME);
+        contentHandler.startElement(INNER_NAMESPACE_URI, ComponentDescriptorIO.IMPLEMENTATION,
+                        ComponentDescriptorIO.IMPLEMENTATION_QNAME, ai);
+        contentHandler.endElement(INNER_NAMESPACE_URI, ComponentDescriptorIO.IMPLEMENTATION,
+                        ComponentDescriptorIO.IMPLEMENTATION_QNAME);
         IOUtils.newline(contentHandler);
     }
 
     /**
      * Write the xml for a {@link Service}.
+     *
      * @param service
      * @param contentHandler
      * @throws SAXException
      */
-    protected static void generateXML(Service service, ContentHandler contentHandler)
-    throws SAXException {
+    protected static void generateXML(Service service, ContentHandler contentHandler) throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
-        IOUtils.addAttribute(ai, "servicefactory", String.valueOf(service.isServicefactory()));
+        IOUtils.addAttribute(ai, "servicefactory", String.valueOf(service.isServiceFactory()));
         IOUtils.indent(contentHandler, 2);
         contentHandler.startElement(INNER_NAMESPACE_URI, ComponentDescriptorIO.SERVICE, ComponentDescriptorIO.SERVICE_QNAME, ai);
-        if ( service.getInterfaces() != null && service.getInterfaces().size() > 0 ) {
+        if (service.getInterfaces() != null && service.getInterfaces().size() > 0) {
             IOUtils.newline(contentHandler);
-            for(final Interface interf : service.getInterfaces()) {
+            for (final Interface interf : service.getInterfaces()) {
                 generateXML(interf, contentHandler);
             }
             IOUtils.indent(contentHandler, 2);
@@ -261,51 +288,40 @@
 
     /**
      * Write the xml for a {@link Interface}.
+     *
      * @param interf
      * @param contentHandler
      * @throws SAXException
      */
-    protected static void generateXML(Interface interf, ContentHandler contentHandler)
-    throws SAXException {
+    protected static void generateXML(Interface interf, ContentHandler contentHandler) throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
-        IOUtils.addAttribute(ai, "interface", interf.getInterfacename());
+        IOUtils.addAttribute(ai, "interface", interf.getInterfaceName());
         IOUtils.indent(contentHandler, 3);
-        contentHandler.startElement(INNER_NAMESPACE_URI, ComponentDescriptorIO.INTERFACE, ComponentDescriptorIO.INTERFACE_QNAME, ai);
+        contentHandler.startElement(INNER_NAMESPACE_URI, ComponentDescriptorIO.INTERFACE, ComponentDescriptorIO.INTERFACE_QNAME,
+                        ai);
         contentHandler.endElement(INNER_NAMESPACE_URI, ComponentDescriptorIO.INTERFACE, ComponentDescriptorIO.INTERFACE_QNAME);
         IOUtils.newline(contentHandler);
     }
 
     /**
      * Write the xml for a {@link Property}.
+     *
      * @param property
      * @param contentHandler
      * @throws SAXException
      */
-    protected static void generateXML(Property property, ContentHandler contentHandler, boolean isScrPrivateFile)
-    throws SAXException {
+    protected static void generateXML(Property property, ContentHandler contentHandler) throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
         IOUtils.addAttribute(ai, "name", property.getName());
         IOUtils.addAttribute(ai, "type", property.getType());
         IOUtils.addAttribute(ai, "value", property.getValue());
-        // we have to write more information if this is our scr private file
-        if ( isScrPrivateFile ) {
-            IOUtils.addAttribute(ai, "private", String.valueOf(property.isPrivate()));
-            if ( property.getLabel() != null ) {
-                IOUtils.addAttribute(ai, "label", String.valueOf(property.getLabel()));
-            }
-            if ( property.getDescription() != null ) {
-                IOUtils.addAttribute(ai, "description", String.valueOf(property.getDescription()));
-            }
-            if ( property.getCardinality() != null ) {
-                IOUtils.addAttribute(ai, "cardinality", String.valueOf(property.getCardinality()));
-            }
-        }
+
         IOUtils.indent(contentHandler, 2);
         contentHandler.startElement(INNER_NAMESPACE_URI, ComponentDescriptorIO.PROPERTY, ComponentDescriptorIO.PROPERTY_QNAME, ai);
-        if ( property.getMultiValue() != null && property.getMultiValue().length > 0 ) {
+        if (property.getMultiValue() != null && property.getMultiValue().length > 0) {
             // generate a new line first
             IOUtils.text(contentHandler, "\n");
-            for(int i=0; i<property.getMultiValue().length; i++) {
+            for (int i = 0; i < property.getMultiValue().length; i++) {
                 IOUtils.indent(contentHandler, 3);
                 IOUtils.text(contentHandler, property.getMultiValue()[i]);
                 IOUtils.newline(contentHandler);
@@ -318,32 +334,30 @@
 
     /**
      * Write the xml for a {@link Reference}.
+     *
      * @param reference
      * @param contentHandler
      * @throws SAXException
      */
-    protected static void generateXML(final String namespace,Reference reference, ContentHandler contentHandler, boolean isScrPrivateFile)
-    throws SAXException {
+    protected static void generateXML(final String namespace, Reference reference, ContentHandler contentHandler)
+                    throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
         IOUtils.addAttribute(ai, "name", reference.getName());
         IOUtils.addAttribute(ai, "interface", reference.getInterfacename());
-        IOUtils.addAttribute(ai, "cardinality", reference.getCardinality());
-        IOUtils.addAttribute(ai, "policy", reference.getPolicy());
+        IOUtils.addAttribute(ai, "cardinality", reference.getCardinality().getCardinalityString());
+        IOUtils.addAttribute(ai, "policy", reference.getPolicy().name());
         IOUtils.addAttribute(ai, "target", reference.getTarget());
         IOUtils.addAttribute(ai, "bind", reference.getBind());
         IOUtils.addAttribute(ai, "unbind", reference.getUnbind());
 
         // attributes new in 1.1-felix (FELIX-1893)
-        if ( NAMESPACE_URI_1_1_FELIX.equals( namespace ) ) {
+        if (NAMESPACE_URI_1_1_FELIX.equals(namespace)) {
             IOUtils.addAttribute(ai, "updated", reference.getUpdated());
         }
 
-        if ( isScrPrivateFile ) {
-            IOUtils.addAttribute(ai, "checked", String.valueOf(reference.isChecked()));
-            IOUtils.addAttribute(ai, "strategy", reference.getStrategy());
-        }
         IOUtils.indent(contentHandler, 2);
-        contentHandler.startElement(INNER_NAMESPACE_URI, ComponentDescriptorIO.REFERENCE, ComponentDescriptorIO.REFERENCE_QNAME, ai);
+        contentHandler.startElement(INNER_NAMESPACE_URI, ComponentDescriptorIO.REFERENCE, ComponentDescriptorIO.REFERENCE_QNAME,
+                        ai);
         contentHandler.endElement(INNER_NAMESPACE_URI, ComponentDescriptorIO.REFERENCE, ComponentDescriptorIO.REFERENCE_QNAME);
         IOUtils.newline(contentHandler);
     }
@@ -355,120 +369,169 @@
     protected static final class XmlHandler extends DefaultHandler {
 
         /** The components container. */
-        protected final Components components = new Components();
+        private final List<ClassDescription> components = new ArrayList<ClassDescription>();
+
+        /** Spec version. */
+        private SpecVersion specVersion;
+
+        /** A reference to the current class. */
+        private ClassDescription currentClass;
 
         /** A reference to the current component. */
-        protected Component currentComponent;
+        private ComponentDescription currentComponent;
 
         /** The current service. */
-        protected Service currentService;
+        private ServiceDescription currentService;
 
         /** Pending property. */
-        protected Property pendingProperty;
+        private PropertyDescription pendingProperty;
 
         /** Flag for detecting the first element. */
-        protected boolean firstElement = true;
+        private boolean firstElement = true;
 
         /** Flag for elements inside a component element */
-        protected boolean isComponent = false;
+        private boolean isComponent = false;
 
         /** Override namespace. */
-        protected String overrideNamespace;
+        private String overrideNamespace;
 
-        public void startElement(String uri, String localName, String name, Attributes attributes)
+        /** The issue log. */
+        private final IssueLog iLog;
+
+        /** XML file location. */
+        private final String location;
+
+        /** Classloader. */
+        private final ClassLoader classLoader;
+
+        public XmlHandler(final ClassLoader classLoader, final IssueLog iLog, final String loc) {
+            this.iLog = iLog;
+            this.location = loc;
+            this.classLoader = classLoader;
+        }
+
+        /**
+         * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+         */
+        public void startElement(String uri, final String localName, final String name, final Attributes attributes)
         throws SAXException {
             // according to the spec, the elements should have the namespace,
             // except when the root element is the "component" element
             // So we check this for the first element, we receive.
-            if ( this.firstElement ) {
+            if (this.firstElement) {
                 this.firstElement = false;
-                if ( localName.equals(COMPONENT) && "".equals(uri) ) {
+                if (localName.equals(COMPONENT) && "".equals(uri)) {
                     this.overrideNamespace = NAMESPACE_URI_1_0;
                 }
             }
 
-            if ( this.overrideNamespace != null && "".equals(uri) ) {
+            if (this.overrideNamespace != null && "".equals(uri)) {
                 uri = this.overrideNamespace;
             }
 
             // however the spec also states that the inner elements
             // of a component are unqualified, so they don't have
             // the namespace - we allow both: with or without namespace!
-            if ( this.isComponent && "".equals(uri) )  {
+            if (this.isComponent && "".equals(uri)) {
                 uri = NAMESPACE_URI_1_0;
             }
 
             // from here on, uri has the namespace regardless of the used xml format
-            if ( NAMESPACE_URI_1_0.equals( uri ) || NAMESPACE_URI_1_1.equals( uri )
-                || NAMESPACE_URI_1_1_FELIX.equals( uri ) ) {
+            if (NAMESPACE_URI_1_0.equals(uri) || NAMESPACE_URI_1_1.equals(uri) || NAMESPACE_URI_1_1_FELIX.equals(uri)) {
 
-                if ( NAMESPACE_URI_1_1.equals(uri) ) {
-                    components.setSpecVersion(Constants.VERSION_1_1);
-                } else if ( NAMESPACE_URI_1_1_FELIX.equals(uri) ) {
-                    components.setSpecVersion(Constants.VERSION_1_1_FELIX);
+                if (NAMESPACE_URI_1_0.equals(uri)) {
+                    specVersion = SpecVersion.VERSION_1_0;
+                } else if (NAMESPACE_URI_1_1.equals(uri)) {
+                    specVersion = SpecVersion.VERSION_1_1;
+                } else if (NAMESPACE_URI_1_1_FELIX.equals(uri)) {
+                    specVersion = SpecVersion.VERSION_1_1_FELIX;
                 }
 
                 if (localName.equals(COMPONENT)) {
                     this.isComponent = true;
 
-                    this.currentComponent = new Component();
-                    this.currentComponent.setName(attributes.getValue(COMPONENT_ATTR_NAME));
+                    final ComponentDescription desc = new ComponentDescription(null);
+                    desc.setName(attributes.getValue(COMPONENT_ATTR_NAME));
 
                     // enabled attribute is optional
                     if (attributes.getValue(COMPONENT_ATTR_ENABLED) != null) {
-                        this.currentComponent.setEnabled(Boolean.valueOf(attributes.getValue(COMPONENT_ATTR_ENABLED)));
+                        desc.setEnabled(Boolean.valueOf(attributes.getValue(COMPONENT_ATTR_ENABLED)));
                     }
 
                     // immediate attribute is optional
                     if (attributes.getValue(COMPONENT_ATTR_IMMEDIATE) != null) {
-                        this.currentComponent.setImmediate(Boolean.valueOf(attributes.getValue(COMPONENT_ATTR_IMMEDIATE)));
+                        desc.setImmediate(Boolean.valueOf(attributes.getValue(COMPONENT_ATTR_IMMEDIATE)));
                     }
 
-                    this.currentComponent.setFactory(attributes.getValue(COMPONENT_ATTR_FACTORY));
+                    desc.setFactory(attributes.getValue(COMPONENT_ATTR_FACTORY));
 
+                    desc.setConfigurationPolicy(ComponentConfigurationPolicy.OPTIONAL);
                     // check for version 1.1 attributes
-                    if ( components.getSpecVersion() == Constants.VERSION_1_1 ) {
-                        this.currentComponent.setConfigurationPolicy(attributes.getValue(COMPONENT_ATTR_POLICY));
-                        this.currentComponent.setActivate(attributes.getValue(COMPONENT_ATTR_ACTIVATE));
-                        this.currentComponent.setDeactivate(attributes.getValue(COMPONENT_ATTR_DEACTIVATE));
-                        this.currentComponent.setModified(attributes.getValue(COMPONENT_ATTR_MODIFIED));
+                    if (specVersion == SpecVersion.VERSION_1_1
+                                    || specVersion == SpecVersion.VERSION_1_1_FELIX) {
+                        final String policy = attributes.getValue(COMPONENT_ATTR_POLICY);
+                        if ( policy != null ) {
+                            try {
+                                desc.setConfigurationPolicy(ComponentConfigurationPolicy.valueOf(policy));
+                            } catch (final IllegalArgumentException iae) {
+                                iLog.addWarning("Invalid value for attribute " + COMPONENT_ATTR_POLICY + " : " + policy, this.location);
+                            }
+                        }
+                        if ( attributes.getValue(COMPONENT_ATTR_ACTIVATE) != null ) {
+                            desc.setActivate(new MethodDescription(attributes.getValue(COMPONENT_ATTR_ACTIVATE)));
+                        }
+                        if ( attributes.getValue(COMPONENT_ATTR_DEACTIVATE) != null ) {
+                            desc.setDeactivate(new MethodDescription(attributes.getValue(COMPONENT_ATTR_DEACTIVATE)));
+                        }
+                        if ( attributes.getValue(COMPONENT_ATTR_MODIFIED) != null ) {
+                            desc.setModified(new MethodDescription(attributes.getValue(COMPONENT_ATTR_MODIFIED)));
+                        }
                     }
                 } else if (localName.equals(IMPLEMENTATION)) {
+                    // now we can create the class description and attach the component description
                     // Set the implementation class name (mandatory)
-                    final Implementation impl = new Implementation();
-                    this.currentComponent.setImplementation(impl);
-                    impl.setClassname(attributes.getValue("class"));
+                    try {
+                        this.currentClass = new ClassDescription(this.classLoader.loadClass(attributes.getValue("class")), null);
+                    } catch (final ClassNotFoundException e) {
+                        iLog.addError("Unable to load class " + attributes.getValue("class") + " from dependencies.", this.location);
+                    }
+                    this.currentClass.add(this.currentComponent);
 
                 } else if (localName.equals(PROPERTY)) {
 
                     // read the property, unless it is the service.pid
                     // property which must not be inherited
-                    final String propName = attributes.getValue( "name" );
-                    if ( !org.osgi.framework.Constants.SERVICE_PID.equals( propName ) )
-                    {
-                        final Property prop = new Property();
+                    final String propName = attributes.getValue("name");
+                    if (!org.osgi.framework.Constants.SERVICE_PID.equals(propName)) {
+                        final PropertyDescription prop = new PropertyDescription(null);
 
-                        prop.setName( propName );
-                        prop.setType( attributes.getValue( "type" ) );
-
-                        if ( attributes.getValue( "value" ) != null )
-                        {
-                            prop.setValue( attributes.getValue( "value" ) );
-                            this.currentComponent.addProperty( prop );
+                        prop.setName(propName);
+                        final String type = attributes.getValue("type");
+                        if ( type != null ) {
+                            try {
+                                prop.setType(PropertyType.valueOf(type));
+                            } catch (final IllegalArgumentException iae) {
+                                iLog.addWarning("Invalid value for attribute type : " + type, this.location);
+                            }
                         }
-                        else
-                        {
+
+                        if (attributes.getValue("value") != null) {
+                            prop.setValue(attributes.getValue("value"));
+                            this.currentClass.add(prop);
+                        } else {
                             // hold the property pending as we have a multi value
                             this.pendingProperty = prop;
                         }
                         // check for abstract properties
-                        prop.setLabel( attributes.getValue( "label" ) );
-                        prop.setDescription( attributes.getValue( "description" ) );
-                        prop.setCardinality( attributes.getValue( "cardinality" ) );
-                        final String pValue = attributes.getValue( "private" );
-                        if ( pValue != null )
-                        {
-                            prop.setPrivate( Boolean.valueOf( pValue ).booleanValue() );
+                        prop.setLabel(attributes.getValue("label"));
+                        prop.setDescription(attributes.getValue("description"));
+                        final String cardinality = attributes.getValue("cardinality");
+                        if ( cardinality != null ) {
+                            prop.setCardinality(Integer.valueOf(cardinality));
+                        }
+                        final String pValue = attributes.getValue("private");
+                        if (pValue != null) {
+                            prop.setPrivate(Boolean.valueOf(pValue));
                         }
                     }
 
@@ -478,36 +541,54 @@
 
                 } else if (localName.equals(SERVICE)) {
 
-                    this.currentService = new Service();
+                    this.currentService = new ServiceDescription(null);
+                    this.currentClass.add(this.currentService);
 
-                    this.currentService.setServicefactory(attributes.getValue("servicefactory"));
-
-                    this.currentComponent.setService(this.currentService);
+                    if (attributes.getValue("servicefactory") != null) {
+                        this.currentService.setServiceFactory(Boolean.valueOf(attributes.getValue("servicefactory")));
+                    }
 
                 } else if (localName.equals(INTERFACE)) {
-                    final Interface interf = new Interface();
-                    this.currentService.addInterface(interf);
-                    interf.setInterfacename(attributes.getValue("interface"));
+                    this.currentService.addInterface(attributes.getValue("interface"));
 
                 } else if (localName.equals(REFERENCE)) {
-                    final Reference ref = new Reference();
+                    final ReferenceDescription ref = new ReferenceDescription(null);
 
                     ref.setName(attributes.getValue("name"));
-                    ref.setInterfacename(attributes.getValue("interface"));
-                    ref.setCardinality(attributes.getValue("cardinality"));
-                    ref.setPolicy(attributes.getValue("policy"));
+                    ref.setInterfaceName(attributes.getValue("interface"));
+                    final String cardinality = attributes.getValue("cardinality");
+                    if ( cardinality != null ) {
+                        ref.setCardinality(ReferenceCardinality.fromValue(cardinality));
+                        if ( ref.getCardinality() == null ) {
+                            iLog.addWarning("Invalid value for attribute cardinality : " + cardinality, this.location);
+                        }
+                    }
+                    final String policy = attributes.getValue("policy");
+                    if ( policy != null ) {
+                        try {
+                            ref.setPolicy(ReferencePolicy.valueOf(policy));
+                        } catch (final IllegalArgumentException iae) {
+                            iLog.addWarning("Invalid value for attribute policy : " + policy, this.location);
+                        }
+                    }
                     ref.setTarget(attributes.getValue("target"));
-                    ref.setBind(attributes.getValue("bind"));
-                    ref.setUnbind(attributes.getValue("unbind"));
-
-                    if ( attributes.getValue("checked") != null ) {
-                        ref.setChecked(Boolean.valueOf(attributes.getValue("checked")).booleanValue());
+                    if ( attributes.getValue("bind") != null ) {
+                        ref.setBind(new MethodDescription(attributes.getValue("bind")));
                     }
-                    if ( attributes.getValue("strategy") != null ) {
-                        ref.setStrategy(attributes.getValue("strategy"));
+                    if ( attributes.getValue("unbind") != null ) {
+                        ref.setUnbind(new MethodDescription(attributes.getValue("unbind")));
                     }
 
-                    this.currentComponent.addReference(ref);
+                    final String strategy = attributes.getValue("strategy");
+                    if ( strategy != null ) {
+                        try {
+                            ref.setStrategy(ReferenceStrategy.valueOf(strategy));
+                        } catch (final IllegalArgumentException iae) {
+                            throw new SAXException("Invalid value for attribute strategy : " + strategy);
+                        }
+                    }
+
+                    this.currentClass.add(ref);
                 }
             }
         }
@@ -516,35 +597,33 @@
          * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
          */
         public void endElement(String uri, String localName, String name) throws SAXException {
-            if ( this.overrideNamespace != null && "".equals(uri) ) {
+            if (this.overrideNamespace != null && "".equals(uri)) {
                 uri = this.overrideNamespace;
             }
 
-            if ( this.isComponent && "".equals(uri) )  {
+            if (this.isComponent && "".equals(uri)) {
                 uri = NAMESPACE_URI_1_0;
             }
 
-            if ( NAMESPACE_URI_1_0.equals( uri ) || NAMESPACE_URI_1_1.equals( uri )
-                || NAMESPACE_URI_1_1_FELIX.equals( uri ) )
-            {
-                if (localName.equals(COMPONENT) ) {
-                    this.components.addComponent(this.currentComponent);
+            if (NAMESPACE_URI_1_0.equals(uri) || NAMESPACE_URI_1_1.equals(uri) || NAMESPACE_URI_1_1_FELIX.equals(uri)) {
+                if (localName.equals(COMPONENT)) {
+                    this.currentClass = null;
                     this.currentComponent = null;
                     this.isComponent = false;
                 } else if (localName.equals(PROPERTY) && this.pendingProperty != null) {
                     // now split the value
                     final String text = this.pendingProperty.getValue();
-                    if ( text != null ) {
+                    if (text != null) {
                         final StringTokenizer st = new StringTokenizer(text);
                         final String[] values = new String[st.countTokens()];
                         int index = 0;
-                        while ( st.hasMoreTokens() ) {
+                        while (st.hasMoreTokens()) {
                             values[index] = st.nextToken();
                             index++;
                         }
                         this.pendingProperty.setMultiValue(values);
                     }
-                    this.currentComponent.addProperty(this.pendingProperty);
+                    this.currentClass.add(this.pendingProperty);
                     this.pendingProperty = null;
                 }
             }
@@ -554,9 +633,9 @@
          * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
          */
         public void characters(char[] ch, int start, int length) throws SAXException {
-            if ( this.pendingProperty != null ) {
+            if (this.pendingProperty != null) {
                 final String text = new String(ch, start, length);
-                if ( this.pendingProperty.getValue() == null ) {
+                if (this.pendingProperty.getValue() == null) {
                     this.pendingProperty.setValue(text);
                 } else {
                     this.pendingProperty.setValue(this.pendingProperty.getValue() + text);