FELIX-3550 : Reimplement the SCR Generator

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1354338 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scrplugin/annotations/src/main/java/org/apache/felix/scrplugin/processing/SCRAnnotationProcessor.java b/scrplugin/annotations/src/main/java/org/apache/felix/scrplugin/processing/SCRAnnotationProcessor.java
index 986fc5f..584a4a2 100644
--- a/scrplugin/annotations/src/main/java/org/apache/felix/scrplugin/processing/SCRAnnotationProcessor.java
+++ b/scrplugin/annotations/src/main/java/org/apache/felix/scrplugin/processing/SCRAnnotationProcessor.java
@@ -46,7 +46,6 @@
 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.PropertyUnbounded;
@@ -98,13 +97,13 @@
             final List<MethodAnnotation> methodTags = scannedClass.getMethodAnnotations(null);
             for (final MethodAnnotation m : methodTags) {
                 if (m.getName().equals(Activate.class.getName())) {
-                    cd.setActivate(new MethodDescription(m.getAnnotatedMethod()));
+                    cd.setActivate(m.getAnnotatedMethod().getName());
                     scannedClass.processed(m);
                 } else if (m.getName().equals(Deactivate.class.getName())) {
-                    cd.setDeactivate(new MethodDescription(m.getAnnotatedMethod()));
+                    cd.setDeactivate(m.getAnnotatedMethod().getName());
                     scannedClass.processed(m);
                 } else if (m.getName().equals(Modified.class.getName())) {
-                    cd.setModified(new MethodDescription(m.getAnnotatedMethod()));
+                    cd.setModified(m.getAnnotatedMethod().getName());
                     scannedClass.processed(m);
                 }
             }
