diff --git a/tools/package/maven-plugin/pom.xml b/tools/package/maven-plugin/pom.xml
index f9016d2..82a688f 100644
--- a/tools/package/maven-plugin/pom.xml
+++ b/tools/package/maven-plugin/pom.xml
@@ -26,7 +26,7 @@
 
     <groupId>org.onosproject</groupId>
     <artifactId>onos-maven-plugin</artifactId>
-    <version>2.1-SNAPSHOT</version>
+    <version>2.1</version>
     <packaging>maven-plugin</packaging>
 
     <description>Maven plugin for packaging ONOS applications or generating
diff --git a/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosCfgMojo.java b/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosCfgMojo.java
index 19628f8..f8ea71c 100644
--- a/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosCfgMojo.java
+++ b/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosCfgMojo.java
@@ -15,10 +15,15 @@
  */
 package org.onosproject.maven;
 
+import com.google.common.collect.Maps;
 import com.thoughtworks.qdox.JavaProjectBuilder;
 import com.thoughtworks.qdox.model.JavaAnnotation;
 import com.thoughtworks.qdox.model.JavaClass;
 import com.thoughtworks.qdox.model.JavaField;
+import com.thoughtworks.qdox.model.expression.Add;
+import com.thoughtworks.qdox.model.expression.AnnotationValue;
+import com.thoughtworks.qdox.model.expression.AnnotationValueList;
+import com.thoughtworks.qdox.model.expression.FieldRef;
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugins.annotations.LifecyclePhase;
@@ -31,6 +36,9 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.jar.JarEntry;
 
 /**
  * Produces ONOS component configuration catalogue resources.
@@ -39,10 +47,6 @@
 @java.lang.SuppressWarnings("squid:S1148")
 public class OnosCfgMojo extends AbstractMojo {
 
-    private static final String COMPONENT = "org.apache.felix.scr.annotations.Component";
-    private static final String PROPERTY = "org.apache.felix.scr.annotations.Property";
-    private static final String SEP = "|";
-
     /**
      * The directory where the generated catalogue file will be put.
      */
@@ -59,84 +63,161 @@
     public void execute() throws MojoExecutionException {
         getLog().info("Generating ONOS component configuration catalogues...");
         try {
-            JavaProjectBuilder builder = new JavaProjectBuilder();
-            builder.addSourceTree(new File(srcDirectory, "src/main/java"));
-            builder.getClasses().forEach(this::processClass);
+            CfgDefGenerator gen = new CfgDefGenerator(dstDirectory, srcDirectory);
+            gen.analyze();
+            gen.generate();
         } catch (Exception e) {
             e.printStackTrace();
-            throw e;
+            throw new MojoExecutionException("Unable to generate property catalog", e);
         }
     }
 
