FELIX-3550 : Reimplement the SCR Generator

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1350929 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scrplugin/annotations/src/main/java/org/apache/felix/scr/annotations/Component.java b/scrplugin/annotations/src/main/java/org/apache/felix/scr/annotations/Component.java
index 55c3738..f6ee448 100644
--- a/scrplugin/annotations/src/main/java/org/apache/felix/scr/annotations/Component.java
+++ b/scrplugin/annotations/src/main/java/org/apache/felix/scr/annotations/Component.java
@@ -142,5 +142,5 @@
      * The default value for this is the name of the component.
      * @since 1.7
      */
-    String configurationPid();
+    String configurationPid() default "";
 }
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 49e29ca..c36c534 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
@@ -21,7 +21,6 @@
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -36,6 +35,7 @@
 import org.apache.felix.scrplugin.description.ReferenceDescription;
 import org.apache.felix.scrplugin.description.ReferencePolicyOption;
 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;
@@ -43,7 +43,6 @@
 import org.apache.felix.scrplugin.helper.StringUtils;
 import org.apache.felix.scrplugin.om.Component;
 import org.apache.felix.scrplugin.om.Components;
-import org.apache.felix.scrplugin.om.Context;
 import org.apache.felix.scrplugin.om.Interface;
 import org.apache.felix.scrplugin.om.Property;
 import org.apache.felix.scrplugin.om.Reference;