@@ -273,20 +272,6 @@
     }
 
     /**
-     * Create a method description if a name is provided.
-     *
-     * @param methodName
-     *            The name of the method or <code>null</code>
-     * @return A method description if the name is not null.
-     */
-    private MethodDescription getMethodDescription(final String methodName) {
-        if (methodName != null) {
-            return new MethodDescription(methodName);
-        }
-        return null;
-    }
-
-    /**
      * Create reference descriptions
      *
      * @param descs
@@ -318,9 +303,9 @@
             ref.setPolicyOption(ReferencePolicyOption.valueOf(ad.getEnumValue("policyOption", ReferencePolicyOption.RELUCTANT.name())));
             ref.setStrategy(ReferenceStrategy.valueOf(ad.getEnumValue("strategy", ReferenceStrategy.EVENT.name())));
 
-            ref.setBind(getMethodDescription(ad.getStringValue("bind", null)));
-            ref.setUnbind(getMethodDescription(ad.getStringValue("unbind", null)));
-            ref.setUpdated(getMethodDescription(ad.getStringValue("updated", null)));
+            ref.setBind(ad.getStringValue("bind", null));
+            ref.setUnbind(ad.getStringValue("unbind", null));
+            ref.setUpdated(ad.getStringValue("updated", null));
 
             describedClass.add(ref);
         }
diff --git a/scrplugin/ds-annotations/src/main/java/org/apache/felix/scrplugin/ds/DSAnnotationProcessor.java b/scrplugin/ds-annotations/src/main/java/org/apache/felix/scrplugin/ds/DSAnnotationProcessor.java
index b67787a..0be35b2 100644
--- a/scrplugin/ds-annotations/src/main/java/org/apache/felix/scrplugin/ds/DSAnnotationProcessor.java
+++ b/scrplugin/ds-annotations/src/main/java/org/apache/felix/scrplugin/ds/DSAnnotationProcessor.java
@@ -33,7 +33,6 @@
 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.PropertyUnbounded;
@@ -88,13 +87,13 @@
             final List<MethodAnnotation> methodTags = scannedClass.getMethodAnnotations(null);
             for (final MethodAnnotation m : methodTags) {
                 if (m.getName().equals(Activate.class.getName())) {
-                    cd.setActivate(new MethodDescription(m.getAnnotatedMethod()));
+                    cd.setActivate(m.getAnnotatedMethod().getName());
                     scannedClass.processed(m);
                 } else if (m.getName().equals(Deactivate.class.getName())) {
-                    cd.setDeactivate(new MethodDescription(m.getAnnotatedMethod()));
+                    cd.setDeactivate(m.getAnnotatedMethod().getName());
                     scannedClass.processed(m);
                 } else if (m.getName().equals(Modified.class.getName())) {
-                    cd.setModified(new MethodDescription(m.getAnnotatedMethod()));
+                    cd.setModified(m.getAnnotatedMethod().getName());
                     scannedClass.processed(m);
                 } else if (m.getName().equals(Reference.class.getName()) ) {
                     this.processReference(describedClass, m);
@@ -196,7 +195,7 @@
             final SpecVersion spec = SpecVersion.fromNamespaceUrl(cad.getValue("xmlns").toString());
             if ( spec == null ) {
                 throw new SCRDescriptorException("Unknown xmlns attribute value: " + cad.getValue("xmlns"),
-                                describedClass.getSource(), -1);
+                                describedClass.getSource());
             }
             component.setSpecVersion(spec);
         }
@@ -253,18 +252,18 @@
         final String defaultUpdateMethodName = "updated" + refNameByMethod;
 
         // bind method
-        ref.setBind(new MethodDescription(ad.getAnnotatedMethod()));
+        ref.setBind(ad.getAnnotatedMethod().getName());
         // unbind method
         final String unbind = ad.getStringValue("unbind",
                         this.hasMethod(describedClass, defaultUnbindMethodName) ? defaultUnbindMethodName : "-");
         if ( !unbind.equals("-") ) {
-            ref.setUnbind(new MethodDescription(unbind));
+            ref.setUnbind(unbind);
         }
         // update method
-        final String update = ad.getStringValue("updated",
+        final String updated = ad.getStringValue("updated",
                         this.hasMethod(describedClass, defaultUpdateMethodName) ? defaultUpdateMethodName : "-");
-        if ( !update.equals("-") ) {
-            ref.setUpdated(new MethodDescription(update));
+        if ( !updated.equals("-") ) {
+            ref.setUpdated(updated);
         }
 
         // name
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
index 8599040..03acc1e 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Options.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/Options.java
@@ -28,20 +28,31 @@
  */
 public class Options {
 
+    /** Flag for generating accessor methods. */
     private boolean generateAccessors = true;
 
+    /** Flag for strict mode. */
     private boolean strictMode = false;
 
+    /** Map of global properties. */
     private Map<String, String> properties = Collections.emptyMap();
 
+    /** The requested spec version. */
     private SpecVersion specVersion;
 
+    /** The output directory for the generated files. */
     private File outputDirectory;
 
+    /** The name of the scr file. */
     private String scrName = "serviceComponents.xml";
 
+    /** The name of the metatype file. */
     private String metaTypeName = "metatype.xml";
 
+    /**
+     * @see #setGenerateAccessors(boolean)
+     * @return Whether accessor methods should be generated.
+     */
     public boolean isGenerateAccessors() {
         return generateAccessors;
     }
@@ -56,10 +67,14 @@
      * <p>
      * The default value of this property is <code>true</code>.
      */
-    public void setGenerateAccessors(boolean generateAccessors) {
+    public void setGenerateAccessors(final boolean generateAccessors) {
         this.generateAccessors = generateAccessors;
     }
 
+    /**
+     * @see #setStrictMode(boolean)
+     * @return Whether strict mode should be used or not.
+     */
     public boolean isStrictMode() {
         return strictMode;
     }
@@ -70,7 +85,7 @@
      * <p>
      * The default value of this property is <code>false</code>.
      */
-    public void setStrictMode(boolean strictMode) {
+    public void setStrictMode(final boolean strictMode) {
         this.strictMode = strictMode;
     }
 
@@ -89,6 +104,10 @@
         this.properties = properties;
     }
 
+    /**
+     * @see #setSpecVersion(SpecVersion)
+     * @return Return the requested spec version
+     */
     public SpecVersion getSpecVersion() {
         return specVersion;
     }
@@ -106,20 +125,37 @@
      * <code>configuration-policy</code>, are used, version 1.0 is used,
      * otherwise a 1.1 descriptor is generated.
      */
-    public void setSpecVersion(SpecVersion specVersion) {
+    public void setSpecVersion(final SpecVersion specVersion) {
         this.specVersion = specVersion;
     }
 
     /**
+     * @see #setOutputDirectory(File)
+     * @return The output directory for the generated files.
+     */
+    public File getOutputDirectory() {
+        return this.outputDirectory;
+    }
+
+    /**
      * 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
+     * before passing this object to {@link SCRDescriptorGenerator#setOptions(Options)}.
      */
     public void setOutputDirectory(final File outputDirectory) {
         this.outputDirectory = outputDirectory;
     }
 
     /**
+     * @see #setSCRName(String)
+     * @return The file name for the SCR file.
+     */
+    public String getSCRName() {
+        return this.scrName;
+    }
+
+    /**
      * 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}.
      * <p>
@@ -132,6 +168,14 @@
     }
 
     /**
+     * @see #setMetaTypeName(String)
+     * @return The name for the metatype file
+     */
+    public String getMetaTypeName() {
+        return this.metaTypeName;
+    }
+
+    /**
      * 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}
      * .
@@ -143,16 +187,4 @@
     public void setMetaTypeName(final String metaTypeName) {
         this.metaTypeName = metaTypeName;
     }
-
-    public File getOutputDirectory() {
-        return this.outputDirectory;
-    }
-
-    public String getMetaTypeName() {
-        return this.metaTypeName;
-    }
-
-    public String getSCRName() {
-        return this.scrName;
-    }
 }
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 fec894b..683e9c5 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
@@ -21,44 +21,29 @@
 
 public class SCRDescriptorException extends Exception {
 
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 2L;
 
     private final String m_sourceLocation;
 
-    private final int m_lineNumber;
-
-
-    public SCRDescriptorException( final String message, final String sourceLocation, final int lineNumber )
-    {
+    public SCRDescriptorException( final String message, final String sourceLocation ) {
         super( message );
         this.m_sourceLocation = sourceLocation;
-        this.m_lineNumber = lineNumber;
     }
 
 
-    public SCRDescriptorException( final String message, final Throwable cause )
-    {
-        this( message, null, -1, cause );
+    public SCRDescriptorException( final String message, final Throwable cause ) {
+        this( message, null, cause );
     }
 
 
-    public SCRDescriptorException( final String message, final String sourceLocation, final int lineNumber,
-        final Throwable cause )
-    {
+    public SCRDescriptorException( final String message, final String sourceLocation,
+        final Throwable cause ) {
         super( message, cause );
         this.m_sourceLocation = sourceLocation;
-        this.m_lineNumber = lineNumber;
     }
 
 
-    public String getSourceLocation()
-    {
+    public String getSourceLocation() {
         return m_sourceLocation;
     }
-
-
-    public int getLineNumber()
-    {
-        return m_lineNumber;
-    }
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorFailureException.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorFailureException.java
index 4b2ce6a..7bf2c90 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorFailureException.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorFailureException.java
@@ -19,20 +19,17 @@
 package org.apache.felix.scrplugin;
 
 
-public class SCRDescriptorFailureException extends Exception
-{
+public class SCRDescriptorFailureException extends Exception {
 
     private static final long serialVersionUID = 1L;
 
 
-    public SCRDescriptorFailureException( String message )
-    {
+    public SCRDescriptorFailureException( final String message ) {
         super( message );
     }
 
 
-    public SCRDescriptorFailureException( String message, Throwable cause )
-    {
+    public SCRDescriptorFailureException( final String message, final Throwable cause ) {
         super( message, 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 73e2c1a..33193d6 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
@@ -34,19 +34,16 @@
 import org.apache.felix.scrplugin.description.ReferenceCardinality;
 import org.apache.felix.scrplugin.description.ReferenceDescription;
 import org.apache.felix.scrplugin.description.ReferencePolicyOption;
+import org.apache.felix.scrplugin.description.ReferenceStrategy;
 import org.apache.felix.scrplugin.description.ServiceDescription;
-import org.apache.felix.scrplugin.description.Validator;
 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.ComponentContainer;
+import org.apache.felix.scrplugin.helper.DescriptionContainer;
 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.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.helper.Validator;
 import org.apache.felix.scrplugin.om.metatype.AttributeDefinition;
 import org.apache.felix.scrplugin.om.metatype.Designate;
 import org.apache.felix.scrplugin.om.metatype.MTObject;
@@ -150,7 +147,7 @@
         final MetaData metaData = new MetaData();
         metaData.setLocalization(MetaTypeService.METATYPE_DOCUMENTS_LOCATION + "/metatype");
 
-        final List<Component> processedComponents = new ArrayList<Component>();
+        final List<ComponentContainer> processedComponents = new ArrayList<ComponentContainer>();
         for (final ClassDescription desc : scannedDescriptions) {
             this.logger.debug("Processing component class " + desc.getSource());
 
@@ -161,15 +158,15 @@
                                 desc.getSource());
             } else {
                 try {
-                    final Component comp = this.createComponent(desc, metaData, iLog);
-                    if (comp.getSpecVersion() != null) {
+                    final ComponentContainer comp = this.createComponent(desc, metaData, iLog);
+                    if (comp.getComponentDescription().getSpecVersion() != null) {
                         if ( specVersion == null ) {
-                            specVersion = comp.getSpecVersion();
+                            specVersion = comp.getComponentDescription().getSpecVersion();
                             logger.debug("Setting used spec version to " + specVersion);
-                        } else if (comp.getSpecVersion().ordinal() > specVersion.ordinal() && this.options.getSpecVersion() != null) {
+                        } else if (comp.getComponentDescription().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!
-                            iLog.addError("Component " + comp + " requires spec version " + comp.getSpecVersion().name()
+                            iLog.addError("Component " + comp + " requires spec version " + comp.getComponentDescription().getSpecVersion().name()
                                             + " but plugin is configured to use version " + this.options.getSpecVersion(),
                                             desc.getSource());
                         }
@@ -186,42 +183,41 @@
             logger.debug("Using default spec version " + specVersion);
         }
         this.logger.debug("Generating descriptor for spec version: " + specVersion);
+        options.setSpecVersion(specVersion);
 
         // now check for abstract components and fill components objects
-        final Components components = new Components();
-        components.setSpecVersion(specVersion);
+        final DescriptionContainer module = new DescriptionContainer(this.options);
 
-        for (final Component comp : processedComponents) {
+        for (final ComponentContainer comp : processedComponents) {
             final int errorCount = iLog.getNumberOfErrors();
 
-            final Validator validator = new Validator(comp.getClassDescription(),
-                            comp, specVersion, project, options);
+            final Validator validator = new Validator(comp, project, options, iLog);
 
             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()) {
+                for (final ReferenceDescription ref : comp.getReferences().values()) {
                     // 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
+                    if (ref.getStrategy() != ReferenceStrategy.LOOKUP && 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();
+                        final String type = ref.getInterfaceName();
 
                         boolean createBind = false;
                         boolean createUnbind = false;
 
                         // Only create method if no bind name has been specified
-                        if (bindValue == null && validator.findMethod(iLog, ref, "bind") == null) {
+                        if (bindValue == null && validator.findMethod(ref, "bind") == null) {
                             // create bind method
                             createBind = true;
                         }
-                        if (unbindValue == null && validator.findMethod(iLog, ref, "unbind") == null) {
+                        if (unbindValue == null && validator.findMethod(ref, "unbind") == null) {
                             // create unbind method
                             createUnbind = true;
                         }
@@ -237,15 +233,15 @@
                     }
                 }
             }
-            validator.validate(iLog);
+            validator.validate();
 
             // ignore component if it has errors
             if (iLog.getNumberOfErrors() == errorCount) {
-                if (!comp.isDs()) {
+                if (!comp.getComponentDescription().isCreateDs()) {
                     logger.debug("Ignoring descriptor for DS : " + comp);
-                } else if (!comp.isAbstract()) {
+                } else if (!comp.getComponentDescription().isAbstract()) {
                     this.logger.debug("Adding descriptor for DS : " + comp);
-                    components.addComponent(comp);
+                    module.addComponent(comp);
                 }
             }
         }
@@ -284,7 +280,7 @@
         final File descriptorFile = StringUtils.isEmpty(this.options.getSCRName()) ? null : new File(this.options.getOutputDirectory(), descriptorPath);
 
         // terminate if there is nothing else to write
-        if (components.getComponents().isEmpty()) {
+        if (module.getComponents().isEmpty()) {
             this.logger.debug("No Service Component Descriptors found in project.");
             // remove file if it exists
             if (descriptorFile != null && descriptorFile.exists()) {
@@ -299,10 +295,10 @@
             // finally the descriptors have to be written ....
             descriptorFile.getParentFile().mkdirs(); // ensure parent dir
 
-            this.logger.info("Writing " + components.getComponents().size() + " Service Component Descriptors to "
+            this.logger.info("Writing " + module.getComponents().size() + " Service Component Descriptors to "
                             + descriptorFile);
 
-            ComponentDescriptorIO.write(components, descriptorFile);
+            ComponentDescriptorIO.write(module, descriptorFile);
             result.setScrFiles(Collections.singletonList(descriptorPath.replace(File.separatorChar, '/')));
         }
 
@@ -312,24 +308,15 @@
     /**
      * Create the SCR objects based on the descriptions
      */
-    private Component createComponent(final ClassDescription desc,
+    private ComponentContainer 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());
-
-        comp.setName(componentDesc.getName());
-        comp.setConfigurationPolicy(componentDesc.getConfigurationPolicy());
-        comp.setAbstract(componentDesc.isAbstract());
-        comp.setDs(componentDesc.isCreateDs());
-        comp.setFactory(componentDesc.getFactory());
-        comp.setSpecVersion(componentDesc.getSpecVersion());
 
         // configuration pid in 1.2
         if ( componentDesc.getConfigurationPid() != null && !componentDesc.getConfigurationPid().equals(componentDesc.getName())) {
-            comp.setConfigurationPid(componentDesc.getConfigurationPid());
-            comp.setSpecVersion(SpecVersion.VERSION_1_2);
+            componentDesc.setSpecVersion(SpecVersion.VERSION_1_2);
         }
 
         // Create metatype (if required)
@@ -372,8 +359,7 @@
             ocd = null;
         }
 
-        final Map<String, Reference> allReferences = new LinkedHashMap<String, Reference>();
-        final Map<String, Property> allProperties = new LinkedHashMap<String, Property>();
+        final ComponentContainer container = new ComponentContainer(desc, componentDesc);
 
         ClassDescription current = desc;
         boolean inherit;
@@ -383,33 +369,33 @@
 
             if ( cd != null ) {
                 // handle enabled and immediate
-                if ( comp.isEnabled() == null ) {
-                    comp.setEnabled(cd.getEnabled());
+                if ( componentDesc.getEnabled() == null ) {
+                    componentDesc.setEnabled(cd.getEnabled());
                 }
-                if ( comp.isImmediate() == null ) {
-                    comp.setImmediate(cd.getImmediate());
+                if ( componentDesc.getImmediate() == null ) {
+                    componentDesc.setImmediate(cd.getImmediate());
                 }
 
                 // lifecycle methods
-                if ( comp.getActivate() == null && cd.getActivate() != null ) {
-                    comp.setActivate(cd.getActivate().getName());
+                if ( componentDesc.getActivate() == null && cd.getActivate() != null ) {
+                    componentDesc.setActivate(cd.getActivate());
                 }
-                if ( comp.getDeactivate() == null && cd.getDeactivate() != null ) {
-                    comp.setDeactivate(cd.getDeactivate().getName());
+                if ( componentDesc.getDeactivate() == null && cd.getDeactivate() != null ) {
+                    componentDesc.setDeactivate(cd.getDeactivate());
                 }
-                if ( comp.getModified() == null && cd.getModified() != null ) {
-                    comp.setModified(cd.getModified().getName());
+                if ( componentDesc.getModified() == null && cd.getModified() != null ) {
+                    componentDesc.setModified(cd.getModified());
                 }
-                if ( comp.getActivate() != null || comp.getDeactivate() != null || comp.getModified() != null ) {
+                if ( componentDesc.getActivate() != null || componentDesc.getDeactivate() != null || componentDesc.getModified() != null ) {
                     // spec version must be at least 1.1
-                    comp.setSpecVersion(SpecVersion.VERSION_1_1);
+                    componentDesc.setSpecVersion(SpecVersion.VERSION_1_1);
                 }
             }
 
             // services, properties, references
-            this.processServices(current, comp);
-            this.processProperties(current, comp, ocd, allProperties);
-            this.processReferences(current, comp, allReferences);
+            this.processServices(current, container);
+            this.processProperties(current, container, ocd);
+            this.processReferences(current, container);
 
             // go up in the class hierarchy
             if ( !inherit || current.getDescribedClass().getSuperclass() == null ) {
@@ -420,40 +406,37 @@
         } 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");
+        if ( componentDesc.isCreatePid() && !container.getProperties().containsKey(org.osgi.framework.Constants.SERVICE_PID)) {
+            final PropertyDescription pid = new PropertyDescription(null);
             pid.setName( org.osgi.framework.Constants.SERVICE_PID );
-            pid.setValue( comp.getName() );
+            pid.setValue( componentDesc.getName() );
 
-            allProperties.put(org.osgi.framework.Constants.SERVICE_PID, pid);
-            comp.addProperty( pid );
+            container.getProperties().put(org.osgi.framework.Constants.SERVICE_PID, pid);
         }
-        this.processGlobalProperties(desc, comp, allProperties);
+        this.processGlobalProperties(desc, container.getProperties());
 
-        return comp;
+        return container;
     }
 
     /**
      * Process service directives
      */
-    private void processServices(final ClassDescription current, final Component component)
+    private void processServices(final ClassDescription current, final ComponentContainer component)
     throws SCRDescriptorException, SCRDescriptorFailureException {
 
         final ServiceDescription serviceDesc = current.getDescription(ServiceDescription.class);
         if ( serviceDesc != null ) {
-            Service service = component.getService();
+            ServiceDescription service = component.getServiceDescription();
             if ( service == null ) {
-                service = new Service();
+                service = new ServiceDescription(serviceDesc.getAnnotation());
                 service.setServiceFactory(false);
-                component.setService(service);
+                component.setServiceDescription(service);
             }
             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);
+                service.addInterface(className);
             }
         }
     }
@@ -463,26 +446,17 @@
      */
     private void processProperties(
                     final ClassDescription current,
-                    final Component component,
-                    final OCD ocd,
-                    final Map<String, Property> allProperties)
+                    final ComponentContainer component,
+                    final OCD ocd)
     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();
+                final String name = pd.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)
@@ -498,18 +472,18 @@
             if ( !isPrivate && ocd != null ) {
                 final AttributeDefinition ad = new AttributeDefinition();
                 ocd.getProperties().add(ad);
-                ad.setId(prop.getName());
-                ad.setType(prop.getType().name());
+                ad.setId(pd.getName());
+                ad.setType(pd.getType().name());
 
                 if (pd.getLabel() != null ) {
                     ad.setName(pd.getLabel());
                 } else {
-                    ad.setName("%" + prop.getName() + ".name");
+                    ad.setName("%" + pd.getName() + ".name");
                 }
                 if (pd.getDescription() != null ) {
                     ad.setDescription(pd.getDescription());
                 } else {
-                    ad.setDescription("%" + prop.getName() + ".description");
+                    ad.setDescription("%" + pd.getName() + ".description");
                 }
 
                 if ( pd.getUnbounded() == PropertyUnbounded.DEFAULT ) {
@@ -522,8 +496,8 @@
                     ad.setCardinality(new Integer(Integer.MIN_VALUE));
                 }
 
-                ad.setDefaultValue(prop.getValue());
-                ad.setDefaultMultiValue(prop.getMultiValue());
+                ad.setDefaultValue(pd.getValue());
+                ad.setDefaultMultiValue(pd.getMultiValue());
 
                 // check options
                 final String[] parameters = pd.getOptions();
@@ -540,9 +514,7 @@
                 }
 
             }
-            if ( this.testProperty(current, allProperties, prop, current == component.getClassDescription())) {
-                component.addProperty(prop);
-            }
+            this.testProperty(current, component.getProperties(), pd, current == component.getClassDescription());
         }
     }
 