-    private void processClass(JavaClass javaClass) {
-        boolean isComponent = javaClass.getAnnotations().stream()
-                .map(ja -> ja.getType().getName().equals(COMPONENT))
-                .findFirst().isPresent();
-        if (isComponent) {
-            List<String> lines = new ArrayList<>();
-            javaClass.getFields().forEach(field -> processField(lines, javaClass, field));
-            if (!lines.isEmpty()) {
-                writeCatalog(javaClass, lines);
+
+    private static class CfgDefGenerator {
+
+        private static final String COMPONENT = "org.osgi.service.component.annotations.Component";
+        private static final String PROPERTY = "property";
+        private static final String SEP = "|";
+        private static final String UTF_8 = "UTF-8";
+        private static final String JAVA = ".java";
+        private static final String EXT = ".cfgdef";
+        private static final String STRING = "STRING";
+        private static final String NO_DESCRIPTION = "no description provided";
+
+        private final File dstDir;
+        private final JavaProjectBuilder builder;
+
+        private final Map<String, String> constants = Maps.newHashMap();
+
+
+        private CfgDefGenerator(File dstDir, File srcDir) {
+            this.dstDir = dstDir;
+            this.builder = new JavaProjectBuilder();
+            builder.addSourceTree(new File(srcDir, "src/main/java"));
+
+//            Arrays.stream(sourceFilePaths).forEach(filename -> {
+//                try {
+//                    if (filename.endsWith(JAVA))
+//                        builder.addSource(new File(filename));
+//                } catch (ParseException e) {
+//                    // When unable to parse, skip the source; leave it to javac to fail.
+//                } catch (IOException e) {
+//                    throw new IllegalArgumentException("Unable to open file", e);
+//                }
+//            });
+        }
+
+        public void analyze() {
+            builder.getClasses().forEach(this::collectConstants);
+        }
+
+        private void collectConstants(JavaClass javaClass) {
+            javaClass.getFields().stream()
+                    .filter(f -> f.isStatic() && f.isFinal() && !f.isPrivate())
+                    .forEach(f -> constants.put(f.getName(), f.getInitializationExpression()));
+        }
+
+        public void generate() throws IOException {
+            for (JavaClass javaClass : builder.getClasses()) {
+                processClass(javaClass);
             }
         }
-    }
 
-    private void writeCatalog(JavaClass javaClass, List<String> lines) {
-        File dir = new File(dstDirectory, javaClass.getPackageName().replace('.', '/'));
-        dir.mkdirs();
+        private void processClass(JavaClass javaClass) throws IOException {
+            Optional<JavaAnnotation> annotation = javaClass.getAnnotations().stream()
+                    .filter(ja -> ja.getType().getName().equals(COMPONENT))
+                    .findFirst();
+            if (annotation.isPresent()) {
+                AnnotationValue property = annotation.get().getProperty(PROPERTY);
+                List<String> lines = new ArrayList<>();
+                if (property instanceof AnnotationValueList) {
+                    AnnotationValueList list = (AnnotationValueList) property;
+                    list.getValueList().forEach(v -> processProperty(lines, javaClass, v));
+                } else {
+                    processProperty(lines, javaClass, property);
+                }
 
-        File cfgDef = new File(dir, javaClass.getName().replace('.', '/') + ".cfgdef");
-        try (FileWriter fw = new FileWriter(cfgDef);
-             PrintWriter pw = new PrintWriter(fw)) {
-            pw.println("# This file is auto-generated by onos-maven-plugin");
-            lines.forEach(pw::println);
-        } catch (IOException e) {
-            System.err.println("Unable to write catalog for " + javaClass.getName());
-            e.printStackTrace();
-        }
-    }
-
-    private void processField(List<String> lines, JavaClass javaClass, JavaField field) {
-        field.getAnnotations().forEach(ja -> {
-            if (ja.getType().getName().equals(PROPERTY)) {
-                lines.add(expand(javaClass, ja.getNamedParameter("name").toString()) +
-                                  SEP + type(field) +
-                                  SEP + defaultValue(javaClass, field, ja) +
-                                  SEP + description(ja));
+                if (!lines.isEmpty()) {
+                    writeCatalog(javaClass, lines);
+                }
             }
-        });
+        }
+
+        private void processProperty(List<String> lines, JavaClass javaClass,
+                                     AnnotationValue value) {
+            String s = elaborate(value);
+            String[] pex = s.split("=", 2);
+
+            if (pex.length == 2) {
+                String[] rex = pex[0].split(":", 2);
+                String name = rex[0];
+                String type = rex.length == 2 ? rex[1].toUpperCase() : STRING;
+                String def = pex[1];
+                String desc = description(javaClass, name);
+
+                if (desc != null) {
+                    String line = name + SEP + type + SEP + def + SEP + desc + "\n";
+                    lines.add(line);
+                }
+            }
+        }
+
+        // Retrieve description from a comment preceding the field named the same
+        // as the property or
+        // TODO: from an annotated comment.
+        private String description(JavaClass javaClass, String name) {
+            if (name.startsWith("_")) {
+                // Static property - just leave it as is, not for inclusion in the cfg defs
+                return null;
+            }
+            JavaField field = javaClass.getFieldByName(name);
+            if (field != null) {
+                String comment = field.getComment();
+                return comment != null ? comment : NO_DESCRIPTION;
+            }
+            throw new IllegalStateException("cfgdef could not find a variable named " + name + " in " + javaClass.getName());
+        }
+
+        private String elaborate(AnnotationValue value) {
+            if (value instanceof Add) {
+                return elaborate(((Add) value).getLeft()) + elaborate(((Add) value).getRight());
+            } else if (value instanceof FieldRef) {
+                return elaborate((FieldRef) value);
+            } else if (value != null) {
+                return stripped(value.toString());
+            } else {
+                return "";
+            }
+        }
+
+        private String elaborate(FieldRef field) {
+            String name = field.getName();
+            String value = constants.get(name);
+            if (value != null) {
+                return stripped(value);
+            }
+            throw new IllegalStateException("Constant " + name + " cannot be elaborated;" +
+                                                    " value not in the same compilation context");
+        }
+
+        private String stripped(String s) {
+            return s.trim().replaceFirst("^[^\"]*\"", "").replaceFirst("\"$", "");
+        }
+
+        private void writeCatalog(JavaClass javaClass, List<String> lines) {
+            File dir = new File(dstDir, javaClass.getPackageName().replace('.', '/'));
+            dir.mkdirs();
+
+            File cfgDef = new File(dir, javaClass.getName().replace('.', '/') + ".cfgdef");
+            try (FileWriter fw = new FileWriter(cfgDef);
+                 PrintWriter pw = new PrintWriter(fw)) {
+                pw.println("# This file is auto-generated by onos-maven-plugin");
+                lines.forEach(pw::println);
+            } catch (IOException e) {
+                System.err.println("Unable to write catalog for " + javaClass.getName());
+                e.printStackTrace();
+            }
+        }
+
     }
-
-    // TODO: Stuff below is very much hack-ish and should be redone; it works for now though.
-
-    private String description(JavaAnnotation annotation) {
-        String description = (String) annotation.getNamedParameter("label");
-        return description.replaceAll("\" \\+ \"", "")
-                .replaceFirst("^[^\"]*\"", "").replaceFirst("\"$", "");
-    }
-
-    private String type(JavaField field) {
-        String ft = field.getType().getName().toUpperCase();
-        return ft.equals("INT") ? "INTEGER" : ft;
-    }
-
-    private String defaultValue(JavaClass javaClass, JavaField field,
-                                JavaAnnotation annotation) {
-        String ft = field.getType().getName().toLowerCase();
-        String defValueName = ft.equals("boolean") ? "boolValue" :
-                ft.equals("string") ? "value" : ft + "Value";
-        Object dv = annotation.getNamedParameter(defValueName);
-        return dv == null ? "" : expand(javaClass, dv.toString());
-    }
-
-    private String stripQuotes(String string) {
-        return string.trim().replaceFirst("^[^\"]*\"", "").replaceFirst("\"$", "");
-    }
-
-    private String expand(JavaClass javaClass, String value) {
-        JavaField field = javaClass.getFieldByName(value);
-        return field == null ? stripQuotes(value) :
-                stripQuotes(field.getCodeBlock().replaceFirst(".*=", "").replaceFirst(";$", ""));
-    }
-
-}
+}
\ No newline at end of file