@@ -235,12 +234,8 @@
         for (final Component comp : processedComponents) {
             final int errorCount = iLog.getNumberOfErrors();
 
-            final Context ctx = new Context();
-            ctx.setClassDescription(comp.getClassDescription());
-            ctx.setIssueLog(iLog);
-            ctx.setProject(project);
-            ctx.setSpecVersion(specVersion);
-            ctx.setOptions(options);
+            final Validator validator = new Validator(comp.getClassDescription(),
+                            comp, specVersion, project, options);
 
             if ( this.options.isGenerateAccessors() ) {
                 // before we can validate we should check the references for bind/unbind method
@@ -262,11 +257,11 @@
                         boolean createUnbind = false;
 
                         // Only create method if no bind name has been specified
-                        if (bindValue == null && ref.findMethod(ctx, "bind") == null) {
+                        if (bindValue == null && validator.findMethod(iLog, ref, "bind") == null) {
                             // create bind method
                             createBind = true;
                         }
-                        if (unbindValue == null && ref.findMethod(ctx, "unbind") == null) {
+                        if (unbindValue == null && validator.findMethod(iLog, ref, "unbind") == null) {
                             // create unbind method
                             createUnbind = true;
                         }
@@ -282,7 +277,7 @@
                     }
                 }
             }
-            comp.validate(ctx);
+            validator.validate(iLog);
 
             // ignore component if it has errors
             if (iLog.getNumberOfErrors() == errorCount) {
@@ -417,8 +412,8 @@
             ocd = null;
         }
 
-        final Map<String, Reference> allReferences = new HashMap<String, Reference>();
-        final Map<String, Property> allProperties = new HashMap<String, Property>();
+        final Map<String, Reference> allReferences = new LinkedHashMap<String, Reference>();
+        final Map<String, Property> allProperties = new LinkedHashMap<String, Property>();
 
         ClassDescription current = desc;
         boolean inherit;
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/description/Validator.java
new file mode 100644
index 0000000..6ee2c2c
--- /dev/null
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/description/Validator.java
@@ -0,0 +1,566 @@
+/*
+ * 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.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Map;
+
+import org.apache.felix.scrplugin.Options;
+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;
+
+public class Validator {
+
+    private final ClassDescription classDescription;
+
+    private final Component component;
+
+    private final SpecVersion specVersion;
+
+    private final Options options;
+
+    private final Project project;
+
+    public Validator(final ClassDescription cd,
+                    final Component component,
+                    final SpecVersion specVersion,
+                    final Project project,
+                    final Options options) {
+        this.classDescription = cd;
+        this.project = project;
+        this.specVersion = specVersion;
+        this.component = component;
+        this.options = options;
+    }
+
+    /**
+     * 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)
+    throws SCRDescriptorException {
+        // nothing to check if this is ignored
+        if (!component.isDs()) {
+            return;
+        }
+
+        final int currentIssueCount = iLog.getNumberOfErrors();
+
+        // if the component is abstract, we do not validate everything
+        if (!this.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 "
+                                + 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.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());
+            }
+
+            // 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();
+
+                // check activate and deactivate methods
+                this.checkLifecycleMethod(iLog, activateName, true);
+                this.checkLifecycleMethod(iLog, deactivateName, false);
+
+                if (this.component.getModified() != null) {
+                    if ( this.specVersion.ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
+                        this.checkLifecycleMethod(iLog, this.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());
+                    }
+                }
+
+                // ensure public default constructor
+                boolean constructorFound = true;
+                Constructor<?>[] constructors = this.classDescription.getDescribedClass().getDeclaredConstructors();
+                for (int i = 0; constructors != null && i < constructors.length; i++) {
+                    // if public default, succeed
+                    if (Modifier.isPublic(constructors[i].getModifiers())
+                        && (constructors[i].getParameterTypes() == null || constructors[i].getParameterTypes().length == 0)) {
+                        constructorFound = true;
+                        break;
+                    }
+
+                    // non-public/non-default constructor found, must have
+                    // explicit
+                    constructorFound = false;
+                }
+
+                if (!constructorFound) {
+                    this.component.logError(iLog, "Class must have public default constructor: " + this.classDescription.getDescribedClass().getName());
+                }
+
+                // verify properties
+                for (final Property prop : this.component.getProperties()) {
+                    this.validateProperty(iLog, 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!");
+                    }
+                    this.validateService(iLog, component.getService());
+                    isServiceFactory = this.component.getService().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,
+                        "Component must not be a ServiceFactory, if immediate and/or component factory: "
+                        + this.classDescription.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 (iLog.getNumberOfErrors() == currentIssueCount) {
+            // verify references
+            for (final Reference ref : this.component.getReferences()) {
+                this.validateReference(iLog, ref, this.component.isAbstract());
+            }
+        }
+    }
+
+    private static final String TYPE_COMPONENT_CONTEXT = "org.osgi.service.component.ComponentContext";
+    private static final String TYPE_BUNDLE_CONTEXT = "org.osgi.framework.BundleContext";
+    private static final String TYPE_MAP = "java.util.Map";
+    private static final String TYPE_INT = "int";
+    private static final String TYPE_INTEGER = "java.lang.Integer";
+
+    private Method getMethod(final String name, final String[] sig)
+    throws SCRDescriptorException {
+        Class<?>[] classSig = (sig == null ? null : new Class<?>[sig.length]);
+        if ( sig != null ) {
+            for(int i = 0; i<sig.length; i++) {
+                try {
+                    if ( sig[i].equals("int") ) {
+                        classSig[i] = int.class;
+                    } else {
+                        classSig[i] = this.project.getClassLoader().loadClass(sig[i]);
+                    }
+                } catch (final ClassNotFoundException e) {
+                    throw new SCRDescriptorException("Unable to load class.", e);
+                }
+            }
+        }
+        try {
+            return this.classDescription.getDescribedClass().getDeclaredMethod(name, classSig);
+        } catch (final SecurityException e) {
+            // ignore
+        } catch (final NoSuchMethodException e) {
+            // ignore
+        }
+        return null;
+    }
+
+    /**
+     * Check for existence of lifecycle methods.
+     *
+     * @param specVersion
+     *            The spec version
+     * @param javaClass
+     *            The java class to inspect.
+     * @param methodName
+     *            The method name.
+     * @param warnings
+     *            The list of warnings used to add new warnings.
+     */
+    private void checkLifecycleMethod(final IssueLog iLog,
+                                      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() ) {
+                // second candidate is (de)activate(BundleContext)
+                method = this.getMethod(methodName, new String[] { TYPE_BUNDLE_CONTEXT });
+                if (method == null) {
+                    // third candidate is (de)activate(Map)
+                    method = this.getMethod(methodName, new String[] { TYPE_MAP });
+
+                    if (method == null) {
+                        // if this is a deactivate method, we have two
+                        // additional possibilities
+                        // a method with parameter of type int and one of type
+                        // Integer
+                        if (!isActivate) {
+                            method = this.getMethod(methodName, new String[] { TYPE_INT });
+                            if (method == null) {
+                                method = this.getMethod(methodName, new String[] { TYPE_INTEGER });
+                            }
+                        }
+                    }
+
+                    if (method == null) {
+                        // fourth candidate is (de)activate with two or three
+                        // arguments (type must be BundleContext, ComponentCtx
+                        // and Map)
+                        // as we have to iterate now and the fifth candidate is
+                        // zero arguments
+                        // we already store this option
+                        Method zeroArgMethod = null;
+                        Method found = method;
+                        final Method[] methods = this.classDescription.getDescribedClass().getDeclaredMethods();
+                        int i = 0;
+                        while (i < methods.length) {
+                            if (methodName.equals(methods[i].getName())) {
+
+                                if (methods[i].getParameterTypes() == null || methods[i].getParameterTypes().length == 0) {
+                                    zeroArgMethod = methods[i];
+                                } else if (methods[i].getParameterTypes().length >= 2) {
+                                    boolean valid = true;
+                                    for (int m = 0; m < methods[i].getParameterTypes().length; m++) {
+                                        final String type = methods[i].getParameterTypes()[m].getName();
+                                        if (!type.equals(TYPE_BUNDLE_CONTEXT) && !type.equals(TYPE_COMPONENT_CONTEXT)
+                                            && !type.equals(TYPE_MAP)) {
+                                            // if this is deactivate, int and
+                                            // integer are possible as well
+                                            if (isActivate || (!type.equals(TYPE_INT) && !type.equals(TYPE_INTEGER))) {
+                                                valid = false;
+                                            }
+                                        }
+                                    }
+                                    if (valid) {
+                                        if (found == null) {
+                                            found = methods[i];
+                                        } else {
+                                            // print warning
+                                            this.component.logWarn(iLog, "Lifecycle method " + methods[i].getName()
+                                                      + " occurs several times with different matching signature.");
+                                        }
+                                    }
+                                }
+                            }
+                            i++;
+                        }
+                        if (found != null) {
+                            method = found;
+                        } else {
+                            method = zeroArgMethod;
+                        }
+                    }
+                }
+            }
+        }
+        // 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();
+            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");
+                    } else {
+                        this.component.logWarn(iLog,
+                            "Lifecycle method " + methods[i].getName() + " has wrong argument "
+                            + methods[i].getParameterTypes()[0].getName());
+                    }
+                }
+            }
+        }
+
+        // method must be protected for version 1.0
+        if (method != null && specVersion == SpecVersion.VERSION_1_0) {
+            // check protected
+            if (Modifier.isPublic(method.getModifiers())) {
+                this.component.logWarn(iLog, "Lifecycle method " + method.getName() + " should be declared protected");
+            } else if (!Modifier.isProtected(method.getModifiers())) {
+                this.component.logWarn(iLog, "Lifecycle method " + method.getName() +
+                            " has wrong qualifier, public or protected required");
+            }
+        }
+    }
+
+    /**
+     * Validate the service.
+     * 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());
+                }
+            } catch (final ClassNotFoundException cnfe) {
+                throw new SCRDescriptorException("Unable to load interface class.", cnfe);
+            }
+        }
+    }
+
+    /**
+     * Validate the property.
+     * 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) {
+        if (property.getName() == null || property.getName().trim().length() == 0) {
+            property.logError(iLog, "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) {
+                property.setType(PropertyType.Char);
+            }
+            if (this.specVersion.ordinal() >= SpecVersion.VERSION_1_1.ordinal()
+                            && property.getType() == PropertyType.Char) {
+                property.setType(PropertyType.Character);
+            }
+        }
+        // TODO might want to check value
+    }
+
+    /**
+     * Validate the reference.
+     * 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)
+    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");
+            }
+        }
+
+        // validate interface
+        if (StringUtils.isEmpty(ref.getInterfacename())) {
+            ref.logError(iLog, "Missing interface name");
+        }
+        try {
+            this.project.getClassLoader().loadClass(ref.getInterfacename());
+        } catch (final ClassNotFoundException e) {
+            ref.logError(iLog, "Interface class can't be loaded: " + ref.getInterfacename());
+        }
+
+        // validate cardinality
+        if (ref.getCardinality() == null) {
+            ref.setCardinality(ReferenceCardinality.MANDATORY_UNARY);
+        }
+
+        // validate policy
+        if (ref.getPolicy() == null) {
+            ref.setPolicy(ReferencePolicy.STATIC);
+        }
+
+        // validate policy option
+        if ( ref.getPolicyOption() == null ) {
+            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() +
+                                " requires spec version " + SpecVersion.VERSION_1_2.getName() + " or higher.");
+            }
+        }
+        // validate strategy
+        if (ref.getStrategy() == null) {
+            ref.setStrategy(ReferenceStrategy.EVENT);
+        }
+
+        // validate bind and unbind methods
+        if (!ref.isLookupStrategy()) {
+            String bindName = ref.getBind();
+            String unbindName = ref.getUnbind();
+
+            final boolean canGenerate = this.options.isGenerateAccessors() &&
+                            !ref.isLookupStrategy() && ref.getField() != null
+                            && (ref.getCardinality() == ReferenceCardinality.OPTIONAL_UNARY || ref.getCardinality() == ReferenceCardinality.MANDATORY_UNARY);
+            if (bindName == null && !canGenerate ) {
+                bindName = "bind";
+            }
+            if (unbindName == null && !canGenerate ) {
+                unbindName = "unbind";
+            }
+
+            if ( bindName != null ) {
+                bindName = this.validateMethod(iLog, 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);
+            } else {
+                unbindName = "unbind" + Character.toUpperCase(ref.getName().charAt(0)) + ref.getName().substring(1);
+            }
+
+            if (iLog.getNumberOfErrors() == currentIssueCount) {
+                ref.setBind(bindName);
+                ref.setUnbind(unbindName);
+            }
+        } else {
+            ref.setBind(null);
+            ref.setUnbind(null);
+        }
+
+        // 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 "
+                                + 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)
+    throws SCRDescriptorException {
+        final Method method = this.findMethod(iLog, ref, methodName);
+        if (method == null) {
+            if (!componentIsAbstract) {
+                ref.logError(iLog,
+                                "Missing method " + methodName + " for reference "
+                                                + (ref.getName() == null ? "" : ref.getName()));
+            }
+            return null;
+        }
+
+        // method needs to be protected for 1.0
+        if (this.specVersion == SpecVersion.VERSION_1_0) {
+            if (Modifier.isPublic(method.getModifiers())) {
+                ref.logWarn(iLog, "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");
+                return null;
+            }
+        }
+        return method.getName();
+    }
+
+    private static final String TYPE_SERVICE_REFERENCE = "org.osgi.framework.ServiceReference";
+
+    private Method getMethod(final String name, final Class<?>[] sig) {
+        try {
+            return this.classDescription.getDescribedClass().getDeclaredMethod(name, sig);
+        } catch (final SecurityException e) {
+            // ignore
+        } catch (final NoSuchMethodException e) {
+            // ignore
+        }
+        return null;
+    }
+
+    public Method findMethod(final IssueLog iLog, final Reference 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 };
+
+            // 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() ) {
+                    method = getMethod(realMethodName, sig3);
+                }
+            }
+
+            // append reference name with service interface and ServiceReference
+            if (method == null) {
+                final String info;
+                if (StringUtils.isEmpty(ref.getName())) {
+                    final String interfaceName = ref.getInterfacename();
+                    final int pos = interfaceName.lastIndexOf('.');
+                    info = interfaceName.substring(pos + 1);
+                } else {
+                    info = ref.getName();
+                }
+                realMethodName = methodName + Character.toUpperCase(info.charAt(0)) + info.substring(1);
+
+                method = getMethod(realMethodName, sig);
+            }
+            if (method == null) {
+                method = getMethod(realMethodName, sig2);
+                if (method == null && this.specVersion.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);
+                method = getMethod(realMethodName, sig);
+            }
+            if (method == null) {
+                method = getMethod(realMethodName, sig2);
+                if (method == null && this.specVersion.ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
+                    method = getMethod(realMethodName, sig3);
+                }
+            }
+
+            return method;
+        } catch (final ClassNotFoundException cnfe) {
+            throw new SCRDescriptorException("Unable to load class!", cnfe);
+        }
+    }
+}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/AbstractObject.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/AbstractObject.java
index bc8fa38..f6b843a 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/AbstractObject.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/AbstractObject.java
@@ -39,11 +39,11 @@
         this.sourceLocation = sourceLocation;
     }
 
-    protected void logWarn(IssueLog iLog, String message) {
+    public void logWarn(IssueLog iLog, String message) {
         iLog.addWarning(this.annotationPrefix + message, sourceLocation);
     }
 
-    protected void logError(IssueLog iLog, String message) {
+    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
index bd1d24e..4d036a9 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Component.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Component.java
@@ -18,13 +18,9 @@
  */
 package org.apache.felix.scrplugin.om;
 
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.felix.scrplugin.SCRDescriptorException;
 import org.apache.felix.scrplugin.SpecVersion;
 import org.apache.felix.scrplugin.annotations.ScannedAnnotation;
 import org.apache.felix.scrplugin.description.ClassDescription;