@@ -550,8 +522,7 @@
      * Add global properties (if not already defined in the component)
      */
     private void processGlobalProperties(final ClassDescription desc,
-                    final Component component,
-                    final Map<String, Property> allProperties) {
+                    final Map<String, PropertyDescription> allProperties) {
         // apply pre configured global properties
         if ( this.options.getProperties() != null ) {
             for(final Map.Entry<String, String> entry : this.options.getProperties().entrySet()) {
@@ -560,12 +531,11 @@
                 // check if the service already provides this property
                 if ( value != null && !allProperties.containsKey(propName) ) {
 
-                    final Property p = new Property(null, "scr-generator");
+                    final PropertyDescription p = new PropertyDescription(null);
                     p.setName(propName);
                     p.setValue(value);
                     p.setType(PropertyType.String);
 
-                    component.addProperty(p);
                     allProperties.put(propName, p);
                 }
             }
@@ -575,9 +545,9 @@
     /**
      * Test a newly found property
      */
-    private boolean testProperty(final ClassDescription current,
-                    final Map<String, Property> allProperties,
-                    final Property newProperty,
+    private void testProperty(final ClassDescription current,
+                    final Map<String, PropertyDescription> allProperties,
+                    final PropertyDescription newProperty,
                     boolean isInspectedClass ) {
         final String propName = newProperty.getName();
 
@@ -591,63 +561,42 @@
                 }
             } 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)
+                    final ComponentContainer component)
     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());
-            ref.setPolicyOption(rd.getPolicyOption());
-            if ( ref.getPolicyOption() != ReferencePolicyOption.RELUCTANT ) {
-                component.setSpecVersion(SpecVersion.VERSION_1_2);
-            }
-            if ( rd.getBind() != null ) {
-                ref.setBind(rd.getBind().getName());
-            }
-            if ( rd.getUnbind() != null ) {
-                ref.setUnbind(rd.getUnbind().getName());
+            if ( rd.getPolicyOption() != ReferencePolicyOption.RELUCTANT ) {
+                component.getComponentDescription().setSpecVersion(SpecVersion.VERSION_1_2);
             }
             if ( rd.getUpdated() != null ) {
                 // updated requires 1.2 or 1.1_FELIX, if nothing is set, we use 1.2
-                if ( component.getSpecVersion() == null
-                     || component.getSpecVersion().ordinal() < SpecVersion.VERSION_1_1_FELIX.ordinal() ) {
-                    component.setSpecVersion(SpecVersion.VERSION_1_2);
+                if ( component.getComponentDescription().getSpecVersion() == null
+                     || component.getComponentDescription().getSpecVersion().ordinal() < SpecVersion.VERSION_1_1_FELIX.ordinal() ) {
+                    component.getComponentDescription().setSpecVersion(SpecVersion.VERSION_1_2);
                 }
-                ref.setUpdated(rd.getUpdated().getName());
             }
 
-            if ( this.testReference(current, allReferences, ref, component.getClassDescription() == current) ) {
-                component.addReference(ref);
-            }
+            this.testReference(current, component.getReferences(), rd, component.getClassDescription() == current);
         }
     }
 
     /**
      * Test a newly found reference
      */
-    private boolean testReference(final ClassDescription current,
-                    final Map<String, Reference> allReferences,
-                    final Reference newReference,
+    private void testReference(final ClassDescription current,
+                    final Map<String, ReferenceDescription> allReferences,
+                    final ReferenceDescription newReference,
                     boolean isInspectedClass ) {
         String refName = newReference.getName();
         if ( refName == null) {
-            refName = newReference.getInterfacename();
+            refName = newReference.getInterfaceName();
         }
 
         if ( refName != null ) {
@@ -660,9 +609,7 @@
                 }
             } else {
                 allReferences.put(refName, newReference);
-                return true;
             }
         }
-        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
index b275ff9..1d10c0c 100644
--- 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
@@ -34,12 +34,22 @@
     /** The corresponding annotation from the class file. */
     protected final ScannedAnnotation annotation;
 
+    private final String annotationPrefix;
+
+    private String sourceLocation;
+
     /**
      * Create a new abstract description
      * @param annotation The corresponding annotation.
      */
     public AbstractDescription(final ScannedAnnotation annotation) {
         this.annotation = annotation;
+        if ( annotation == null ) {
+            this.annotationPrefix = "";
+        } else {
+            this.annotationPrefix = "@" + annotation.getSimpleName();
+        }
+        this.sourceLocation = "<unknown>";
     }
 
     /**
@@ -49,4 +59,16 @@
     public ScannedAnnotation getAnnotation() {
         return this.annotation;
     }
+
+    public void setSource(final String location) {
+        this.sourceLocation = location;
+    }
+
+    public String getSource() {
+        return this.sourceLocation;
+    }
+
+    public String getIdentifier() {
+        return this.annotationPrefix;
+    }
 }
\ 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
index 2d1f70f..a8b8a53 100644
--- 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
@@ -73,6 +73,7 @@
      */
     public void add(final AbstractDescription desc) {
         this.descriptions.add(desc);
+        desc.setSource(this.source);
     }
 
     /**
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
index e42cb56..11c1bfa 100644
--- 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
@@ -94,13 +94,13 @@
     private boolean isSetMetatypeFactoryPid = false;
 
     /** Activation method. (V1.1) */
-    private MethodDescription activate;
+    private String activate;
 
     /** Deactivation method. (V1.1) */
-    private MethodDescription deactivate;
+    private String deactivate;
 
     /** Modified method. (V1.1) */
-    private MethodDescription modified;
+    private String modified;
 
     /** The spec version. */
     private SpecVersion specVersion;
@@ -216,27 +216,27 @@
         this.configurationPolicy = configurationPolicy;
     }
 