@@ -239,264 +235,6 @@
     }
 
     /**
-     * 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 Context context) throws SCRDescriptorException {
-        // nothing to check if this is ignored
-        if (!isDs()) {
-            return;
-        }
-
-        final int currentIssueCount = context.getIssueLog().getNumberOfErrors();
-
-        // if the service is abstract, we do not validate everything
-        if (!this.isAbstract) {
-            // if configuration pid is set and different from name, we need 1.2
-            if ( this.configurationPid != null && !this.configurationPid.equals(this.name)
-                 && context.getSpecVersion().ordinal() < SpecVersion.VERSION_1_2.ordinal() ) {
-                this.logError(context.getIssueLog(), "Different configuration pid requires "
-                                + SpecVersion.VERSION_1_2.getName() + " or higher.");
-            }
-            // ensure non-abstract, public class
-            if (!Modifier.isPublic(context.getClassDescription().getDescribedClass().getModifiers())) {
-                this.logError(context.getIssueLog(), "Class must be public: "
-                                + context.getClassDescription().getDescribedClass().getName());
-            }
-            if (Modifier.isAbstract(context.getClassDescription().getDescribedClass().getModifiers())
-                            || context.getClassDescription().getDescribedClass().isInterface()) {
-                this.logError(context.getIssueLog(), "Class must be concrete class (not abstract or interface) : "
-                                + context.getClassDescription().getDescribedClass().getName());
-            }
-
-            // no errors so far, let's continue
-            if (context.getIssueLog().getNumberOfErrors() == currentIssueCount) {
-
-                final String activateName = this.activate == null ? "activate" : this.activate;
-                final String deactivateName = this.deactivate == null ? "deactivate" : this.deactivate;
-
-                // check activate and deactivate methods
-                this.checkLifecycleMethod(context, activateName, true);
-                this.checkLifecycleMethod(context, deactivateName, false);
-
-                if (this.modified != null) {
-                    if ( context.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
-                        this.checkLifecycleMethod(context, this.modified, true);
-                    } else {
-                        this.logError(context.getIssueLog(), "If modified version is specified, spec version must be " +
-                            SpecVersion.VERSION_1_1.name() + " or higher : " + this.modified);
-                    }
-                }
-
-                // ensure public default constructor
-                boolean constructorFound = true;
-                Constructor<?>[] constructors = this.classDescription.getDescribedClass().getDeclaredConstructors();
-                for (int i = 0; constructors != null && i < constructors.length; i++) {
-                    // if public default, succeed
-                    if (Modifier.isPublic(constructors[i].getModifiers())
-                        && (constructors[i].getParameterTypes() == null || constructors[i].getParameterTypes().length == 0)) {
-                        constructorFound = true;
-                        break;
-                    }
-
-                    // non-public/non-default constructor found, must have
-                    // explicit
-                    constructorFound = false;
-                }
-
-                if (!constructorFound) {
-                    this.logError(context.getIssueLog(), "Class must have public default constructor: " + this.classDescription.getDescribedClass().getName());
-                }
-
-                // verify properties
-                for (final Property prop : this.getProperties()) {
-                    prop.validate(context);
-                }
-
-                // verify service
-                boolean isServiceFactory = false;
-                if (this.getService() != null) {
-                    if (this.getService().getInterfaces().size() == 0) {
-                        this.logError(context.getIssueLog(), "Service interface information is missing!");
-                    }
-                    this.getService().validate(context);
-                    isServiceFactory = this.getService().isServiceFactory();
-                }
-
-                // serviceFactory must not be true for immediate of component factory
-                if (isServiceFactory && this.isImmediate() != null && this.isImmediate().booleanValue()
-                    && this.getFactory() != null) {
-                    this.logError(context.getIssueLog(),
-                        "Component must not be a ServiceFactory, if immediate and/or component factory: "
-                        + this.getClassDescription().getDescribedClass().getName());
-                }
-
-                // immediate must not be true for component factory
-                if (this.isImmediate() != null && this.isImmediate().booleanValue() && this.getFactory() != null) {
-                    this.logError(context.getIssueLog(),
-                        "Component must not be immediate if component factory: " + this.getClassDescription().getDescribedClass().getName());
-                }
-            }
-        }
-        if (context.getIssueLog().getNumberOfErrors() == currentIssueCount) {
-            // verify references
-            for (final Reference ref : this.getReferences()) {
-                ref.validate(context, this.isAbstract);
-            }
-        }
-    }
-
-    private static final String TYPE_COMPONENT_CONTEXT = "org.osgi.service.component.ComponentContext";
-    private static final String TYPE_BUNDLE_CONTEXT = "org.osgi.framework.BundleContext";
-    private static final String TYPE_MAP = "java.util.Map";
-    private static final String TYPE_INT = "int";
-    private static final String TYPE_INTEGER = "java.lang.Integer";
-
-    private Method getMethod(final Context ctx, final String name, final String[] sig)
-    throws SCRDescriptorException {
-        Class<?>[] classSig = (sig == null ? null : new Class<?>[sig.length]);
-        if ( sig != null ) {
-            for(int i = 0; i<sig.length; i++) {
-                try {
-                    if ( sig[i].equals("int") ) {
-                        classSig[i] = int.class;
-                    } else {
-                        classSig[i] = ctx.getProject().getClassLoader().loadClass(sig[i]);
-                    }
-                } catch (final ClassNotFoundException e) {
-                    throw new SCRDescriptorException("Unable to load class.", e);
-                }
-            }
-        }
-        try {
-            return ctx.getClassDescription().getDescribedClass().getDeclaredMethod(name, classSig);
-        } catch (final SecurityException e) {
-            // ignore
-        } catch (final NoSuchMethodException e) {
-            // ignore
-        }
-        return null;
-    }
-
-    /**
-     * Check for existence of lifecycle methods.
-     *
-     * @param specVersion
-     *            The spec version
-     * @param javaClass
-     *            The java class to inspect.
-     * @param methodName
-     *            The method name.
-     * @param warnings
-     *            The list of warnings used to add new warnings.
-     */
-    private void checkLifecycleMethod(final Context ctx,
-                                      final String methodName,
-                                      final boolean isActivate)
-    throws SCRDescriptorException {
-        // first candidate is (de)activate(ComponentContext)
-        Method method = this.getMethod(ctx, methodName, new String[] { TYPE_COMPONENT_CONTEXT });
-        if (method == null) {
-            if (ctx.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
-                // second candidate is (de)activate(BundleContext)
-                method = this.getMethod(ctx, methodName, new String[] { TYPE_BUNDLE_CONTEXT });
-                if (method == null) {
-                    // third candidate is (de)activate(Map)
-                    method = this.getMethod(ctx, methodName, new String[] { TYPE_MAP });
-
-                    if (method == null) {
-                        // if this is a deactivate method, we have two
-                        // additional possibilities
-                        // a method with parameter of type int and one of type
-                        // Integer
-                        if (!isActivate) {
-                            method = this.getMethod(ctx, methodName, new String[] { TYPE_INT });
-                            if (method == null) {
-                                method = this.getMethod(ctx, methodName, new String[] { TYPE_INTEGER });
-                            }
-                        }
-                    }
-
-                    if (method == null) {
-                        // fourth candidate is (de)activate with two or three
-                        // arguments (type must be BundleContext, ComponentCtx
-                        // and Map)
-                        // as we have to iterate now and the fifth candidate is
-                        // zero arguments
-                        // we already store this option
-                        Method zeroArgMethod = null;
-                        Method found = method;
-                        final Method[] methods = ctx.getClassDescription().getDescribedClass().getDeclaredMethods();
-                        int i = 0;
-                        while (i < methods.length) {
-                            if (methodName.equals(methods[i].getName())) {
-
-                                if (methods[i].getParameterTypes() == null || methods[i].getParameterTypes().length == 0) {
-                                    zeroArgMethod = methods[i];
-                                } else if (methods[i].getParameterTypes().length >= 2) {
-                                    boolean valid = true;
-                                    for (int m = 0; m < methods[i].getParameterTypes().length; m++) {
-                                        final String type = methods[i].getParameterTypes()[m].getName();
-                                        if (!type.equals(TYPE_BUNDLE_CONTEXT) && !type.equals(TYPE_COMPONENT_CONTEXT)
-                                            && !type.equals(TYPE_MAP)) {
-                                            // if this is deactivate, int and
-                                            // integer are possible as well
-                                            if (isActivate || (!type.equals(TYPE_INT) && !type.equals(TYPE_INTEGER))) {
-                                                valid = false;
-                                            }
-                                        }
-                                    }
-                                    if (valid) {
-                                        if (found == null) {
-                                            found = methods[i];
-                                        } else {
-                                            // print warning
-                                            this.logWarn(ctx.getIssueLog(), "Lifecycle method " + methods[i].getName()
-                                                      + " occurs several times with different matching signature.");
-                                        }
-                                    }
-                                }
-                            }
-                            i++;
-                        }
-                        if (found != null) {
-                            method = found;
-                        } else {
-                            method = zeroArgMethod;
-                        }
-                    }
-                }
-            }
-        }
-        // if no method is found, we check for any method with that name to print some warnings!
-        if (method == null) {
-           final Method[] methods = ctx.getClassDescription().getDescribedClass().getDeclaredMethods();
-            for (int i = 0; i < methods.length; i++) {
-                if (methodName.equals(methods[i].getName())) {
-                    if (methods[i].getParameterTypes() == null || methods[i].getParameterTypes().length != 1) {
-                        this.logWarn(ctx.getIssueLog(), "Lifecycle method " + methods[i].getName() + " has wrong number of arguments");
-                    } else {
-                        this.logWarn(ctx.getIssueLog(),
-                            "Lifecycle method " + methods[i].getName() + " has wrong argument "
-                            + methods[i].getParameterTypes()[0].getName());
-                    }
-                }
-            }
-        }
-
-        // method must be protected for version 1.0
-        if (method != null && specVersion == SpecVersion.VERSION_1_0) {
-            // check protected
-            if (Modifier.isPublic(method.getModifiers())) {
-                this.logWarn(ctx.getIssueLog(), "Lifecycle method " + method.getName() + " should be declared protected");
-            } else if (!Modifier.isProtected(method.getModifiers())) {
-                this.logWarn(ctx.getIssueLog(), "Lifecycle method " + method.getName() +
-                            " has wrong qualifier, public or protected required");
-            }
-        }
-    }
-
-    /**
      * Return the configuration policy.
      */
     public ComponentConfigurationPolicy getConfigurationPolicy() {
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Context.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Context.java
deleted file mode 100644
index 2af92df..0000000
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Context.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.scrplugin.om;
-
-import org.apache.felix.scrplugin.Options;
-import org.apache.felix.scrplugin.Project;
-import org.apache.felix.scrplugin.SpecVersion;
-import org.apache.felix.scrplugin.description.ClassDescription;
-import org.apache.felix.scrplugin.helper.IssueLog;
-
-public class Context {
-
-    private Project project;
-
-    private IssueLog issueLog;
-
-    private SpecVersion specVersion;
-
-    private ClassDescription classDescription;
-
-    private Options options;
-
-    public Project getProject() {
-        return project;
-    }
-
-    public void setProject(Project project) {
-        this.project = project;
-    }
-
-    public IssueLog getIssueLog() {
-        return issueLog;
-    }
-
-    public void setIssueLog(IssueLog issueLog) {
-        this.issueLog = issueLog;
-    }
-
-    public SpecVersion getSpecVersion() {
-        return specVersion;
-    }
-
-    public void setSpecVersion(SpecVersion specVersion) {
-        this.specVersion = specVersion;
-    }
-
-    public ClassDescription getClassDescription() {
-        return classDescription;
-    }
-
-    public void setClassDescription(ClassDescription classDescription) {
-        this.classDescription = classDescription;
-    }
-
-    public Options getOptions() {
-        return options;
-    }
-
-    public void setOptions(Options options) {
-        this.options = options;
-    }
-}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Interface.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Interface.java
index 4fba368..d7930a1 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Interface.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Interface.java
@@ -18,7 +18,6 @@
  */
 package org.apache.felix.scrplugin.om;
 
-import org.apache.felix.scrplugin.SCRDescriptorException;
 import org.apache.felix.scrplugin.annotations.ScannedAnnotation;
 
 /**
@@ -52,25 +51,4 @@
     public void setInterfaceName(final String name) {
         this.interfaceName = name;
     }
-
-    /**
-     * Validate the interface.
-     * If errors occur a message is added to the issues list,
-     * warnings can be added to the warnings list.
-     */
-    public void validate(final Context context) throws SCRDescriptorException {
-        if (context.getClassDescription().getDescribedClass().isInterface()) {
-            this.logError(context.getIssueLog(), "Must be declared in a Java class - not an interface");
-        } else {
-            try {
-                final Class<?> interfaceClass = context.getProject().getClassLoader().loadClass(this.interfaceName);
-                if (!interfaceClass.isAssignableFrom(context.getClassDescription().getDescribedClass())) {
-                    // interface not implemented
-                    this.logError(context.getIssueLog(), "Class must implement provided interface " + this.interfaceName);
-                }
-            } catch (final ClassNotFoundException cnfe) {
-                throw new SCRDescriptorException("Unable to load interface class.", cnfe);
-            }
-        }
-    }
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Property.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Property.java
index c041dea..10ebbf6 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Property.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Property.java
@@ -18,7 +18,6 @@
  */
 package org.apache.felix.scrplugin.om;
 
-import org.apache.felix.scrplugin.SpecVersion;
 import org.apache.felix.scrplugin.annotations.ScannedAnnotation;
 import org.apache.felix.scrplugin.description.PropertyType;
 
@@ -73,26 +72,4 @@
         this.multiValue = values;
         this.value = null;
     }