-    public MethodDescription getActivate() {
+    public String getActivate() {
         return activate;
     }
 
-    public void setActivate(MethodDescription activate) {
+    public void setActivate(String activate) {
         this.activate = activate;
     }
 
-    public MethodDescription getDeactivate() {
+    public String getDeactivate() {
         return deactivate;
     }
 
-    public void setDeactivate(MethodDescription deactivate) {
+    public void setDeactivate(String deactivate) {
         this.deactivate = deactivate;
     }
 
-    public MethodDescription getModified() {
+    public String getModified() {
         return modified;
     }
 
-    public void setModified(MethodDescription modified) {
+    public void setModified(String modified) {
         this.modified = modified;
     }
 
@@ -244,8 +244,10 @@
         return specVersion;
     }
 
-    public void setSpecVersion(SpecVersion specVersion) {
-        this.specVersion = specVersion;
+    public void setSpecVersion(final SpecVersion specVersion) {
+        if ( this.specVersion == null || this.specVersion.ordinal() < specVersion.ordinal() ) {
+            this.specVersion = specVersion;
+        }
     }
 
     @Override
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
deleted file mode 100644
index fbffba8..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/MethodDescription.java
+++ /dev/null
@@ -1,55 +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.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/ReferenceDescription.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/ReferenceDescription.java
index 57fb7d8..3ec48ff 100644
--- 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
@@ -58,9 +58,9 @@
 
     private Field field;
 
-    private MethodDescription bind;
-    private MethodDescription unbind;
-    private MethodDescription updated;
+    private String bind;
+    private String unbind;
+    private String updated;
 
     public ReferenceDescription(final ScannedAnnotation annotation) {
         super(annotation);
@@ -114,27 +114,27 @@
         this.policyOption = policyOption;
     }
 
-    public MethodDescription getBind() {
+    public String getBind() {
         return bind;
     }
 
-    public void setBind(MethodDescription bind) {
+    public void setBind(String bind) {
         this.bind = bind;
     }
 
-    public MethodDescription getUnbind() {
+    public String getUnbind() {
         return unbind;
     }
 
-    public void setUnbind(MethodDescription unbind) {
+    public void setUnbind(String unbind) {
         this.unbind = unbind;
     }
 
-    public MethodDescription getUpdated() {
+    public String getUpdated() {
         return updated;
     }
 
-    public void setUpdated(MethodDescription updated) {
+    public void setUpdated(String updated) {
         this.updated = updated;
     }
 
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
index 21d0576..bf3c9f2 100644
--- 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
@@ -18,7 +18,7 @@
  */
 package org.apache.felix.scrplugin.description;
 
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Set;
 
 import org.apache.felix.scrplugin.annotations.ScannedAnnotation;
@@ -36,7 +36,7 @@
     private boolean isServiceFactory = false;
 
     /** The list of implemented interfaces. */
-    protected final Set<String> interfaces = new HashSet<String>();
+    protected final Set<String> interfaces = new LinkedHashSet<String>();
 
     public ServiceDescription(final ScannedAnnotation annotation) {
         super(annotation);
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
index 1ebdbed..fb8ba92 100644
--- 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
@@ -123,29 +123,4 @@
             this.processors.put(key, processor);
         }
     }
-
-    private void loadProcessor( final ClassLoader classLoader, final String className )
-    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 exception
-        if ( failureMessage != null  ) {
-            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
index aedb87c..28df6d9 100644
--- 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
@@ -70,7 +70,7 @@
             fos.write(writer.toByteArray());
             fos.close();
         } catch (final Exception e) {
-            throw new SCRDescriptorException("Unable to add methods to " + className, typeName, 0, e);
+            throw new SCRDescriptorException("Unable to add methods to " + className, typeName, e);
         }
     }
 
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
index 50f21f8..ff9c5cd 100644
--- 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
@@ -240,7 +240,7 @@
                         }
                         if (found == null) {
                             throw new SCRDescriptorException("Annotated method " + name + " not found.",
-                                            annotatedClass.getName(), -1);
+                                            annotatedClass.getName());
                         }
                         for (final AnnotationNode annotation : annos) {
                             parseAnnotation(descriptions, annotation, found);
@@ -267,7 +267,7 @@
                         }
                         if (found == null) {
                             throw new SCRDescriptorException("Annotated field " + name + " not found.",
-                                            annotatedClass.getName(), -1);
+                                            annotatedClass.getName());
                         }
                         for (final AnnotationNode annotation : annos) {
                             parseAnnotation(descriptions, annotation, found);
@@ -414,7 +414,7 @@
                         }
                         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,
+                        throw new SCRDescriptorException( "Unable to get scrinfo from artifact", artifact.toString(),
                             ioe );
                     } finally {
                         if ( scrInfoFile != null ) {
@@ -448,7 +448,7 @@
                         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,
+                    throw new SCRDescriptorException( "Unable to get manifest from artifact", artifact.toString(),
                         ioe );
                 }
 
@@ -485,8 +485,7 @@
         try {
             xml = this.getFile( artifactFile, entry );
             if ( xml == null ) {
-                throw new SCRDescriptorException( "Entry " + entry + " not contained in JAR File ", artifactFile.toString(),
-                    0 );
+                throw new SCRDescriptorException( "Entry " + entry + " not contained in JAR File ", artifactFile.toString());
             }
             return this.parseServiceComponentDescriptor( xml, artifactFile.toString() + ':' + entry );
         } catch ( final IOException mee ) {
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ComponentContainer.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ComponentContainer.java
new file mode 100644
index 0000000..e57a5d0
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ComponentContainer.java
@@ -0,0 +1,81 @@
+/*
+ * 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.LinkedHashMap;
+import java.util.Map;
+
+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.ReferenceDescription;
+import org.apache.felix.scrplugin.description.ServiceDescription;
+
+
+/**
+ * A <code>ComponentContainer</code> contains all relevant information
+ * about a component:
+ * - the class descriptor
+ * - the component descriptor
+ * - the service descriptor
+ * - reference descriptors
+ * - property descriptors
+ *
+ */
+public class ComponentContainer {
+
+    private final ClassDescription classDescription;
+
+    private final ComponentDescription componentDescription;
+
+    private ServiceDescription serviceDescription;
+
+    private final Map<String, ReferenceDescription> allReferences = new LinkedHashMap<String, ReferenceDescription>();
+    private final Map<String, PropertyDescription> allProperties = new LinkedHashMap<String, PropertyDescription>();
+
+    public ComponentContainer(final ClassDescription classDescription,
+                    final ComponentDescription componentDescription) {
+        this.classDescription = classDescription;
+        this.componentDescription = componentDescription;
+    }
+
+    public ClassDescription getClassDescription() {
+        return this.classDescription;
+    }
+
+    public ComponentDescription getComponentDescription() {
+        return this.componentDescription;
+    }
+
+    public Map<String, ReferenceDescription> getReferences() {
+        return this.allReferences;
+    }
+
+    public Map<String, PropertyDescription> getProperties() {
+        return this.allProperties;
+    }
+
+    public ServiceDescription getServiceDescription() {
+        return serviceDescription;
+    }
+
+    public void setServiceDescription(ServiceDescription serviceDescription) {
+        this.serviceDescription = serviceDescription;
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/DescriptionContainer.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/DescriptionContainer.java
new file mode 100644
index 0000000..cbd2dec
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/DescriptionContainer.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.helper;
+
+import java.awt.Component;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.scrplugin.Options;
+import org.apache.felix.scrplugin.description.ComponentDescription;
+
+/**
+ * <code>DescriptionContainer</code>...
+ *
+ * A description container is a collection of {@link ComponentDescription}s.
+ */
+public class DescriptionContainer {
+
+    /** The options. */
+    private final Options options;
+
+    /** The list of {@link Component}s. */
+    private final List<ComponentContainer> components = new ArrayList<ComponentContainer>();
+
+    public DescriptionContainer(final Options options) {
+        this.options = options;
+    }
+
+    public Options getOptions() {
+        return this.options;
+    }
+
+    /**
+     * Return the list of {@link Component}s.
+     */
+    public List<ComponentContainer> getComponents() {
+        return this.components;
+    }
+
+    /**
+     * Add a component to the list.
+     */
+    public void addComponent(ComponentContainer component) {
+        this.components.add(component);
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/Validator.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/Validator.java
similarity index 64%
rename from scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/Validator.java
rename to scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/Validator.java
index 6ee2c2c..374453c 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/Validator.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/Validator.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.scrplugin.description;
+package org.apache.felix.scrplugin.helper;
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
@@ -27,93 +27,102 @@
 import org.apache.felix.scrplugin.Project;
 import org.apache.felix.scrplugin.SCRDescriptorException;
 import org.apache.felix.scrplugin.SpecVersion;
-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.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.description.AbstractDescription;
+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.ReferenceCardinality;
+import org.apache.felix.scrplugin.description.ReferenceDescription;
+import org.apache.felix.scrplugin.description.ReferencePolicy;
+import org.apache.felix.scrplugin.description.ReferencePolicyOption;
+import org.apache.felix.scrplugin.description.ReferenceStrategy;
+import org.apache.felix.scrplugin.description.ServiceDescription;
 
 public class Validator {
 
-    private final ClassDescription classDescription;
-
-    private final Component component;
-
-    private final SpecVersion specVersion;
+    private final ComponentContainer container;
 
     private final Options options;
 
     private final Project project;
 
-    public Validator(final ClassDescription cd,
-                    final Component component,
-                    final SpecVersion specVersion,
+    private final IssueLog iLog;
+
+    public Validator(final ComponentContainer container,
                     final Project project,
-                    final Options options) {
-        this.classDescription = cd;
+                    final Options options,
+                    final IssueLog iLog) {
+        this.container = container;
         this.project = project;
-        this.specVersion = specVersion;
-        this.component = component;
         this.options = options;
+        this.iLog = iLog;
+    }
+
+    private void logWarn(final AbstractDescription desc, final String message) {
+        iLog.addWarning(desc.getIdentifier() + " : " + message, desc.getSource());
+    }
+
+    private void logError(final AbstractDescription desc, final String message) {
+        iLog.addError(desc.getIdentifier() + " : " + message, desc.getSource());
     }
 
     /**
      * 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 IssueLog iLog)
+    public void validate()
     throws SCRDescriptorException {
+        final ComponentDescription component = this.container.getComponentDescription();
+
         // nothing to check if this is ignored
-        if (!component.isDs()) {
+        if (!component.isCreateDs()) {
             return;
         }
 
         final int currentIssueCount = iLog.getNumberOfErrors();
 
         // if the component is abstract, we do not validate everything
-        if (!this.component.isAbstract()) {
+        if (!component.isAbstract()) {
             // if configuration pid is set and different from name, we need 1.2
-            if ( this.component.getConfigurationPid() != null && !this.component.getConfigurationPid().equals(this.component.getName())
-                 && this.specVersion.ordinal() < SpecVersion.VERSION_1_2.ordinal() ) {
-                this.component.logError(iLog, "Different configuration pid requires "
+            if ( component.getConfigurationPid() != null && !component.getConfigurationPid().equals(component.getName())
+                 && options.getSpecVersion().ordinal() < SpecVersion.VERSION_1_2.ordinal() ) {
+                this.logError(component, "Different configuration pid requires "
                                 + SpecVersion.VERSION_1_2.getName() + " or higher.");
             }
 
             // ensure non-abstract, public class
-            if (!Modifier.isPublic(this.classDescription.getDescribedClass().getModifiers())) {
-                this.component.logError(iLog, "Class must be public: "
-                                + this.classDescription.getDescribedClass().getName());
+            if (!Modifier.isPublic(this.container.getClassDescription().getDescribedClass().getModifiers())) {
+                this.logError(component, "Class must be public: "
+                                + this.container.getClassDescription().getDescribedClass().getName());
             }
-            if (Modifier.isAbstract(this.classDescription.getDescribedClass().getModifiers())
-                            || this.classDescription.getDescribedClass().isInterface()) {
-                this.component.logError(iLog, "Class must be concrete class (not abstract or interface) : "
-                                + this.classDescription.getDescribedClass().getName());
+            if (Modifier.isAbstract(this.container.getClassDescription().getDescribedClass().getModifiers())
+                            || this.container.getClassDescription().getDescribedClass().isInterface()) {
+                this.logError(component, "Class must be concrete class (not abstract or interface) : "
+                                + this.container.getClassDescription().getDescribedClass().getName());
             }
 
             // no errors so far, let's continue
             if (iLog.getNumberOfErrors() == currentIssueCount) {
 
-                final String activateName = this.component.getActivate() == null ? "activate" : this.component.getActivate();
-                final String deactivateName = this.component.getDeactivate() == null ? "deactivate" : this.component.getDeactivate();
+                final String activateName = component.getActivate() == null ? "activate" : component.getActivate();
+                final String deactivateName = component.getDeactivate() == null ? "deactivate" : component.getDeactivate();
 
                 // check activate and deactivate methods
-                this.checkLifecycleMethod(iLog, activateName, true);
-                this.checkLifecycleMethod(iLog, deactivateName, false);
+                this.checkLifecycleMethod(activateName, true);
+                this.checkLifecycleMethod(deactivateName, false);
 
-                if (this.component.getModified() != null) {
-                    if ( this.specVersion.ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
-                        this.checkLifecycleMethod(iLog, this.component.getModified(), true);
+                if (component.getModified() != null) {
+                    if ( this.options.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
+                        this.checkLifecycleMethod(component.getModified(), true);
                     } else {
-                        this.component.logError(iLog, "If modified version is specified, spec version must be " +
-                            SpecVersion.VERSION_1_1.name() + " or higher : " + this.component.getModified());
+                        this.logError(component, "If modified version is specified, spec version must be " +
+                            SpecVersion.VERSION_1_1.name() + " or higher : " + component.getModified());
                     }
                 }
 
                 // ensure public default constructor
                 boolean constructorFound = true;
-                Constructor<?>[] constructors = this.classDescription.getDescribedClass().getDeclaredConstructors();
+                Constructor<?>[] constructors = this.container.getClassDescription().getDescribedClass().getDeclaredConstructors();
                 for (int i = 0; constructors != null && i < constructors.length; i++) {
                     // if public default, succeed
                     if (Modifier.isPublic(constructors[i].getModifiers())
@@ -128,43 +137,43 @@
                 }
 
                 if (!constructorFound) {
-                    this.component.logError(iLog, "Class must have public default constructor: " + this.classDescription.getDescribedClass().getName());
+                    this.logError(component, "Class must have public default constructor: " + this.container.getClassDescription().getDescribedClass().getName());
                 }
 
                 // verify properties
-                for (final Property prop : this.component.getProperties()) {
-                    this.validateProperty(iLog, prop);
+                for (final PropertyDescription prop : this.container.getProperties().values()) {
+                    this.validateProperty(prop);
                 }
 
                 // verify service
                 boolean isServiceFactory = false;
-                if (this.component.getService() != null) {
-                    if (this.component.getService().getInterfaces().size() == 0) {
-                        this.component.logError(iLog, "Service interface information is missing!");
+                if (this.container.getServiceDescription() != null) {
+                    if (this.container.getServiceDescription().getInterfaces().size() == 0) {
+                        this.logError(component, "Service interface information is missing!");
                     }
-                    this.validateService(iLog, component.getService());
-                    isServiceFactory = this.component.getService().isServiceFactory();
+                    this.validateService(this.container.getServiceDescription());
+                    isServiceFactory = this.container.getServiceDescription().isServiceFactory();
                 }
 
                 // serviceFactory must not be true for immediate of component factory
-                if (isServiceFactory && this.component.isImmediate() != null && this.component.isImmediate().booleanValue()
-                    && this.component.getFactory() != null) {
-                    this.component.logError(iLog,
+                if (isServiceFactory && component.getImmediate() != null && component.getImmediate().booleanValue()
+                    && component.getFactory() != null) {
+                    this.logError(component,
                         "Component must not be a ServiceFactory, if immediate and/or component factory: "
-                        + this.classDescription.getDescribedClass().getName());
+                        + this.container.getClassDescription().getDescribedClass().getName());
                 }
 
                 // immediate must not be true for component factory
-                if (this.component.isImmediate() != null && this.component.isImmediate().booleanValue() && this.component.getFactory() != null) {
-                    this.component.logError(iLog,
-                        "Component must not be immediate if component factory: " + this.classDescription.getDescribedClass().getName());
+                if (component.getImmediate() != null && component.getImmediate().booleanValue() && component.getFactory() != null) {
+                    this.logError(component,
+                        "Component must not be immediate if component factory: " + this.container.getClassDescription().getDescribedClass().getName());
                 }
             }
         }
         if (iLog.getNumberOfErrors() == currentIssueCount) {
             // verify references
-            for (final Reference ref : this.component.getReferences()) {
-                this.validateReference(iLog, ref, this.component.isAbstract());
+            for (final ReferenceDescription ref : this.container.getReferences().values()) {
+                this.validateReference(ref, component.isAbstract());
             }
         }
     }
@@ -192,7 +201,7 @@
             }
         }
         try {
-            return this.classDescription.getDescribedClass().getDeclaredMethod(name, classSig);
+            return this.container.getClassDescription().getDescribedClass().getDeclaredMethod(name, classSig);
         } catch (final SecurityException e) {
             // ignore
         } catch (final NoSuchMethodException e) {
@@ -213,14 +222,13 @@
      * @param warnings
      *            The list of warnings used to add new warnings.
      */
-    private void checkLifecycleMethod(final IssueLog iLog,
-                                      final String methodName,
+    private void checkLifecycleMethod(final String methodName,
                                       final boolean isActivate)
     throws SCRDescriptorException {
         // first candidate is (de)activate(ComponentContext)
         Method method = this.getMethod(methodName, new String[] { TYPE_COMPONENT_CONTEXT });
         if (method == null) {
-            if (this.specVersion.ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
+            if (this.options.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
                 // second candidate is (de)activate(BundleContext)
                 method = this.getMethod(methodName, new String[] { TYPE_BUNDLE_CONTEXT });
                 if (method == null) {
@@ -249,7 +257,7 @@
                         // we already store this option
                         Method zeroArgMethod = null;
                         Method found = method;
-                        final Method[] methods = this.classDescription.getDescribedClass().getDeclaredMethods();
+                        final Method[] methods = this.container.getClassDescription().getDescribedClass().getDeclaredMethods();
                         int i = 0;
                         while (i < methods.length) {
                             if (methodName.equals(methods[i].getName())) {
@@ -274,7 +282,7 @@
                                             found = methods[i];
                                         } else {
                                             // print warning
-                                            this.component.logWarn(iLog, "Lifecycle method " + methods[i].getName()
+                                            this.logWarn(this.container.getComponentDescription(), "Lifecycle method " + methods[i].getName()
                                                       + " occurs several times with different matching signature.");
                                         }
                                     }
@@ -293,13 +301,13 @@
         }
         // if no method is found, we check for any method with that name to print some warnings!
         if (method == null) {
-           final Method[] methods = this.classDescription.getDescribedClass().getDeclaredMethods();
+           final Method[] methods = this.container.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.component.logWarn(iLog, "Lifecycle method " + methods[i].getName() + " has wrong number of arguments");
+                        this.logWarn(container.getComponentDescription(), "Lifecycle method " + methods[i].getName() + " has wrong number of arguments");
                     } else {
-                        this.component.logWarn(iLog,
+                        this.logWarn(container.getComponentDescription(),
                             "Lifecycle method " + methods[i].getName() + " has wrong argument "
                             + methods[i].getParameterTypes()[0].getName());
                     }
@@ -308,46 +316,36 @@
         }
 
         // method must be protected for version 1.0
-        if (method != null && specVersion == SpecVersion.VERSION_1_0) {
+        if (method != null && options.getSpecVersion() == SpecVersion.VERSION_1_0) {
             // check protected
             if (Modifier.isPublic(method.getModifiers())) {
-                this.component.logWarn(iLog, "Lifecycle method " + method.getName() + " should be declared protected");
+                this.logWarn(container.getComponentDescription(), "Lifecycle method " + method.getName() + " should be declared protected");
             } else if (!Modifier.isProtected(method.getModifiers())) {
-                this.component.logWarn(iLog, "Lifecycle method " + method.getName() +
+                this.logWarn(container.getComponentDescription(), "Lifecycle method " + method.getName() +
                             " has wrong qualifier, public or protected required");
             }
         }
     }
 
     /**
-     * Validate the service.
+     * Validate the service and its interfaces
      * If errors occur a message is added to the issues list,
      * warnings can be added to the warnings list.
      */
-    private void validateService(final IssueLog iLog, final Service service) throws SCRDescriptorException {
-        for (final Interface interf : service.getInterfaces()) {
-            this.validateInterface(iLog, interf);
-        }
-    }
-
-    /**
-     * Validate the interface.
-     * If errors occur a message is added to the issues list,
-     * warnings can be added to the warnings list.
-     */
-    private void validateInterface(final IssueLog iLog, final Interface iFace)
-    throws SCRDescriptorException {
-        if (this.classDescription.getDescribedClass().isInterface()) {
-            iFace.logError(iLog, "Must be declared in a Java class - not an interface");
-        } else {
-            try {
-                final Class<?> interfaceClass = project.getClassLoader().loadClass(iFace.getInterfaceName());
-                if (!interfaceClass.isAssignableFrom(this.classDescription.getDescribedClass())) {
-                    // interface not implemented
-                    iFace.logError(iLog, "Class must implement provided interface " + iFace.getInterfaceName());
+    private void validateService(final ServiceDescription service) throws SCRDescriptorException {
+        for (final String interfaceName : service.getInterfaces()) {
+            if (this.container.getClassDescription().getDescribedClass().isInterface()) {
+                this.logError(service, "Must be declared in a Java class - not an interface");
+            } else {
+                try {
+                    final Class<?> interfaceClass = project.getClassLoader().loadClass(interfaceName);
+                    if (!interfaceClass.isAssignableFrom(this.container.getClassDescription().getDescribedClass())) {
+                        // interface not implemented
+                        this.logError(service, "Class must implement provided interface " + interfaceName);
+                    }
+                } catch (final ClassNotFoundException cnfe) {
+                    throw new SCRDescriptorException("Unable to load interface class.", cnfe);
                 }
-            } catch (final ClassNotFoundException cnfe) {
-                throw new SCRDescriptorException("Unable to load interface class.", cnfe);
             }
         }
     }
@@ -357,16 +355,16 @@
      * If errors occur a message is added to the issues list,
      * warnings can be added to the warnings list.
      */
-    private void validateProperty(final IssueLog iLog, final Property property) {
+    private void validateProperty(final PropertyDescription property) {
         if (property.getName() == null || property.getName().trim().length() == 0) {
-            property.logError(iLog, "Property name can not be empty.");
+            this.logError(property, "Property name can not be empty.");
         }
         if (property.getType() != null) {
             // now check for old and new char
-            if (this.specVersion == SpecVersion.VERSION_1_0 && property.getType() == PropertyType.Character) {
+            if (this.options.getSpecVersion() == SpecVersion.VERSION_1_0 && property.getType() == PropertyType.Character) {
                 property.setType(PropertyType.Char);
             }
-            if (this.specVersion.ordinal() >= SpecVersion.VERSION_1_1.ordinal()
+            if (this.options.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal()
                             && property.getType() == PropertyType.Char) {
                 property.setType(PropertyType.Character);
             }
@@ -379,25 +377,25 @@
      * If errors occur a message is added to the issues list,
      * warnings can be added to the warnings list.
      */
-    private void validateReference(final IssueLog iLog, final Reference ref, final boolean componentIsAbstract)
+    private void validateReference(final ReferenceDescription ref, final boolean componentIsAbstract)
     throws SCRDescriptorException {
         final int currentIssueCount = iLog.getNumberOfErrors();
 
         // validate name
         if (StringUtils.isEmpty(ref.getName())) {
-            if (this.specVersion.ordinal() < SpecVersion.VERSION_1_1.ordinal() ) {
-                ref.logError(iLog, "Reference has no name");
+            if (this.options.getSpecVersion().ordinal() < SpecVersion.VERSION_1_1.ordinal() ) {
+                this.logError(ref, "Reference has no name");
             }
         }
 
         // validate interface
-        if (StringUtils.isEmpty(ref.getInterfacename())) {
-            ref.logError(iLog, "Missing interface name");
+        if (StringUtils.isEmpty(ref.getInterfaceName())) {
+            this.logError(ref, "Missing interface name");
         }
         try {
-            this.project.getClassLoader().loadClass(ref.getInterfacename());
+            this.project.getClassLoader().loadClass(ref.getInterfaceName());
         } catch (final ClassNotFoundException e) {
-            ref.logError(iLog, "Interface class can't be loaded: " + ref.getInterfacename());
+            this.logError(ref, "Interface class can't be loaded: " + ref.getInterfaceName());
         }
 
         // validate cardinality
@@ -415,8 +413,8 @@
             ref.setPolicyOption(ReferencePolicyOption.RELUCTANT);
         }
         if ( ref.getPolicyOption() != ReferencePolicyOption.RELUCTANT ) {
-            if ( this.specVersion.ordinal() < SpecVersion.VERSION_1_2.ordinal() ) {
-                ref.logError(iLog, "ReferencePolicyOption " + ref.getPolicyOption().name() +
+            if ( this.options.getSpecVersion().ordinal() < SpecVersion.VERSION_1_2.ordinal() ) {
+                this.logError(ref, "ReferencePolicyOption " + ref.getPolicyOption().name() +
                                 " requires spec version " + SpecVersion.VERSION_1_2.getName() + " or higher.");
             }
         }
@@ -426,12 +424,12 @@
         }
 
         // validate bind and unbind methods
-        if (!ref.isLookupStrategy()) {
+        if (ref.getStrategy() != ReferenceStrategy.LOOKUP) {
             String bindName = ref.getBind();
             String unbindName = ref.getUnbind();
 
             final boolean canGenerate = this.options.isGenerateAccessors() &&
-                            !ref.isLookupStrategy() && ref.getField() != null
+                            ref.getField() != null
                             && (ref.getCardinality() == ReferenceCardinality.OPTIONAL_UNARY || ref.getCardinality() == ReferenceCardinality.MANDATORY_UNARY);
             if (bindName == null && !canGenerate ) {
                 bindName = "bind";
@@ -441,12 +439,12 @@
             }
 
             if ( bindName != null ) {
-                bindName = this.validateMethod(iLog, ref, bindName, componentIsAbstract);
+                bindName = this.validateMethod(ref, bindName, componentIsAbstract);
             } else {
                 bindName = "bind" + Character.toUpperCase(ref.getName().charAt(0)) + ref.getName().substring(1);
             }
             if ( unbindName != null ) {
-                unbindName = this.validateMethod(iLog, ref, unbindName, componentIsAbstract);
+                unbindName = this.validateMethod(ref, unbindName, componentIsAbstract);
             } else {
                 unbindName = "unbind" + Character.toUpperCase(ref.getName().charAt(0)) + ref.getName().substring(1);
             }
@@ -462,20 +460,20 @@
 
         // validate updated method
         if (ref.getUpdated() != null) {
-            if (this.specVersion.ordinal() < SpecVersion.VERSION_1_1_FELIX.ordinal()) {
-                ref.logError(iLog, "Updated method declaration requires version "
+            if (this.options.getSpecVersion().ordinal() < SpecVersion.VERSION_1_1_FELIX.ordinal()) {
+                this.logError(ref, "Updated method declaration requires version "
                                 + SpecVersion.VERSION_1_1_FELIX.getName() + ", " + SpecVersion.VERSION_1_2.getName() + " or newer");
             }
         }
 
     }
 
-    private String validateMethod(final IssueLog iLog, final Reference ref, final String methodName, final boolean componentIsAbstract)
+    private String validateMethod(final ReferenceDescription ref, final String methodName, final boolean componentIsAbstract)
     throws SCRDescriptorException {
-        final Method method = this.findMethod(iLog, ref, methodName);
+        final Method method = this.findMethod(ref, methodName);
         if (method == null) {
             if (!componentIsAbstract) {
-                ref.logError(iLog,
+                this.logError(ref,
                                 "Missing method " + methodName + " for reference "
                                                 + (ref.getName() == null ? "" : ref.getName()));
             }
@@ -483,11 +481,11 @@
         }
 
         // method needs to be protected for 1.0
-        if (this.specVersion == SpecVersion.VERSION_1_0) {
+        if (this.options.getSpecVersion() == SpecVersion.VERSION_1_0) {
             if (Modifier.isPublic(method.getModifiers())) {
-                ref.logWarn(iLog, "Method " + method.getName() + " should be declared protected");
+                this.logWarn(ref, "Method " + method.getName() + " should be declared protected");
             } else if (!Modifier.isProtected(method.getModifiers())) {
-                ref.logError(iLog, "Method " + method.getName() + " has wrong qualifier, public or protected required");
+                this.logError(ref, "Method " + method.getName() + " has wrong qualifier, public or protected required");
                 return null;
             }
         }
@@ -498,7 +496,7 @@
 
     private Method getMethod(final String name, final Class<?>[] sig) {
         try {
-            return this.classDescription.getDescribedClass().getDeclaredMethod(name, sig);
+            return this.container.getClassDescription().getDescribedClass().getDeclaredMethod(name, sig);
         } catch (final SecurityException e) {
             // ignore
         } catch (final NoSuchMethodException e) {
@@ -507,19 +505,19 @@
         return null;
     }
 
-    public Method findMethod(final IssueLog iLog, final Reference ref, final String methodName)
+    public Method findMethod(final ReferenceDescription ref, final String methodName)
     throws SCRDescriptorException {
         try {
             final Class<?>[] sig = new Class<?>[] { this.project.getClassLoader().loadClass(TYPE_SERVICE_REFERENCE) };
-            final Class<?>[] sig2 = new Class<?>[] { this.project.getClassLoader().loadClass(ref.getInterfacename()) };
-            final Class<?>[] sig3 = new Class<?>[] { this.project.getClassLoader().loadClass(ref.getInterfacename()), Map.class };
+            final Class<?>[] sig2 = new Class<?>[] { this.project.getClassLoader().loadClass(ref.getInterfaceName()) };
+            final Class<?>[] sig3 = new Class<?>[] { this.project.getClassLoader().loadClass(ref.getInterfaceName()), Map.class };
 
             // service interface or ServiceReference first
             String realMethodName = methodName;
             Method method = getMethod(realMethodName, sig);
             if (method == null) {
                 method = getMethod(realMethodName, sig2);
-                if (method == null && this.specVersion.ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
+                if (method == null && this.options.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
                     method = getMethod(realMethodName, sig3);
                 }
             }
@@ -528,7 +526,7 @@
             if (method == null) {
                 final String info;
                 if (StringUtils.isEmpty(ref.getName())) {
-                    final String interfaceName = ref.getInterfacename();
+                    final String interfaceName = ref.getInterfaceName();
                     final int pos = interfaceName.lastIndexOf('.');
                     info = interfaceName.substring(pos + 1);
                 } else {
@@ -540,20 +538,20 @@
             }
             if (method == null) {
                 method = getMethod(realMethodName, sig2);
-                if (method == null && this.specVersion.ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
+                if (method == null && this.options.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
                     method = getMethod(realMethodName, sig3);
                 }
             }
 
             // append type name with service interface and ServiceReference
             if (method == null) {
-                int lastDot = ref.getInterfacename().lastIndexOf('.');
-                realMethodName = methodName + ref.getInterfacename().substring(lastDot + 1);
+                int lastDot = ref.getInterfaceName().lastIndexOf('.');
+                realMethodName = methodName + ref.getInterfaceName().substring(lastDot + 1);
                 method = getMethod(realMethodName, sig);
             }
             if (method == null) {
                 method = getMethod(realMethodName, sig2);
-                if (method == null && this.specVersion.ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
+                if (method == null && this.options.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
                     method = getMethod(realMethodName, sig3);
                 }
             }
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
deleted file mode 100644
index f6b843a..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/AbstractObject.java
+++ /dev/null
@@ -1,49 +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.om;
-
-import org.apache.felix.scrplugin.annotations.ScannedAnnotation;
-import org.apache.felix.scrplugin.helper.IssueLog;
-
-/**
- * The <code>AbstractObject</code> is the base class for the all classes of the scr om.
- */
-public abstract class AbstractObject {
-
-    private final String annotationPrefix;
-
-    private final String sourceLocation;
-
-    protected AbstractObject(final ScannedAnnotation annotation, final String sourceLocation) {
-        if ( annotation == null ) {
-            this.annotationPrefix = "";
-        } else {
-            this.annotationPrefix = "@" + annotation.getSimpleName()  + " : ";
-        }
-        this.sourceLocation = sourceLocation;
-    }
-
-    public void logWarn(IssueLog iLog, String message) {
-        iLog.addWarning(this.annotationPrefix + message, sourceLocation);
-    }
-
-    public void logError(IssueLog iLog, String message) {
-        iLog.addError(this.annotationPrefix + 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
deleted file mode 100644
index 4d036a9..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Component.java
+++ /dev/null
@@ -1,267 +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.om;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.felix.scrplugin.SpecVersion;
-import org.apache.felix.scrplugin.annotations.ScannedAnnotation;
-import org.apache.felix.scrplugin.description.ClassDescription;
-import org.apache.felix.scrplugin.description.ComponentConfigurationPolicy;
-
-/**
- * <code>Component</code> is a described component.
- *
- */
-public class Component extends AbstractObject {
-
-    /** The name of the component. */
-    protected String name;
-
-    /** Is this component enabled? */
-    protected Boolean enabled;
-
-    /** Is this component immediately started. */
-    protected Boolean immediate;
-
-    /** The factory. */
-    protected String factory;
-
-    /** All properties. */
-    protected List<Property> properties = new ArrayList<Property>();
-
-    /** The corresponding service. */
-    protected Service service;
-
-    /** The references. */
-    protected List<Reference> references = new ArrayList<Reference>();
-
-    /** Is this an abstract description? */
-    protected boolean isAbstract;
-
-    /** Is this a descriptor to be ignored ? */
-    protected boolean isDs;
-
-    /** Configuration policy. (V1.1) */
-    protected ComponentConfigurationPolicy configurationPolicy;
-
-    /** Activation method. (V1.1) */
-    protected String activate;
-
-    /** Deactivation method. (V1.1) */
-    protected String deactivate;
-
-    /** Modified method. (V1.1) */
-    protected String modified;
-
-    /** The spec version. */
-    protected SpecVersion specVersion;
-
-    /** The class description. */
-    private final ClassDescription classDescription;
-
-    /** Configuration PID (V1.2) */
-    private String configurationPid;
-
-    /**
-     * Constructor from java source.
-     */
-    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 SpecVersion getSpecVersion() {
-        return this.specVersion;
-    }
-
-    /**
-     * Set the spec version.
-     */
-    public void setSpecVersion(final SpecVersion value) {
-        // only set a higher version, never "downgrade"
-        if (this.specVersion == null || this.specVersion.ordinal() < value.ordinal()) {
-            this.specVersion = value;
-        }
-    }
-
-    /**
-     * @return All properties of this component.
-     */
-    public List<Property> getProperties() {
-        return this.properties;
-    }
-
-    public void setProperties(List<Property> properties) {
-        this.properties = properties;
-    }
-
-    public void addProperty(Property property) {
-        this.properties.add(property);
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getFactory() {
-        return this.factory;
-    }
-
-    public void setFactory(String factory) {
-        this.factory = factory;
-    }
-
-    public Boolean isEnabled() {
-        return this.enabled;
-    }
-
-    public void setEnabled(Boolean enabled) {
-        this.enabled = enabled;
-    }
-
-    public Boolean isImmediate() {
-        return this.immediate;
-    }
-
-    public void setImmediate(Boolean immediate) {
-        this.immediate = immediate;
-    }
-
-    public Service getService() {
-        return this.service;
-    }
-
-    public void setService(Service service) {
-        this.service = service;
-    }
-
-    public List<Reference> getReferences() {
-        return this.references;
-    }
-
-    public void setReferences(List<Reference> references) {
-        this.references = references;
-    }
-
-    public void addReference(Reference ref) {
-        this.references.add(ref);
-    }
-
-    public boolean isAbstract() {
-        return this.isAbstract;
-    }
-
-    public void setAbstract(boolean isAbstract) {
-        this.isAbstract = isAbstract;
-    }
-
-    public boolean isDs() {
-        return isDs;
-    }
-
-    public void setDs(boolean isDs) {
-        this.isDs = isDs;
-    }
-
-    /**
-     * Get the name of the activate method (or null for default)
-     */
-    public String getActivate() {
-        return this.activate;
-    }
-
-    /**
-     * Set the name of the deactivate method (or null for default)
-     */
-    public void setDeactivate(final String value) {
-        this.deactivate = value;
-    }
-
-    /**
-     * Get the name of the deactivate method (or null for default)
-     */
-    public String getDeactivate() {
-        return this.deactivate;
-    }
-
-    /**
-     * Set the name of the activate method (or null for default)
-     */
-    public void setActivate(final String value) {
-        this.activate = value;
-    }
-
-    /**
-     * Set the name of the modified method (or null for default)
-     */
-    public void setModified(final String value) {
-        this.modified = value;
-    }
-
-    /**
-     * Get the name of the modified method (or null for default)
-     */
-    public String getModified() {
-        return this.modified;
-    }
-
-    /**
-     * Return the configuration policy.
-     */
-    public ComponentConfigurationPolicy getConfigurationPolicy() {
-        return this.configurationPolicy;
-    }
-
-    /**
-     * Set the configuration policy.
-     */
-    public void setConfigurationPolicy(final ComponentConfigurationPolicy value) {
-        this.configurationPolicy = value;
-    }
-
-    @Override
-    public String toString() {
-        return "Component [name=" + name + ", enabled=" + enabled + ", immediate=" + immediate + ", factory=" + factory
-                        + ", properties=" + properties + ", service=" + service + ", references=" + references + ", isAbstract="
-                        + isAbstract + ", isDs=" + isDs + ", configurationPolicy=" + configurationPolicy + ", activate="
-                        + activate + ", deactivate=" + deactivate + ", modified=" + modified + ", specVersion=" + specVersion
-                        + ", classDescription=" + classDescription + ", configurationPid=" + configurationPid + "]";
-    }
-
-    public String getConfigurationPid() {
-        return configurationPid;
-    }
-
-    public void setConfigurationPid(String configurationPid) {
-        this.configurationPid = configurationPid;
-    }
-}
\ 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
deleted file mode 100644
index b97059d..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Components.java
+++ /dev/null
@@ -1,73 +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.om;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.felix.scrplugin.SpecVersion;
-
-/**
- * <code>Components</code>...
- *
- * Components is just a collection of {@link Component}s.
- */
-public class Components {
-
-    /** The spec version. */
-    private SpecVersion specVersion;
-
-    /** The list of {@link Component}s. */
-    private List<Component> components = new ArrayList<Component>();
-
-    /**
-     * Return the list of {@link Component}s.
-     */
-    public List<Component> getComponents() {
-        return this.components;
-    }
-
-    /**
-     * Set the list of {@link Component}s.
-     */
-    public void setComponents(List<Component> components) {
-        this.components = components;
-    }
-
-    /**
-     * Add a component to the list.
-     */
-    public void addComponent(Component component) {
-        this.components.add(component);
-    }
-
-    /**
-     * Get the spec version.
-     */
-    public SpecVersion getSpecVersion() {
-        return this.specVersion;
-    }
-
-    /**
-     * Set the spec version.
-     */
-    public void setSpecVersion(SpecVersion value) {
-        this.specVersion = value;
-    }
-}
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
deleted file mode 100644
index d7930a1..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Interface.java
+++ /dev/null
@@ -1,54 +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.om;
-
-import org.apache.felix.scrplugin.annotations.ScannedAnnotation;
-
-/**
- * <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 {
-
-    /** Name of the interface. */
-    private String interfaceName;
-
-    /**
-     * Constructor from java source.
-     */
-    public Interface(final ScannedAnnotation annotation, final String sourceLocation) {
-        super(annotation, sourceLocation);
-    }
-
-    /**
-     * Get the interface name.
-     */
-    public String getInterfaceName() {
-        return this.interfaceName;
-    }
-
-    /**
-     * Set the interface name.
-     */
-    public void setInterfaceName(final String name) {
-        this.interfaceName = name;
-    }
-}
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
deleted file mode 100644
index 10ebbf6..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Property.java
+++ /dev/null
@@ -1,75 +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.om;
-
-import org.apache.felix.scrplugin.annotations.ScannedAnnotation;
-import org.apache.felix.scrplugin.description.PropertyType;
-
-/**
- * <code>Property.java</code>...
- *
- */
-public class Property extends AbstractObject {
-
-    protected String name;
-    protected String value;
-    protected PropertyType type;
-    protected String[] multiValue;
-
-    /**
-     * Constructor from java source.
-     */
-    public Property(final ScannedAnnotation annotation, final String sourceLocation) {
-        super(annotation, sourceLocation);
-    }
-
-    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;
-    }
-}
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
deleted file mode 100644
index f099be7..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Reference.java
+++ /dev/null
@@ -1,151 +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.om;
-
-import java.lang.reflect.Field;
-
-import org.apache.felix.scrplugin.annotations.ScannedAnnotation;
-import org.apache.felix.scrplugin.description.ReferenceCardinality;
-import org.apache.felix.scrplugin.description.ReferencePolicy;
-import org.apache.felix.scrplugin.description.ReferencePolicyOption;
-import org.apache.felix.scrplugin.description.ReferenceStrategy;
-
-/**
- * <code>Reference.java</code>...
- *
- */
-public class Reference extends AbstractObject {
-
-    protected String name;
-    protected String interfacename;
-    protected String target;
-    protected ReferenceCardinality cardinality;
-    protected ReferencePolicy policy;
-    protected ReferencePolicyOption policyOption;
-    protected String bind;
-    protected String unbind;
-    protected String updated;
-
-    /** @since 1.0.9 */
-    protected ReferenceStrategy strategy;
-
-    private Field field;
-
-    /**
-     * Constructor from java source.
-     */
-    public Reference(final ScannedAnnotation annotation, final String sourceLocation) {
-        super(annotation, sourceLocation);
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public Field getField() {
-        return this.field;
-    }
-
-    public void setField(Field field) {
-        this.field = field;
-    }
-
-    public String getInterfacename() {
-        return this.interfacename;
-    }
-
-    public void setInterfacename(String interfacename) {
-        this.interfacename = interfacename;
-    }
-
-    public String getTarget() {
-        return this.target;
-    }
-
-    public void setTarget(String target) {
-        this.target = target;
-    }
-
-    public ReferenceCardinality getCardinality() {
-        return this.cardinality;
-    }
-
-    public void setCardinality(ReferenceCardinality cardinality) {
-        this.cardinality = cardinality;
-    }
-
-    public ReferencePolicy getPolicy() {
-        return this.policy;
-    }
-
-    public void setPolicy(ReferencePolicy policy) {
-        this.policy = policy;
-    }
-
-    public ReferencePolicyOption getPolicyOption() {
-        return this.policyOption;
-    }
-
-    public void setPolicyOption(ReferencePolicyOption policyOption) {
-        this.policyOption = policyOption;
-    }
-
-    public String getBind() {
-        return this.bind;
-    }
-
-    public void setBind(String bind) {
-        this.bind = bind;
-    }
-
-    public String getUnbind() {
-        return this.unbind;
-    }
-
-    public void setUnbind(String unbind) {
-        this.unbind = unbind;
-    }
-
-    public String getUpdated() {
-        return this.updated;
-    }
-
-    public void setUpdated(String updated) {
-        this.updated = updated;
-    }
-
-    /** @since 1.0.9 */
-    public ReferenceStrategy getStrategy() {
-        return strategy;
-    }
-
-    /** @since 1.0.9 */
-    public void setStrategy(ReferenceStrategy strategy) {
-        this.strategy = strategy;
-    }
-
-    /** @since 1.0.9 */
-    public boolean isLookupStrategy() {
-        return this.getStrategy() == ReferenceStrategy.LOOKUP;
-    }
-}
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
deleted file mode 100644
index 0eaf89d..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Service.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.om;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * <code>Service</code>
- *
- * contains all service information of a component.
- */
-public class Service {
-
-    /** Flag for the service factory. */
-    private boolean isServiceFactory;
-
-    /** The list of implemented interfaces. */
-    private final List<Interface> interfaces = new ArrayList<Interface>();
-
-    /**
-     * Is this a service factory?
-     */
-    public boolean isServiceFactory() {
-        return this.isServiceFactory;
-    }
-
-    /**
-     * Set the service factory flag.
-     */
-    public void setServiceFactory(final 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.
-     * @return The interface if it is implemented by this service or null.
-     */
-    public Interface findInterface(final String name) {
-        final Iterator<Interface> i = this.getInterfaces().iterator();
-        while (i.hasNext()) {
-            final Interface current = i.next();
-            if (current.getInterfaceName().equals(name)) {
-                return current;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Add an interface to the list of interfaces.
-     *
-     * @param interf
-     *            The interface.
-     */
-    public void addInterface(final Interface interf) {
-        // add interface only once
-        if (this.findInterface(interf.getInterfaceName()) == null) {
-            this.interfaces.add(interf);
-        }
-    }
-}
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 9371e03..1677b77 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,9 +18,11 @@
  */
 package org.apache.felix.scrplugin.xml;
 
+import java.awt.Component;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.security.Provider.Service;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.StringTokenizer;
@@ -32,7 +34,6 @@
 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;
@@ -41,13 +42,9 @@
 import org.apache.felix.scrplugin.description.ReferencePolicyOption;
 import org.apache.felix.scrplugin.description.ReferenceStrategy;
 import org.apache.felix.scrplugin.description.ServiceDescription;
+import org.apache.felix.scrplugin.helper.ComponentContainer;
+import org.apache.felix.scrplugin.helper.DescriptionContainer;
 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.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;
@@ -132,26 +129,26 @@
             IOUtils.parse(file, xmlHandler);
             return xmlHandler.components;
         } catch (final TransformerException e) {
-            throw new SCRDescriptorException("Unable to read xml", "[stream]", 0, e);
+            throw new SCRDescriptorException("Unable to read xml", "[stream]", e);
         }
     }
 
     /**
      * Write the component descriptors to the file.
      *
-     * @param components
+     * @param module
      * @param file
      * @throws SCRDescriptorException
      */
-    public static void write(Components components, File file) throws SCRDescriptorException {
+    public static void write(final DescriptionContainer module, final File file) throws SCRDescriptorException {
         try {
-            generateXML(components, IOUtils.getSerializer(file));
-        } catch (TransformerException e) {
-            throw new SCRDescriptorException("Unable to write xml", file.toString(), 0, e);
-        } catch (SAXException e) {
-            throw new SCRDescriptorException("Unable to generate xml", file.toString(), 0, e);
-        } catch (IOException e) {
-            throw new SCRDescriptorException("Unable to write xml", file.toString(), 0, e);
+            generateXML(module, IOUtils.getSerializer(file));
+        } catch (final TransformerException e) {
+            throw new SCRDescriptorException("Unable to write xml", file.toString(), e);
+        } catch (final SAXException e) {
+            throw new SCRDescriptorException("Unable to generate xml", file.toString(), e);
+        } catch (final IOException e) {
+            throw new SCRDescriptorException("Unable to write xml", file.toString(), e);
         }
     }
 
@@ -163,10 +160,10 @@
      * @param contentHandler
      * @throws SAXException
      */
-    protected static void generateXML(final Components components,
+    protected static void generateXML(final DescriptionContainer module,
                     final ContentHandler contentHandler) throws SAXException {
         // detect namespace to use
-        final String namespace = components.getSpecVersion().getNamespaceUrl();
+        final String namespace = module.getOptions().getSpecVersion().getNamespaceUrl();
 
         contentHandler.startDocument();
         contentHandler.startPrefixMapping(PREFIX, namespace);
@@ -175,14 +172,13 @@
         contentHandler.startElement("", ComponentDescriptorIO.COMPONENTS, ComponentDescriptorIO.COMPONENTS, new AttributesImpl());
         IOUtils.newline(contentHandler);
 
-        for (final Component component : components.getComponents()) {
-            if (component.isDs()) {
-                final SpecVersion oldVersion = component.getSpecVersion();
-                component.setSpecVersion(components.getSpecVersion());
-                generateXML(namespace, component, contentHandler);
-                component.setSpecVersion(oldVersion);
-            }
+        for (final ComponentContainer component : module.getComponents()) {
+            final SpecVersion oldVersion = component.getComponentDescription().getSpecVersion();
+            component.getComponentDescription().setSpecVersion(module.getOptions().getSpecVersion());
+            generateXML(namespace, component, contentHandler);
+            component.getComponentDescription().setSpecVersion(oldVersion);
         }
+
         // end wrapper element
         contentHandler.endElement("", ComponentDescriptorIO.COMPONENTS, ComponentDescriptorIO.COMPONENTS);
         IOUtils.newline(contentHandler);
@@ -197,11 +193,13 @@
      * @param contentHandler
      * @throws SAXException
      */
-    protected static void generateXML(final String namespace, final Component component, final ContentHandler contentHandler)
-                    throws SAXException {
+    protected static void generateXML(final String namespace, final ComponentContainer container, final ContentHandler contentHandler)
+    throws SAXException {
+        final ComponentDescription component = container.getComponentDescription();
+
         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_ENABLED, component.getEnabled());
+        IOUtils.addAttribute(ai, COMPONENT_ATTR_IMMEDIATE, component.getImmediate());
         IOUtils.addAttribute(ai, COMPONENT_ATTR_NAME, component.getName());
         IOUtils.addAttribute(ai, COMPONENT_ATTR_FACTORY, component.getFactory());
 
@@ -223,20 +221,18 @@
         IOUtils.indent(contentHandler, 1);
         contentHandler.startElement(namespace, ComponentDescriptorIO.COMPONENT, ComponentDescriptorIO.COMPONENT_QNAME, ai);
         IOUtils.newline(contentHandler);
-        generateImplementationXML(component, contentHandler);
-        if (component.getService() != null) {
-            generateServiceXML(component.getService(), contentHandler);
+        generateImplementationXML(container, contentHandler);
+        if (container.getServiceDescription() != null) {
+            generateServiceXML(container.getServiceDescription(), contentHandler);
         }
-        if (component.getProperties() != null) {
-            for (final Property property : component.getProperties()) {
-                generatePropertyXML(property, contentHandler);
-            }
+        for (final PropertyDescription property : container.getProperties().values()) {
+            generatePropertyXML(property, contentHandler);
         }
-        if (component.getReferences() != null) {
-            for (final Reference reference : component.getReferences()) {
-                generateReferenceXML(component, reference, contentHandler);
-            }
+
+        for (final ReferenceDescription reference : container.getReferences().values()) {
+            generateReferenceXML(component, reference, contentHandler);
         }
+
         IOUtils.indent(contentHandler, 1);
         contentHandler.endElement(namespace, ComponentDescriptorIO.COMPONENT, ComponentDescriptorIO.COMPONENT_QNAME);
         IOUtils.newline(contentHandler);
@@ -249,7 +245,7 @@
      * @param contentHandler
      * @throws SAXException
      */
-    protected static void generateImplementationXML(Component component, ContentHandler contentHandler) throws SAXException {
+    protected static void generateImplementationXML(ComponentContainer component, ContentHandler contentHandler) throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
         IOUtils.addAttribute(ai, "class", component.getClassDescription().getDescribedClass().getName());
         IOUtils.indent(contentHandler, 2);
@@ -268,7 +264,7 @@
      * @throws SAXException
      */
     protected static void generateServiceXML(
-                    final Service service,
+                    final ServiceDescription service,
                     final ContentHandler contentHandler)
     throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
@@ -277,8 +273,8 @@
         contentHandler.startElement(INNER_NAMESPACE_URI, ComponentDescriptorIO.SERVICE, ComponentDescriptorIO.SERVICE_QNAME, ai);
         if (service.getInterfaces() != null && service.getInterfaces().size() > 0) {
             IOUtils.newline(contentHandler);
-            for (final Interface interf : service.getInterfaces()) {
-                generateXML(interf, contentHandler);
+            for (final String interf : service.getInterfaces()) {
+                generateServiceXML(interf, contentHandler);
             }
             IOUtils.indent(contentHandler, 2);
         }
@@ -293,9 +289,10 @@
      * @param contentHandler
      * @throws SAXException
      */
-    protected static void generateXML(Interface interf, ContentHandler contentHandler) throws SAXException {
+    private static void generateServiceXML(final String interfaceName, final ContentHandler contentHandler)
+    throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
-        IOUtils.addAttribute(ai, "interface", interf.getInterfaceName());
+        IOUtils.addAttribute(ai, "interface", interfaceName);
         IOUtils.indent(contentHandler, 3);
         contentHandler.startElement(INNER_NAMESPACE_URI, ComponentDescriptorIO.INTERFACE, ComponentDescriptorIO.INTERFACE_QNAME,
                         ai);
@@ -310,7 +307,7 @@
      * @param contentHandler
      * @throws SAXException
      */
-    protected static void generatePropertyXML(Property property, ContentHandler contentHandler) throws SAXException {
+    protected static void generatePropertyXML(PropertyDescription property, ContentHandler contentHandler) throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
         IOUtils.addAttribute(ai, "name", property.getName());
         IOUtils.addAttribute(ai, "type", property.getType());
@@ -339,13 +336,13 @@
      * @param contentHandler
      * @throws SAXException
      */
-    protected static void generateReferenceXML(final Component component,
-                    final Reference reference,
+    protected static void generateReferenceXML(final ComponentDescription component,
+                    final ReferenceDescription reference,
                     final ContentHandler contentHandler)
     throws SAXException {
         final AttributesImpl ai = new AttributesImpl();
         IOUtils.addAttribute(ai, "name", reference.getName());
-        IOUtils.addAttribute(ai, "interface", reference.getInterfacename());
+        IOUtils.addAttribute(ai, "interface", reference.getInterfaceName());
         IOUtils.addAttribute(ai, "cardinality", reference.getCardinality().getCardinalityString());
         IOUtils.addAttribute(ai, "policy", reference.getPolicy().name().toLowerCase());
         IOUtils.addAttribute(ai, "target", reference.getTarget());
@@ -479,22 +476,23 @@
                             }
                         }
                         if ( attributes.getValue(COMPONENT_ATTR_ACTIVATE) != null ) {
-                            desc.setActivate(new MethodDescription(attributes.getValue(COMPONENT_ATTR_ACTIVATE)));
+                            desc.setActivate(attributes.getValue(COMPONENT_ATTR_ACTIVATE));
                         }
                         if ( attributes.getValue(COMPONENT_ATTR_DEACTIVATE) != null ) {
-                            desc.setDeactivate(new MethodDescription(attributes.getValue(COMPONENT_ATTR_DEACTIVATE)));
+                            desc.setDeactivate(attributes.getValue(COMPONENT_ATTR_DEACTIVATE));
                         }
                         if ( attributes.getValue(COMPONENT_ATTR_MODIFIED) != null ) {
-                            desc.setModified(new MethodDescription(attributes.getValue(COMPONENT_ATTR_MODIFIED)));
+                            desc.setModified(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 String className = attributes.getValue("class");
                     try {
-                        this.currentClass = new ClassDescription(this.classLoader.loadClass(attributes.getValue("class")), null);
+                        this.currentClass = new ClassDescription(this.classLoader.loadClass(className), "classpath:" + className);
                     } catch (final ClassNotFoundException e) {
-                        iLog.addError("Unable to load class " + attributes.getValue("class") + " from dependencies.", this.location);
+                        iLog.addError("Unable to load class " + className + " from dependencies.", this.location);
                     }
                     this.currentClass.add(this.currentComponent);
 
@@ -584,10 +582,13 @@
                     }
                     ref.setTarget(attributes.getValue("target"));
                     if ( attributes.getValue("bind") != null ) {
-                        ref.setBind(new MethodDescription(attributes.getValue("bind")));
+                        ref.setBind(attributes.getValue("bind"));
                     }
                     if ( attributes.getValue("unbind") != null ) {
-                        ref.setUnbind(new MethodDescription(attributes.getValue("unbind")));
+                        ref.setUnbind(attributes.getValue("unbind"));
+                    }
+                    if ( attributes.getValue("updated") != null ) {
+                        ref.setUnbind(attributes.getValue("updated"));
                     }
 
                     final String strategy = attributes.getValue("strategy");
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java
index dcbae69..4810e25 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java
@@ -73,11 +73,11 @@
         try {
             generateXML(metaData, IOUtils.getSerializer(file));
         } catch (TransformerException e) {
-            throw new SCRDescriptorException("Unable to write xml", file.toString(), 0, e);
+            throw new SCRDescriptorException("Unable to write xml", file.toString(), e);
         } catch (SAXException e) {
-            throw new SCRDescriptorException("Unable to generate xml", file.toString(), 0, e);
+            throw new SCRDescriptorException("Unable to generate xml", file.toString(), e);
         } catch (IOException e) {
-            throw new SCRDescriptorException("Unable to write xml", file.toString(), 0, e);
+            throw new SCRDescriptorException("Unable to write xml", file.toString(), e);
         }
     }
 
diff --git a/scrplugin/scrtask/src/main/java/org/apache/felix/scrplugin/ant/SCRDescriptorTask.java b/scrplugin/scrtask/src/main/java/org/apache/felix/scrplugin/ant/SCRDescriptorTask.java
index 61bfe82..dbea73b 100644
--- a/scrplugin/scrtask/src/main/java/org/apache/felix/scrplugin/ant/SCRDescriptorTask.java
+++ b/scrplugin/scrtask/src/main/java/org/apache/felix/scrplugin/ant/SCRDescriptorTask.java
@@ -129,7 +129,7 @@
             generator.execute();
         } catch ( final SCRDescriptorException sde ) {
             if ( sde.getSourceLocation() != null )  {
-                Location loc = new Location( sde.getSourceLocation(), sde.getLineNumber(), 0 );
+                final Location loc = new Location( sde.getSourceLocation(), -1, 0 );
                 throw new BuildException( sde.getMessage(), sde.getCause(), loc );
             }
             throw new BuildException( sde.getMessage(), sde.getCause() );