-
-    /**
-     * Validate the property.
-     * If errors occur a message is added to the issues list,
-     * warnings can be added to the warnings list.
-     */
-    public void validate(final Context context) {
-        if (name == null || name.trim().length() == 0) {
-            this.logError(context.getIssueLog(), "Property name can not be empty.");
-        }
-        if (type != null) {
-            // now check for old and new char
-            if (context.getSpecVersion() == SpecVersion.VERSION_1_0 && type == PropertyType.Character) {
-                type = PropertyType.Char;
-            }
-            if (context.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal()
-                            && type == PropertyType.Char) {
-                type = PropertyType.Character;
-            }
-        }
-        // TODO might want to check value
-    }
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Reference.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Reference.java
index fc0aab7..f099be7 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Reference.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Reference.java
@@ -19,18 +19,12 @@
 package org.apache.felix.scrplugin.om;
 
 import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Map;
 
-import org.apache.felix.scrplugin.SCRDescriptorException;
-import org.apache.felix.scrplugin.SpecVersion;
 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;
-import org.apache.felix.scrplugin.helper.StringUtils;
 
 /**
  * <code>Reference.java</code>...
@@ -154,195 +148,4 @@
     public boolean isLookupStrategy() {
         return this.getStrategy() == ReferenceStrategy.LOOKUP;
     }
-
-    /**
-     * Validate the property.
-     * If errors occur a message is added to the issues list,
-     * warnings can be added to the warnings list.
-     */
-    public void validate(final Context context, final boolean componentIsAbstract)
-    throws SCRDescriptorException {
-        final int currentIssueCount = context.getIssueLog().getNumberOfErrors();
-
-        // validate name
-        if (StringUtils.isEmpty(this.name)) {
-            if (context.getSpecVersion().ordinal() < SpecVersion.VERSION_1_1.ordinal() ) {
-                this.logError(context.getIssueLog(), "Reference has no name");
-            }
-        }
-
-        // validate interface
-        if (StringUtils.isEmpty(this.interfacename)) {
-            this.logError(context.getIssueLog(), "Missing interface name");
-        }
-        try {
-            context.getProject().getClassLoader().loadClass(this.interfacename);
-        } catch (final ClassNotFoundException e) {
-            this.logError(context.getIssueLog(), "Interface class can't be loaded: " + this.interfacename);
-        }
-
-        // validate cardinality
-        if (this.cardinality == null) {
-            this.cardinality = ReferenceCardinality.MANDATORY_UNARY;
-        }
-
-        // validate policy
-        if (this.policy == null) {
-            this.policy = ReferencePolicy.STATIC;
-        }
-
-        // validate policy option
-        if ( this.policyOption == null ) {
-            this.policyOption = ReferencePolicyOption.RELUCTANT;
-        }
-        if ( this.policyOption != ReferencePolicyOption.RELUCTANT ) {
-            if ( context.getSpecVersion().ordinal() < SpecVersion.VERSION_1_2.ordinal() ) {
-                this.logError(context.getIssueLog(), "ReferencePolicyOption " + this.policyOption.name() +
-                                " requires spec version " + SpecVersion.VERSION_1_2.getName() + " or higher.");
-            }
-        }
-        // validate strategy
-        if (this.strategy == null) {
-            this.strategy = ReferenceStrategy.EVENT;
-        }
-
-        // validate bind and unbind methods
-        if (!isLookupStrategy()) {
-            String bindName = this.bind;
-            String unbindName = this.unbind;
-
-            final boolean canGenerate = context.getOptions().isGenerateAccessors() &&
-                            !this.isLookupStrategy() && this.getField() != null
-                            && (this.getCardinality() == ReferenceCardinality.OPTIONAL_UNARY || this.getCardinality() == ReferenceCardinality.MANDATORY_UNARY);
-            if (bindName == null && !canGenerate ) {
-                bindName = "bind";
-            }
-            if (unbindName == null && !canGenerate ) {
-                unbindName = "unbind";
-            }
-
-            if ( bindName != null ) {
-                bindName = this.validateMethod(context, bindName, componentIsAbstract);
-            } else {
-                bindName = "bind" + Character.toUpperCase(this.name.charAt(0)) + this.name.substring(1);
-            }
-            if ( unbindName != null ) {
-                unbindName = this.validateMethod(context, unbindName, componentIsAbstract);
-            } else {
-                unbindName = "unbind" + Character.toUpperCase(this.name.charAt(0)) + this.name.substring(1);
-            }
-
-            if (context.getIssueLog().getNumberOfErrors() == currentIssueCount) {
-                this.bind = bindName;
-                this.unbind = unbindName;
-            }
-        } else {
-            this.bind = null;
-            this.unbind = null;
-        }
-
-        // validate updated method
-        if (this.updated != null) {
-            if (context.getSpecVersion().ordinal() < SpecVersion.VERSION_1_1_FELIX.ordinal()) {
-                this.logError(context.getIssueLog(), "Updated method declaration requires version "
-                                + SpecVersion.VERSION_1_1_FELIX.getName() + ", " + SpecVersion.VERSION_1_2.getName() + " or newer");
-            }
-        }
-
-    }
-
-    private String validateMethod(final Context ctx, final String methodName, final boolean componentIsAbstract)
-    throws SCRDescriptorException {
-        final Method method = this.findMethod(ctx, methodName);
-        if (method == null) {
-            if (!componentIsAbstract) {
-                this.logError(ctx.getIssueLog(),
-                                "Missing method " + methodName + " for reference "
-                                                + (this.getName() == null ? "" : this.getName()));
-            }
-            return null;
-        }
-
-        // method needs to be protected for 1.0
-        if (ctx.getSpecVersion() == SpecVersion.VERSION_1_0) {
-            if (Modifier.isPublic(method.getModifiers())) {
-                this.logWarn(ctx.getIssueLog(), "Method " + method.getName() + " should be declared protected");
-            } else if (!Modifier.isProtected(method.getModifiers())) {
-                this.logError(ctx.getIssueLog(), "Method " + method.getName() + " has wrong qualifier, public or protected required");
-                return null;
-            }
-        }
-        return method.getName();
-    }
-
-    private static final String TYPE_SERVICE_REFERENCE = "org.osgi.framework.ServiceReference";
-
-    private Method getMethod(final Context ctx, final String name, final Class<?>[] sig) {
-        try {
-            return ctx.getClassDescription().getDescribedClass().getDeclaredMethod(name, sig);
-        } catch (final SecurityException e) {
-            // ignore
-        } catch (final NoSuchMethodException e) {
-            // ignore
-        }
-        return null;
-    }
-
-    public Method findMethod(final Context ctx, final String methodName)
-    throws SCRDescriptorException {
-        try {
-            final Class<?>[] sig = new Class<?>[] { ctx.getProject().getClassLoader().loadClass(TYPE_SERVICE_REFERENCE) };
-            final Class<?>[] sig2 = new Class<?>[] {ctx.getProject().getClassLoader().loadClass(this.interfacename) };
-            final Class<?>[] sig3 = new Class<?>[] { ctx.getProject().getClassLoader().loadClass(this.interfacename), Map.class };
-
-            // service interface or ServiceReference first
-            String realMethodName = methodName;
-            Method method = getMethod(ctx, realMethodName, sig);
-            if (method == null) {
-                method = getMethod(ctx, realMethodName, sig2);
-                if (method == null && ctx.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
-                    method = getMethod(ctx, realMethodName, sig3);
-                }
-            }
-
-            // append reference name with service interface and ServiceReference
-            if (method == null) {
-                final String info;
-                if (StringUtils.isEmpty(this.name)) {
-                    final String interfaceName = this.getInterfacename();
-                    final int pos = interfaceName.lastIndexOf('.');
-                    info = interfaceName.substring(pos + 1);
-                } else {
-                    info = this.name;
-                }
-                realMethodName = methodName + Character.toUpperCase(info.charAt(0)) + info.substring(1);
-
-                method = getMethod(ctx, realMethodName, sig);
-            }
-            if (method == null) {
-                method = getMethod(ctx, realMethodName, sig2);
-                if (method == null && ctx.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
-                    method = getMethod(ctx, realMethodName, sig3);
-                }
-            }
-
-            // append type name with service interface and ServiceReference
-            if (method == null) {
-                int lastDot = this.getInterfacename().lastIndexOf('.');
-                realMethodName = methodName + this.getInterfacename().substring(lastDot + 1);
-                method = getMethod(ctx, realMethodName, sig);
-            }
-            if (method == null) {
-                method = getMethod(ctx, realMethodName, sig2);
-                if (method == null && ctx.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
-                    method = getMethod(ctx, realMethodName, sig3);
-                }
-            }
-
-            return method;
-        } catch (final ClassNotFoundException cnfe) {
-            throw new SCRDescriptorException("Unable to load class!", cnfe);
-        }
-    }
-
 }
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Service.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Service.java
index 216d445..0eaf89d 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Service.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/om/Service.java
@@ -22,11 +22,9 @@
 import java.util.Iterator;
 import java.util.List;
 
-import org.apache.felix.scrplugin.SCRDescriptorException;
-
 /**
  * <code>Service</code>
- * 
+ *
  * contains all service information of a component.
  */
 public class Service {
@@ -60,7 +58,7 @@
 
     /**
      * Search for an implemented interface.
-     * 
+     *
      * @param name
      *            The name of the interface.
      * @return The interface if it is implemented by this service or null.
@@ -78,7 +76,7 @@
 
     /**
      * Add an interface to the list of interfaces.
-     * 
+     *
      * @param interf
      *            The interface.
      */
@@ -88,15 +86,4 @@
             this.interfaces.add(interf);
         }
     }
-
-    /**
-     * Validate the service.
-     * If errors occur a message is added to the issues list,
-     * warnings can be added to the warnings list.
-     */
-    public void validate(final Context context) throws SCRDescriptorException {
-        for (final Interface interf : this.getInterfaces()) {
-            interf.validate(context);
-        }
-    }
 }