Converting builtin applications to be delivered in a self-contained manner via OAR files.

Change-Id: I5b7c6939aacc263248868fac2e0f69124c5f3609
diff --git a/apps/bgprouter/app.xml b/apps/bgprouter/app.xml
index bd71c6b..f5dde68 100644
--- a/apps/bgprouter/app.xml
+++ b/apps/bgprouter/app.xml
@@ -14,7 +14,11 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<app name="org.onosproject.bgprouter" origin="ON.Lab" version="1.2.0"
-        features="onos-app-bgprouter">
-    <description>BGP router application</description>
+<app name="org.onosproject.bgprouter" origin="ON.Lab" version="${feature.version}"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-app-routing-api/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-app-routing/${project.version}</artifact>
 </app>
diff --git a/apps/bgprouter/features.xml b/apps/bgprouter/features.xml
new file mode 100644
index 0000000..b7825b4
--- /dev/null
+++ b/apps/bgprouter/features.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ Copyright 2015 Open Networking Laboratory
+  ~
+  ~ Licensed 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.
+  -->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${feature.version}">
+    <repository>mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features</repository>
+    <feature name="${project.artifactId}" version="${feature.version}"
+             description="${project.description}">
+        <feature>onos-api</feature>
+        <feature>onos-app-proxyarp</feature>
+        <feature>onos-app-config</feature>
+        <bundle>mvn:${project.groupId}/onos-app-bgprouter/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-app-routing-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-app-routing/${project.version}</bundle>
+    </feature>
+</features>
diff --git a/apps/config/app.xml b/apps/config/app.xml
index ab4af9e..0829867 100644
--- a/apps/config/app.xml
+++ b/apps/config/app.xml
@@ -14,7 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<app name="org.onosproject.config" origin="ON.Lab" version="1.2.0"
-        features="onos-app-config">
-    <description>Network configuration application</description>
+<app name="org.onosproject.config" origin="ON.Lab" version="${feature.version}"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
 </app>
diff --git a/apps/config/pom.xml b/apps/config/pom.xml
index 890bb09..f42747e 100644
--- a/apps/config/pom.xml
+++ b/apps/config/pom.xml
@@ -29,7 +29,7 @@
     <artifactId>onos-app-config</artifactId>
     <packaging>bundle</packaging>
 
-    <description>ONOS simple network configuration reader</description>
+    <description>Network configuration application</description>
 
     <dependencies>
       <dependency>
diff --git a/apps/fwd/app.xml b/apps/fwd/app.xml
index e6f022e..5facda1 100644
--- a/apps/fwd/app.xml
+++ b/apps/fwd/app.xml
@@ -14,7 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<app name="org.onosproject.fwd" origin="ON.Lab" version="1.2.0"
-        features="onos-app-fwd">
-    <description>Reactive forwarding application using flow subsystem</description>
+<app name="org.onosproject.fwd" origin="ON.Lab" version="${feature.version}"
+        featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+        features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
 </app>
diff --git a/apps/fwd/pom.xml b/apps/fwd/pom.xml
index d4c92e7..a3b1960 100644
--- a/apps/fwd/pom.xml
+++ b/apps/fwd/pom.xml
@@ -29,7 +29,7 @@
     <artifactId>onos-app-fwd</artifactId>
     <packaging>bundle</packaging>
 
-    <description>ONOS simple reactive forwarding app</description>
+    <description>Reactive forwarding application using flow subsystem</description>
 
     <dependencies>
         <dependency>
diff --git a/apps/metrics/app.xml b/apps/metrics/app.xml
index 53375b9..94bc602 100644
--- a/apps/metrics/app.xml
+++ b/apps/metrics/app.xml
@@ -14,7 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<app name="org.onosproject.metrics" origin="ON.Lab" version="1.2.0"
-        features="onos-app-metrics">
-    <description>Performance metrics collection</description>
+<app name="org.onosproject.metrics" origin="ON.Lab" version="${feature.version}"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
 </app>
diff --git a/apps/metrics/intent/pom.xml b/apps/metrics/intent/pom.xml
deleted file mode 100644
index ddb86ea..0000000
--- a/apps/metrics/intent/pom.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ Copyright 2014 Open Networking Laboratory
-  ~
-  ~ Licensed 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.
-  -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.onosproject</groupId>
-    <artifactId>onos-app-metrics</artifactId>
-    <version>1.2.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-
-  <artifactId>onos-app-metrics-intent</artifactId>
-  <packaging>bundle</packaging>
-
-  <description>ONOS intent metrics application</description>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.onosproject</groupId>
-      <artifactId>onos-cli</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.karaf.shell</groupId>
-      <artifactId>org.apache.karaf.shell.console</artifactId>
-    </dependency>
-  </dependencies>
-
-</project>
diff --git a/apps/metrics/intent/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/metrics/intent/src/main/resources/OSGI-INF/blueprint/shell-config.xml
deleted file mode 100644
index d52ff5a..0000000
--- a/apps/metrics/intent/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-  ~ Copyright 2014 Open Networking Laboratory
-  ~
-  ~ Licensed 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.
-  -->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
-
-  <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
-    <command>
-      <action class="org.onosproject.metrics.intent.cli.IntentEventsListCommand"/>
-    </command>
-    <command>
-      <action class="org.onosproject.metrics.intent.cli.IntentEventsMetricsCommand"/>
-    </command>
-  </command-bundle>
-
-</blueprint>
diff --git a/apps/metrics/pom.xml b/apps/metrics/pom.xml
index 5e8d9ea..2cac15c 100644
--- a/apps/metrics/pom.xml
+++ b/apps/metrics/pom.xml
@@ -17,40 +17,49 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
+    <modelVersion>4.0.0</modelVersion>
 
-  <parent>
-    <groupId>org.onosproject</groupId>
-    <artifactId>onos-apps</artifactId>
-    <version>1.2.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-apps</artifactId>
+        <version>1.2.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
 
-  <artifactId>onos-app-metrics</artifactId>
-  <packaging>pom</packaging>
+    <artifactId>onos-app-metrics</artifactId>
+    <packaging>bundle</packaging>
 
-  <description>ONOS metrics applications</description>
+    <description>Performance metrics collection</description>
 
-  <modules>
-    <module>intent</module>
-    <module>topology</module>
-  </modules>
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-misc</artifactId>
+        </dependency>
 
-  <dependencies>
-    <dependency>
-      <groupId>org.onosproject</groupId>
-      <artifactId>onlab-misc</artifactId>
-    </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cli</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
 
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-databind</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-annotations</artifactId>
-    </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.console</artifactId>
+        </dependency>
 
-  </dependencies>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+        </dependency>
+    </dependencies>
 
 </project>
diff --git a/apps/metrics/intent/src/main/java/org/onosproject/metrics/intent/IntentMetrics.java b/apps/metrics/src/main/java/org/onosproject/metrics/intent/IntentMetrics.java
similarity index 100%
rename from apps/metrics/intent/src/main/java/org/onosproject/metrics/intent/IntentMetrics.java
rename to apps/metrics/src/main/java/org/onosproject/metrics/intent/IntentMetrics.java
diff --git a/apps/metrics/intent/src/main/java/org/onosproject/metrics/intent/IntentMetricsService.java b/apps/metrics/src/main/java/org/onosproject/metrics/intent/IntentMetricsService.java
similarity index 100%
rename from apps/metrics/intent/src/main/java/org/onosproject/metrics/intent/IntentMetricsService.java
rename to apps/metrics/src/main/java/org/onosproject/metrics/intent/IntentMetricsService.java
diff --git a/apps/metrics/intent/src/main/java/org/onosproject/metrics/intent/cli/IntentEventsListCommand.java b/apps/metrics/src/main/java/org/onosproject/metrics/intent/cli/IntentEventsListCommand.java
similarity index 100%
rename from apps/metrics/intent/src/main/java/org/onosproject/metrics/intent/cli/IntentEventsListCommand.java
rename to apps/metrics/src/main/java/org/onosproject/metrics/intent/cli/IntentEventsListCommand.java
diff --git a/apps/metrics/intent/src/main/java/org/onosproject/metrics/intent/cli/IntentEventsMetricsCommand.java b/apps/metrics/src/main/java/org/onosproject/metrics/intent/cli/IntentEventsMetricsCommand.java
similarity index 100%
rename from apps/metrics/intent/src/main/java/org/onosproject/metrics/intent/cli/IntentEventsMetricsCommand.java
rename to apps/metrics/src/main/java/org/onosproject/metrics/intent/cli/IntentEventsMetricsCommand.java
diff --git a/apps/metrics/intent/src/main/java/org/onosproject/metrics/intent/cli/package-info.java b/apps/metrics/src/main/java/org/onosproject/metrics/intent/cli/package-info.java
similarity index 100%
rename from apps/metrics/intent/src/main/java/org/onosproject/metrics/intent/cli/package-info.java
rename to apps/metrics/src/main/java/org/onosproject/metrics/intent/cli/package-info.java
diff --git a/apps/metrics/intent/src/main/java/org/onosproject/metrics/intent/package-info.java b/apps/metrics/src/main/java/org/onosproject/metrics/intent/package-info.java
similarity index 100%
rename from apps/metrics/intent/src/main/java/org/onosproject/metrics/intent/package-info.java
rename to apps/metrics/src/main/java/org/onosproject/metrics/intent/package-info.java
diff --git a/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/TopologyMetrics.java b/apps/metrics/src/main/java/org/onosproject/metrics/topology/TopologyMetrics.java
similarity index 100%
rename from apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/TopologyMetrics.java
rename to apps/metrics/src/main/java/org/onosproject/metrics/topology/TopologyMetrics.java
diff --git a/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/TopologyMetricsService.java b/apps/metrics/src/main/java/org/onosproject/metrics/topology/TopologyMetricsService.java
similarity index 100%
rename from apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/TopologyMetricsService.java
rename to apps/metrics/src/main/java/org/onosproject/metrics/topology/TopologyMetricsService.java
diff --git a/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/cli/TopologyEventsListCommand.java b/apps/metrics/src/main/java/org/onosproject/metrics/topology/cli/TopologyEventsListCommand.java
similarity index 100%
rename from apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/cli/TopologyEventsListCommand.java
rename to apps/metrics/src/main/java/org/onosproject/metrics/topology/cli/TopologyEventsListCommand.java
diff --git a/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/cli/TopologyEventsMetricsCommand.java b/apps/metrics/src/main/java/org/onosproject/metrics/topology/cli/TopologyEventsMetricsCommand.java
similarity index 100%
rename from apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/cli/TopologyEventsMetricsCommand.java
rename to apps/metrics/src/main/java/org/onosproject/metrics/topology/cli/TopologyEventsMetricsCommand.java
diff --git a/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/cli/package-info.java b/apps/metrics/src/main/java/org/onosproject/metrics/topology/cli/package-info.java
similarity index 100%
rename from apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/cli/package-info.java
rename to apps/metrics/src/main/java/org/onosproject/metrics/topology/cli/package-info.java
diff --git a/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/package-info.java b/apps/metrics/src/main/java/org/onosproject/metrics/topology/package-info.java
similarity index 100%
rename from apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/package-info.java
rename to apps/metrics/src/main/java/org/onosproject/metrics/topology/package-info.java
diff --git a/apps/metrics/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/metrics/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..c2d8241
--- /dev/null
+++ b/apps/metrics/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,32 @@
+<!--
+  ~ Copyright 2014 Open Networking Laboratory
+  ~
+  ~ Licensed 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.
+  -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.metrics.intent.cli.IntentEventsListCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.metrics.intent.cli.IntentEventsMetricsCommand"/>
+        </command>
+
+        <command>
+            <action class="org.onosproject.metrics.topology.cli.TopologyEventsListCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.metrics.topology.cli.TopologyEventsMetricsCommand"/>
+        </command>
+    </command-bundle>
+</blueprint>
diff --git a/apps/metrics/topology/pom.xml b/apps/metrics/topology/pom.xml
deleted file mode 100644
index b71656d..0000000
--- a/apps/metrics/topology/pom.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ Copyright 2014 Open Networking Laboratory
-  ~
-  ~ Licensed 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.
-  -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.onosproject</groupId>
-    <artifactId>onos-app-metrics</artifactId>
-    <version>1.2.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-
-  <artifactId>onos-app-metrics-topology</artifactId>
-  <packaging>bundle</packaging>
-
-  <description>ONOS topology metrics application</description>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.onosproject</groupId>
-      <artifactId>onos-cli</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.karaf.shell</groupId>
-      <artifactId>org.apache.karaf.shell.console</artifactId>
-    </dependency>
-  </dependencies>
-
-</project>
diff --git a/apps/metrics/topology/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/metrics/topology/src/main/resources/OSGI-INF/blueprint/shell-config.xml
deleted file mode 100644
index 90ea719..0000000
--- a/apps/metrics/topology/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-  ~ Copyright 2014 Open Networking Laboratory
-  ~
-  ~ Licensed 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.
-  -->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
-
-  <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
-    <command>
-      <action class="org.onosproject.metrics.topology.cli.TopologyEventsListCommand"/>
-    </command>
-    <command>
-      <action class="org.onosproject.metrics.topology.cli.TopologyEventsMetricsCommand"/>
-    </command>
-  </command-bundle>
-
-</blueprint>
diff --git a/apps/mobility/app.xml b/apps/mobility/app.xml
index 4cbc1be..2462ea4 100644
--- a/apps/mobility/app.xml
+++ b/apps/mobility/app.xml
@@ -14,7 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<app name="org.onosproject.mobility" origin="ON.Lab" version="1.2.0"
-        features="onos-app-mobility">
-    <description>Host mobility application</description>
+<app name="org.onosproject.mobility" origin="ON.Lab" version="${feature.version}"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
 </app>
diff --git a/apps/mobility/pom.xml b/apps/mobility/pom.xml
index 80c51e1..034d3ee 100644
--- a/apps/mobility/pom.xml
+++ b/apps/mobility/pom.xml
@@ -29,7 +29,7 @@
     <artifactId>onos-app-mobility</artifactId>
     <packaging>bundle</packaging>
 
-    <description>ONOS simple Mobility app</description>
+    <description>Host mobility application</description>
 
     <dependencies>
       <dependency>
diff --git a/apps/optical/app.xml b/apps/optical/app.xml
index f12f840..7ff588b 100644
--- a/apps/optical/app.xml
+++ b/apps/optical/app.xml
@@ -14,7 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<app name="org.onosproject.optical" origin="ON.Lab" version="1.2.0"
-        features="onos-app-optical">
-    <description>Packet/Optical use-case application</description>
+<app name="org.onosproject.optical" origin="ON.Lab" version="${feature.version}"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
 </app>
diff --git a/apps/optical/pom.xml b/apps/optical/pom.xml
index f4f1e68..6e38bc8 100644
--- a/apps/optical/pom.xml
+++ b/apps/optical/pom.xml
@@ -29,7 +29,7 @@
     <artifactId>onos-app-optical</artifactId>
     <packaging>bundle</packaging>
 
-    <description>ONOS application for packet/optical deployments</description>
+    <description>Packet/Optical use-case application</description>
 
     <dependencies>
 
diff --git a/apps/proxyarp/app.xml b/apps/proxyarp/app.xml
index 54c2fd8..0459388 100644
--- a/apps/proxyarp/app.xml
+++ b/apps/proxyarp/app.xml
@@ -14,7 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<app name="org.onosproject.proxyarp" origin="ON.Lab" version="1.2.0"
-        features="onos-app-proxyarp">
-    <description>Proxy ARP/NDP application</description>
+<app name="org.onosproject.proxyarp" origin="ON.Lab" version="${feature.version}"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
 </app>
diff --git a/apps/proxyarp/pom.xml b/apps/proxyarp/pom.xml
index ca30c3e..85429aa 100644
--- a/apps/proxyarp/pom.xml
+++ b/apps/proxyarp/pom.xml
@@ -29,7 +29,7 @@
     <artifactId>onos-app-proxyarp</artifactId>
     <packaging>bundle</packaging>
 
-    <description>ONOS simple proxy arp module</description>
+    <description>Proxy ARP/NDP application</description>
 
     <dependencies>
         <dependency>
diff --git a/apps/reactive-routing/app.xml b/apps/reactive-routing/app.xml
index 2c45141..b6b7e2d 100644
--- a/apps/reactive-routing/app.xml
+++ b/apps/reactive-routing/app.xml
@@ -14,7 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<app name="org.onosproject.reactive.routing" origin="ON.Lab" version="1.2.0"
-        features="onos-app-reactive-routing">
-    <description> ONOS SDN/IP reactive routing </description>
+<app name="org.onosproject.routing" origin="ON.Lab" version="${feature.version}"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
 </app>
\ No newline at end of file
diff --git a/apps/reactive-routing/pom.xml b/apps/reactive-routing/pom.xml
index a5059ca..dc6ef28 100644
--- a/apps/reactive-routing/pom.xml
+++ b/apps/reactive-routing/pom.xml
@@ -14,38 +14,34 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
 
-  <artifactId>onos-app-reactive-routing</artifactId>
-  <packaging>bundle</packaging>
-  <description> SDN-IP reactive routing </description>
+    <artifactId>onos-app-reactive-routing</artifactId>
+    <packaging>bundle</packaging>
+    <description>SDN-IP reactive routing application</description>
 
-  <parent>
-    <groupId>org.onosproject</groupId>
-    <artifactId>onos-apps</artifactId>
-    <version>1.2.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-apps</artifactId>
+        <version>1.2.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
 
-  <dependencies>
-    <dependency>
-      <groupId>org.onosproject</groupId>
-      <artifactId>onos-app-routing-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-routing-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
 
-    <dependency>
-      <groupId>org.onosproject</groupId>
-      <artifactId>onos-app-routing</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-
-    <dependency>
-      <groupId>org.onosproject</groupId>
-      <artifactId>onos-api</artifactId>
-    </dependency>
-  </dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-routing</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/apps/sdnip/app.xml b/apps/sdnip/app.xml
index 0e9627f..e5c6f42 100644
--- a/apps/sdnip/app.xml
+++ b/apps/sdnip/app.xml
@@ -14,7 +14,11 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<app name="org.onosproject.sdnip" origin="ON.Lab" version="1.2.0"
-        features="onos-app-sdnip">
-    <description>SDN/IP use-case application</description>
+<app name="org.onosproject.sdnip" origin="ON.Lab" version="${feature.version}"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-app-routing-api/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-app-routing/${project.version}</artifact>
 </app>
diff --git a/apps/sdnip/features.xml b/apps/sdnip/features.xml
new file mode 100644
index 0000000..2ddec48
--- /dev/null
+++ b/apps/sdnip/features.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ Copyright 2015 Open Networking Laboratory
+  ~
+  ~ Licensed 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.
+  -->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${feature.version}">
+    <repository>mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features</repository>
+    <feature name="onos-app-sdnip" version="${feature.version}"
+             description="${project.description}">
+        <feature>onos-api</feature>
+        <feature>onos-app-proxyarp</feature>
+        <feature>onos-app-config</feature>
+        <bundle>mvn:${project.groupId}/onos-app-sdnip/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-app-bgprouter/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-app-routing-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-app-routing/${project.version}</bundle>
+    </feature>
+</features>
diff --git a/apps/sdnip/pom.xml b/apps/sdnip/pom.xml
index 78def10..bd3f323 100644
--- a/apps/sdnip/pom.xml
+++ b/apps/sdnip/pom.xml
@@ -17,78 +17,78 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
+    <modelVersion>4.0.0</modelVersion>
 
-  <parent>
-    <groupId>org.onosproject</groupId>
-    <artifactId>onos-apps</artifactId>
-    <version>1.2.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-apps</artifactId>
+        <version>1.2.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
 
-  <artifactId>onos-app-sdnip</artifactId>
-  <packaging>bundle</packaging>
+    <artifactId>onos-app-sdnip</artifactId>
+    <packaging>bundle</packaging>
 
-  <description>SDN-IP peering application</description>
+    <description>SDN-IP peering application</description>
 
-  <dependencies>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
+    <dependencies>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
 
-    <dependency>
-      <groupId>org.onosproject</groupId>
-      <artifactId>onlab-misc</artifactId>
-    </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-misc</artifactId>
+        </dependency>
 
-    <dependency>
-      <groupId>org.onosproject</groupId>
-      <artifactId>onlab-junit</artifactId>
-      <scope>test</scope>
-    </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-junit</artifactId>
+            <scope>test</scope>
+        </dependency>
 
-    <dependency>
-      <groupId>org.onosproject</groupId>
-      <artifactId>onos-api</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-      <classifier>tests</classifier>
-    </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+            <classifier>tests</classifier>
+        </dependency>
 
-    <dependency>
-      <groupId>org.onosproject</groupId>
-      <artifactId>onos-app-routing-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-routing</artifactId>
+            <version>${project.version}</version>
+        </dependency>
 
-    <dependency>
-      <groupId>org.onosproject</groupId>
-      <artifactId>onos-cli</artifactId>
-      <version>${project.version}</version>
-    </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cli</artifactId>
+            <version>${project.version}</version>
+        </dependency>
 
-    <dependency>
-      <groupId>org.onosproject</groupId>
-      <artifactId>onos-app-config</artifactId>
-      <version>${project.version}</version>
-    </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
 
-    <dependency>
-      <groupId>org.apache.karaf.shell</groupId>
-      <artifactId>org.apache.karaf.shell.console</artifactId>
-    </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.console</artifactId>
+        </dependency>
 
-    <dependency>
-        <groupId>org.osgi</groupId>
-        <artifactId>org.osgi.core</artifactId>
-    </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
 
-    <dependency>
-      <groupId>org.easymock</groupId>
-      <artifactId>easymock</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
 
 </project>
diff --git a/apps/test/intent-perf/src/assembly/app.xml b/apps/segmentrouting/app.xml
similarity index 64%
copy from apps/test/intent-perf/src/assembly/app.xml
copy to apps/segmentrouting/app.xml
index c20888b..90246c1 100644
--- a/apps/test/intent-perf/src/assembly/app.xml
+++ b/apps/segmentrouting/app.xml
@@ -14,7 +14,10 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<app name="org.onosproject.intentperf" origin="ON.Lab" version="1.2.0"
-     features="onos-app-intent-perf">
-    <description>Intent performance test application</description>
-</app>
\ No newline at end of file
+<app name="org.onosproject.segmentrouting" origin="ON.Lab" version="${feature.version}"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
+</app>
+
diff --git a/apps/segmentrouting/pom.xml b/apps/segmentrouting/pom.xml
index 3e541f0..fa54f26 100644
--- a/apps/segmentrouting/pom.xml
+++ b/apps/segmentrouting/pom.xml
@@ -13,26 +13,21 @@
   ~ 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.

-  --><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

+  -->

+<project xmlns="http://maven.apache.org/POM/4.0.0"

+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

     <modelVersion>4.0.0</modelVersion>

     <parent>

-    <artifactId>onos-apps</artifactId>

-    <groupId>org.onosproject</groupId>

-    <version>1.2.0-SNAPSHOT</version>

-  </parent>

+        <artifactId>onos-apps</artifactId>

+        <groupId>org.onosproject</groupId>

+        <version>1.2.0-SNAPSHOT</version>

+        <relativePath>../pom.xml</relativePath>

+    </parent>

 

     <artifactId>onos-app-segmentrouting</artifactId>

     <packaging>bundle</packaging>

 

-    <description>ONOS OSGi bundle archetype</description>

-    <url>http://onosproject.org</url>

-

-    <dependencies>

-        <dependency>

-            <groupId>org.onosproject</groupId>

-            <artifactId>onos-app-grouphandler</artifactId>

-            <version>1.2.0-SNAPSHOT</version>

-        </dependency>

-    </dependencies>

+    <description>Segment routing application</description>

 

 </project>

diff --git a/apps/test/demo/app.xml b/apps/test/demo/app.xml
index 0318f9c..a7c59fb 100644
--- a/apps/test/demo/app.xml
+++ b/apps/test/demo/app.xml
@@ -14,7 +14,10 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<app name="org.onosproject.demo" origin="ON.Lab" version="1.2.0"
-        features="onos-app-demo">
-    <description>Flow throughput test application</description>
+<app name="org.onosproject.demo" origin="ON.Lab" version="${feature.version}"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
 </app>
+
diff --git a/apps/test/demo/pom.xml b/apps/test/demo/pom.xml
index adac250..70c0306 100644
--- a/apps/test/demo/pom.xml
+++ b/apps/test/demo/pom.xml
@@ -29,7 +29,7 @@
     <artifactId>onos-app-demo</artifactId>
     <packaging>bundle</packaging>
 
-    <description>ONOS demo app bundle</description>
+    <description>Flow throughput test application</description>
 
     <properties>
         <web.context>/onos/demo</web.context>
diff --git a/apps/test/election/app.xml b/apps/test/election/app.xml
index a907d33..9fa94e9 100644
--- a/apps/test/election/app.xml
+++ b/apps/test/election/app.xml
@@ -14,7 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<app name="org.onosproject.election" origin="ON.Lab" version="1.2.0"
-        features="onos-app-election">
-    <description>Master election test application</description>
+<app name="org.onosproject.election" origin="ON.Lab" version="${feature.version}"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
 </app>
diff --git a/apps/test/election/pom.xml b/apps/test/election/pom.xml
index f6027a0..687beb7 100644
--- a/apps/test/election/pom.xml
+++ b/apps/test/election/pom.xml
@@ -30,7 +30,7 @@
     <artifactId>onos-app-election</artifactId>
     <packaging>bundle</packaging>
 
-    <description>ONOS app leadership election test</description>
+    <description>Master election test application</description>
 
     <dependencies>
 
diff --git a/apps/test/intent-perf/src/assembly/app.xml b/apps/test/intent-perf/app.xml
similarity index 70%
rename from apps/test/intent-perf/src/assembly/app.xml
rename to apps/test/intent-perf/app.xml
index c20888b..8e7438b 100644
--- a/apps/test/intent-perf/src/assembly/app.xml
+++ b/apps/test/intent-perf/app.xml
@@ -14,7 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<app name="org.onosproject.intentperf" origin="ON.Lab" version="1.2.0"
-     features="onos-app-intent-perf">
-    <description>Intent performance test application</description>
-</app>
\ No newline at end of file
+<app name="org.onosproject.intentperf" origin="ON.Lab" version="${feature.version}"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
+</app>
diff --git a/apps/test/intent-perf/pom.xml b/apps/test/intent-perf/pom.xml
index f56ee46..c5be5aa 100644
--- a/apps/test/intent-perf/pom.xml
+++ b/apps/test/intent-perf/pom.xml
@@ -29,15 +29,10 @@
     <artifactId>onos-app-intent-perf</artifactId>
     <packaging>bundle</packaging>
 
-    <description>ONOS intent perf app bundle</description>
+    <description>Intent performance test application</description>
 
     <dependencies>
         <dependency>
-            <groupId>org.apache.karaf.shell</groupId>
-            <artifactId>org.apache.karaf.shell.console</artifactId>
-        </dependency>
-
-        <dependency>
             <groupId>org.onosproject</groupId>
             <artifactId>onos-cli</artifactId>
             <version>${project.version}</version>
@@ -46,6 +41,10 @@
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.compendium</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.console</artifactId>
+        </dependency>
         <!-- Required for javadoc generation -->
         <dependency>
            <groupId>org.osgi</groupId>
@@ -53,24 +52,4 @@
         </dependency>
     </dependencies>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-assembly-plugin</artifactId>
-                <version>2.5.3</version>
-                <configuration>
-                    <descriptor>src/assembly/bin.xml</descriptor>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>single</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
 </project>
diff --git a/apps/test/intent-perf/src/assembly/bin.xml b/apps/test/intent-perf/src/assembly/bin.xml
deleted file mode 100644
index b92fa72..0000000
--- a/apps/test/intent-perf/src/assembly/bin.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ Copyright 2015 Open Networking Laboratory
-  ~
-  ~ Licensed 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.
-  -->
-<assembly
-        xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
-        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
-    <formats>
-        <format>zip</format>
-    </formats>
-    <id>onos</id>
-    <includeBaseDirectory>false</includeBaseDirectory>
-    <files>
-        <file>
-            <source>src/assembly/app.xml</source>
-            <destName>app.xml</destName>
-        </file>
-        <file>
-            <source>target/${project.artifactId}-${project.version}.jar</source>
-            <destName>m2/org/onosproject/${project.artifactId}/${project.version}/${project.artifactId}-${project.version}.jar</destName>
-        </file>
-    </files>
-</assembly>
\ No newline at end of file
diff --git a/cli/src/main/java/org/onosproject/cli/AbstractShellCommand.java b/cli/src/main/java/org/onosproject/cli/AbstractShellCommand.java
index ee3c5e8..4dd767b 100644
--- a/cli/src/main/java/org/onosproject/cli/AbstractShellCommand.java
+++ b/cli/src/main/java/org/onosproject/cli/AbstractShellCommand.java
@@ -18,17 +18,17 @@
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.apache.karaf.shell.commands.Option;
-import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.console.AbstractAction;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.osgi.ServiceNotFoundException;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.net.Annotations;
-import org.onlab.osgi.DefaultServiceDirectory;
-import org.onlab.osgi.ServiceNotFoundException;
 
 /**
  * Base abstraction of Karaf shell commands.
  */
-public abstract class AbstractShellCommand extends OsgiCommandSupport {
+public abstract class AbstractShellCommand extends AbstractAction {
 
     @Option(name = "-j", aliases = "--json", description = "Output JSON",
             required = false, multiValued = false)
diff --git a/cli/src/main/java/org/onosproject/cli/app/ApplicationCommand.java b/cli/src/main/java/org/onosproject/cli/app/ApplicationCommand.java
index 68a1957..9d40c66 100644
--- a/cli/src/main/java/org/onosproject/cli/app/ApplicationCommand.java
+++ b/cli/src/main/java/org/onosproject/cli/app/ApplicationCommand.java
@@ -21,6 +21,9 @@
 import org.onosproject.cli.AbstractShellCommand;
 import org.onosproject.core.ApplicationId;
 
+import java.io.IOException;
+import java.net.URL;
+
 /**
  * Manages application inventory.
  */
@@ -34,11 +37,11 @@
     static final String DEACTIVATE = "deactivate";
 
     @Argument(index = 0, name = "command",
-            description = "Command name (activate|deactivate|uninstall)",
+            description = "Command name (install|activate|deactivate|uninstall)",
             required = true, multiValued = false)
     String command = null;
 
-    @Argument(index = 1, name = "names", description = "Application name(s)",
+    @Argument(index = 1, name = "names", description = "Application name(s) or URL(s)",
             required = true, multiValued = true)
     String[] names = null;
 
@@ -46,27 +49,55 @@
     protected void execute() {
         ApplicationAdminService service = get(ApplicationAdminService.class);
         if (command.equals(INSTALL)) {
-            print("Not supported via CLI yet.");
+            for (String name : names) {
+                if (!installApp(service, name)) {
+                    return;
+                }
+            }
 
         } else {
             for (String name : names) {
-                ApplicationId appId = service.getId(name);
-                if (appId == null) {
-                    print("No such application: %s", name);
+                if (!manageApp(service, name)) {
                     return;
                 }
-
-                if (command.equals(UNINSTALL)) {
-                    service.uninstall(appId);
-                } else if (command.equals(ACTIVATE)) {
-                    service.activate(appId);
-                } else if (command.equals(DEACTIVATE)) {
-                    service.deactivate(appId);
-                } else {
-                    print("Unsupported command: %s", command);
-                }
             }
         }
     }
 
+    // Installs the application from input of the specified URL
+    private boolean installApp(ApplicationAdminService service, String url) {
+        try {
+            if (url.equals("-")) {
+                service.install(System.in);
+            } else {
+                service.install(new URL(url).openStream());
+            }
+        } catch (IOException e) {
+            error("Unable to get URL: %s", url);
+            return false;
+        }
+        return true;
+    }
+
+    // Manages the specified application.
+    private boolean manageApp(ApplicationAdminService service, String name) {
+        ApplicationId appId = service.getId(name);
+        if (appId == null) {
+            print("No such application: %s", name);
+            return false;
+        }
+
+        if (command.equals(UNINSTALL)) {
+            service.uninstall(appId);
+        } else if (command.equals(ACTIVATE)) {
+            service.activate(appId);
+        } else if (command.equals(DEACTIVATE)) {
+            service.deactivate(appId);
+        } else {
+            print("Unsupported command: %s", command);
+            return false;
+        }
+        return true;
+    }
+
 }
diff --git a/cli/src/main/java/org/onosproject/cli/app/ApplicationNameCompleter.java b/cli/src/main/java/org/onosproject/cli/app/ApplicationNameCompleter.java
index 1479b9d..1746169 100644
--- a/cli/src/main/java/org/onosproject/cli/app/ApplicationNameCompleter.java
+++ b/cli/src/main/java/org/onosproject/cli/app/ApplicationNameCompleter.java
@@ -15,7 +15,6 @@
  */
 package org.onosproject.cli.app;
 
-import com.google.common.collect.Sets;
 import org.apache.karaf.shell.console.completer.ArgumentCompleter;
 import org.apache.karaf.shell.console.completer.StringsCompleter;
 import org.onosproject.app.ApplicationService;
@@ -23,11 +22,8 @@
 import org.onosproject.cli.AbstractCompleter;
 import org.onosproject.core.Application;
 
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
 import java.util.SortedSet;
 
 import static org.onosproject.app.ApplicationState.ACTIVE;
@@ -48,13 +44,14 @@
         String cmd = list.getArguments()[1];
 
         // Grab apps already on the command (to prevent tab-completed duplicates)
-        final Set previousApps;
-        if (list.getArguments().length > 2) {
-            previousApps = Sets.newHashSet(
-                    Arrays.copyOfRange(list.getArguments(), 2, list.getArguments().length));
-        } else {
-            previousApps = Collections.emptySet();
-        }
+        // FIXME: This does not work.
+//        final Set previousApps;
+//        if (list.getArguments().length > 2) {
+//            previousApps = Sets.newHashSet(
+//                    Arrays.copyOfRange(list.getArguments(), 2, list.getArguments().length));
+//        } else {
+//            previousApps = Collections.emptySet();
+//        }
 
         // Fetch our service and feed it's offerings to the string completer
         ApplicationService service = get(ApplicationService.class);
@@ -63,9 +60,9 @@
         while (it.hasNext()) {
             Application app = it.next();
             ApplicationState state = service.getState(app.id());
-            if (previousApps.contains(app.id().name())) {
-                continue;
-            }
+//            if (previousApps.contains(app.id().name())) {
+//                continue;
+//            }
             if (cmd.equals("uninstall") ||
                     (cmd.equals("activate") && state == INSTALLED) ||
                     (cmd.equals("deactivate") && state == ACTIVE)) {
diff --git a/core/common/src/main/java/org/onosproject/common/app/ApplicationArchive.java b/core/common/src/main/java/org/onosproject/common/app/ApplicationArchive.java
index 117195f..f8359fd 100644
--- a/core/common/src/main/java/org/onosproject/common/app/ApplicationArchive.java
+++ b/core/common/src/main/java/org/onosproject/common/app/ApplicationArchive.java
@@ -58,6 +58,8 @@
 public class ApplicationArchive
         extends AbstractStore<ApplicationEvent, ApplicationStoreDelegate> {
 
+    private static Logger log = LoggerFactory.getLogger(ApplicationArchive.class);
+
     // Magic strings to search for at the beginning of the archive stream
     private static final String XML_MAGIC = "<?xml ";
 
@@ -72,7 +74,7 @@
     private static final String FEATURES = "[@features]";
     private static final String DESCRIPTION = "description";
 
-    private static Logger log = LoggerFactory.getLogger(ApplicationArchive.class);
+    private static final String OAR = ".oar";
     private static final String APP_XML = "app.xml";
     private static final String M2_PREFIX = "m2";
 
@@ -222,7 +224,7 @@
      */
     public synchronized InputStream getApplicationInputStream(String appName) {
         try {
-            File appFile = appFile(appName, appName + ".zip");
+            File appFile = appFile(appName, appName + OAR);
             return new FileInputStream(appFile.exists() ? appFile : appFile(appName, APP_XML));
         } catch (FileNotFoundException e) {
             throw new ApplicationException("Application " + appName + " not found");
@@ -304,7 +306,7 @@
     // Saves the specified ZIP stream into a file under app-specific directory.
     private void saveApplication(InputStream stream, ApplicationDescription desc)
             throws IOException {
-        Files.write(toByteArray(stream), appFile(desc.name(), desc.name() + ".zip"));
+        Files.write(toByteArray(stream), appFile(desc.name(), desc.name() + OAR));
     }
 
     // Installs application artifacts into M2 repository.
diff --git a/features/features.xml b/features/features.xml
index d4d37ff..bf7e17c 100644
--- a/features/features.xml
+++ b/features/features.xml
@@ -97,14 +97,6 @@
         <bundle>mvn:org.onosproject/onlab-netty/@ONOS-VERSION</bundle>
     </feature>
 
-    <feature name="onos-core-trivial" version="@FEATURE-VERSION"
-             description="ONOS core components">
-        <feature>onos-api</feature>
-        <bundle>mvn:org.onosproject/onos-core-net/@ONOS-VERSION</bundle>
-        <bundle>mvn:org.onosproject/onos-core-common/@ONOS-VERSION</bundle>
-        <bundle>mvn:org.onosproject/onos-core-trivial/@ONOS-VERSION</bundle>
-    </feature>
-
     <feature name="onos-rest" version="@FEATURE-VERSION"
              description="ONOS REST API components">
         <feature>onos-api</feature>
@@ -128,11 +120,7 @@
         <bundle>mvn:org.onosproject/onos-cli/@ONOS-VERSION</bundle>
     </feature>
 
-    <feature name="onos-null" version="@FEATURE-VERSION"
-             description="ONOS Null providers">
-        <feature>onos-api</feature>
-        <bundle>mvn:org.onosproject/onos-null-provider/@ONOS-VERSION</bundle>
-    </feature>
+    <!-- ONOS OpenFlow provider app features -->
 
     <feature name="onos-openflow" version="@FEATURE-VERSION"
              description="ONOS OpenFlow API, Controller &amp; Providers">
@@ -151,146 +139,14 @@
         <bundle>mvn:org.onosproject/onos-of-provider-group/@ONOS-VERSION</bundle>
     </feature>
 
-    <!-- ONOS built-in app features -->
+    <!-- Deprecated! For standalone testing only. -->
 
-    <feature name="onos-app-fwd" version="@FEATURE-VERSION"
-             description="ONOS sample forwarding application">
+    <feature name="onos-core-trivial" version="@FEATURE-VERSION"
+             description="ONOS core components">
         <feature>onos-api</feature>
-        <bundle>mvn:org.onosproject/onos-app-fwd/@ONOS-VERSION</bundle>
+        <bundle>mvn:org.onosproject/onos-core-net/@ONOS-VERSION</bundle>
+        <bundle>mvn:org.onosproject/onos-core-common/@ONOS-VERSION</bundle>
+        <bundle>mvn:org.onosproject/onos-core-trivial/@ONOS-VERSION</bundle>
     </feature>
 
-    <feature name="onos-app-mobility" version="@FEATURE-VERSION"
-             description="ONOS sample mobility application">
-        <feature>onos-api</feature>
-        <bundle>mvn:org.onosproject/onos-app-mobility/@ONOS-VERSION</bundle>
-    </feature>
-
-    <feature name="onos-app-proxyarp" version="@FEATURE-VERSION"
-             description="ONOS sample proxyarp application">
-        <feature>onos-api</feature>
-        <bundle>mvn:org.onosproject/onos-app-proxyarp/@ONOS-VERSION</bundle>
-    </feature>
-
-    <feature name="onos-app-config" version="@FEATURE-VERSION"
-             description="ONOS network config reader">
-        <feature>onos-api</feature>
-        <bundle>mvn:org.onosproject/onos-app-config/@ONOS-VERSION</bundle>
-    </feature>
-
-    <feature name="onos-app-optical" version="@FEATURE-VERSION"
-             description="ONOS optical network config">
-        <feature>onos-api</feature>
-        <bundle>mvn:org.onosproject/onos-app-optical/@ONOS-VERSION</bundle>
-    </feature>
-
-    <feature name="onos-app-reactive-routing" version="@FEATURE-VERSION"
-             description="ONOS SDN/IP reactive routing">
-        <feature>onos-app-sdnip</feature>
-        <bundle>mvn:org.onosproject/onos-app-reactive-routing/@ONOS-VERSION</bundle>
-    </feature>
-
-    <feature name="onos-app-sdnip" version="@FEATURE-VERSION"
-             description="SDN-IP peering application">
-        <feature>onos-api</feature>
-        <feature>onos-app-proxyarp</feature>
-        <feature>onos-app-config</feature>
-        <bundle>mvn:org.onosproject/onos-app-sdnip/@ONOS-VERSION</bundle>
-        <bundle>mvn:org.onosproject/onos-app-routing-api/@ONOS-VERSION</bundle>
-        <bundle>mvn:org.onosproject/onos-app-routing/@ONOS-VERSION</bundle>
-    </feature>
-
-    <feature name="onos-app-bgprouter" version="@FEATURE-VERSION"
-             description="BGP router application">
-        <feature>onos-api</feature>
-        <feature>onos-app-proxyarp</feature>
-        <feature>onos-app-config</feature>
-        <bundle>mvn:org.onosproject/onos-app-bgprouter/@ONOS-VERSION</bundle>
-        <bundle>mvn:org.onosproject/onos-app-routing-api/@ONOS-VERSION</bundle>
-        <bundle>mvn:org.onosproject/onos-app-routing/@ONOS-VERSION</bundle>
-    </feature>
-
-    <feature name="onos-app-metrics" version="@FEATURE-VERSION"
-             description="ONOS metrics applications">
-        <feature>onos-app-metrics-intent</feature>
-        <feature>onos-app-metrics-topology</feature>
-    </feature>
-
-    <feature name="onos-app-metrics-intent" version="@FEATURE-VERSION"
-             description="ONOS intent metrics application">
-        <feature>onos-api</feature>
-        <bundle>mvn:org.onosproject/onos-app-metrics-intent/@ONOS-VERSION</bundle>
-    </feature>
-
-    <feature name="onos-app-metrics-topology" version="@FEATURE-VERSION"
-             description="ONOS topology metrics application">
-        <feature>onos-api</feature>
-        <bundle>mvn:org.onosproject/onos-app-metrics-topology/@ONOS-VERSION</bundle>
-    </feature>
-
-
-    <!-- ONOS test app features -->
-
-    <feature name="onos-app-intent-perf" version="@FEATURE-VERSION"
-             description="ONOS intent perf applications">
-        <feature>onos-api</feature>
-        <bundle>mvn:org.onosproject/onos-app-intent-perf/@ONOS-VERSION</bundle>
-    </feature>
-
-    <feature name="onos-app-election" version="@FEATURE-VERSION"
-             description="ONOS app leadership election test">
-        <feature>onos-api</feature>
-        <bundle>mvn:org.onosproject/onos-app-election/@ONOS-VERSION</bundle>
-    </feature>
-
-    <feature name="onos-app-demo" version="@FEATURE-VERSION"
-             description="ONOS demo applications">
-        <feature>onos-api</feature>
-        <bundle>mvn:org.onosproject/onlab-misc/@ONOS-VERSION</bundle>
-        <bundle>mvn:org.onosproject/onos-app-demo/@ONOS-VERSION</bundle>
-    </feature>
-
-
-    <!-- ONOS sample app features: to be moved to a different repo -->
-
-    <feature name="onos-app-tvue" version="@FEATURE-VERSION"
-             description="ONOS sample topology viewer application">
-        <feature>onos-api</feature>
-        <feature>onos-thirdparty-web</feature>
-        <bundle>mvn:org.onosproject/onlab-rest/@ONOS-VERSION</bundle>
-        <bundle>mvn:org.onosproject/onos-app-tvue/@ONOS-VERSION</bundle>
-    </feature>
-
-    <feature name="onos-app-ifwd" version="@FEATURE-VERSION"
-             description="ONOS sample forwarding application using intents">
-        <feature>onos-api</feature>
-        <bundle>mvn:org.onosproject/onos-app-ifwd/@ONOS-VERSION</bundle>
-    </feature>
-
-    <feature name="onos-app-database-perf" version="@FEATURE-VERSION"
-             description="ONOS partitioned database perf application">
-        <feature>onos-api</feature>
-        <bundle>mvn:org.onosproject/onos-app-database-perf/@ONOS-VERSION</bundle>
-    </feature>
-
-    <feature name="onos-app-calendar" version="@FEATURE-VERSION"
-             description="REST interface for scheduling intents from an external calendar">
-        <feature>onos-api</feature>
-        <feature>onos-thirdparty-web</feature>
-        <bundle>mvn:org.onosproject/onos-app-calendar/@ONOS-VERSION</bundle>
-    </feature>
-
-    <feature name="onos-app-grouphandler" version="@FEATURE-VERSION"
-             description="Group Handler Sample App">
-        <feature>onos-api</feature>
-        <bundle>mvn:org.onosproject/onos-app-grouphandler/@ONOS-VERSION</bundle>
-    </feature>
-
-    <feature name="onos-app-segmentrouting" version="@FEATURE-VERSION"
-             description="Segment routing application">
-        <feature>onos-api</feature>
-        <bundle>mvn:org.onosproject/onos-app-segmentrouting/@ONOS-VERSION</bundle>
-        <bundle>mvn:org.onosproject/onos-app-grouphandler/@ONOS-VERSION</bundle>
-    </feature>
-
-
 </features>
diff --git a/providers/null/app.xml b/providers/null/app.xml
index a6343d2..0965043 100644
--- a/providers/null/app.xml
+++ b/providers/null/app.xml
@@ -14,7 +14,9 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<app name="org.onosproject.null" origin="ON.Lab" version="1.2.0"
-        features="onos-null">
-    <description>Null southbound providers for testing</description>
+<app name="org.onosproject.null" origin="ON.Lab" version="${feature.version}"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
 </app>
diff --git a/providers/null/src/main/java/org/onosproject/provider/nil/NullPacketProvider.java b/providers/null/src/main/java/org/onosproject/provider/nil/NullPacketProvider.java
index a1baec9..674b33f 100644
--- a/providers/null/src/main/java/org/onosproject/provider/nil/NullPacketProvider.java
+++ b/providers/null/src/main/java/org/onosproject/provider/nil/NullPacketProvider.java
@@ -136,8 +136,8 @@
 
         @Override
         public void run(Timeout to) {
-            if (!devices.isEmpty()) {
-                sendEvent(devices.get(currentDevice));
+            if (!devices.isEmpty() && !to.isCancelled()) {
+                sendEvent(devices.get(Math.max(currentDevice, devices.size())));
                 currentDevice = (currentDevice + 1) % devices.size();
                 timeout = timer.newTimeout(to.getTask(), delay, TimeUnit.MILLISECONDS);
             }
diff --git a/providers/openflow/app.xml b/providers/openflow/app.xml
deleted file mode 100644
index 5159d74..0000000
--- a/providers/openflow/app.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ Copyright 2015 Open Networking Laboratory
-  ~
-  ~ Licensed 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.
-  -->
-<app name="org.onosproject.openflow" origin="ON.Lab" version="1.2.0"
-        features="onos-openflow">
-    <description>OpenFlow protocol southbound providers</description>
-</app>
diff --git a/providers/openflow/app/app.xml b/providers/openflow/app/app.xml
new file mode 100644
index 0000000..afa63fa
--- /dev/null
+++ b/providers/openflow/app/app.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2015 Open Networking Laboratory
+  ~
+  ~ Licensed 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.
+  -->
+<app name="org.onosproject.openflow" origin="ON.Lab" version="${feature.version}"
+     features="onos-openflow">
+    <description>OpenFlow protocol southbound providers</description>
+
+    <artifact>mvn:${project.groupId}/onos-of-api/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-of-drivers/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-of-ctl/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-drivers/${project.version}</artifact>
+
+    <artifact>mvn:${project.groupId}/onos-lldp-provider/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-host-provider/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-of-provider-device/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-of-provider-packet/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-of-provider-flow/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-of-provider-group/${project.version}</artifact>
+</app>
diff --git a/providers/openflow/app/pom.xml b/providers/openflow/app/pom.xml
new file mode 100644
index 0000000..bcbb632
--- /dev/null
+++ b/providers/openflow/app/pom.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2015 Open Networking Laboratory
+  ~
+  ~ Licensed 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-of-providers</artifactId>
+        <version>1.2.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>onos-of-providers-app</artifactId>
+    <packaging>pom</packaging>
+
+    <description>ONOS OpenFlow providers app</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-of-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-of-drivers</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-of-ctl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-drivers</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-of-provider-device</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-of-provider-packet</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-of-provider-flow</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-of-provider-group</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-lldp-provider</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-host-provider</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/providers/openflow/pom.xml b/providers/openflow/pom.xml
index c82516f..6a69b94 100644
--- a/providers/openflow/pom.xml
+++ b/providers/openflow/pom.xml
@@ -36,6 +36,7 @@
         <module>packet</module>
         <module>flow</module>
         <module>group</module>
+        <module>app</module>
     </modules>
 
     <dependencies>
diff --git a/tools/build/onos-package b/tools/build/onos-package
index 836ca9d..5ecb3ab 100755
--- a/tools/build/onos-package
+++ b/tools/build/onos-package
@@ -28,8 +28,8 @@
     echo "Apache Karaf bits $KARAF_ZIP or $KARAF_TAR not found" && exit 1
 
 # Unroll the Apache Karaf bits, prune them and make ONOS top-level directories.
-[ -f $KARAF_ZIP ] && unzip -q $KARAF_ZIP && rm -rf $KARAF_DIST/demos
-[ -f $KARAF_TAR ] && tar zxf $KARAF_TAR && rm -rf $KARAF_DIST/demos
+[ -f $KARAF_ZIP ] && unzip -q $KARAF_ZIP && rm -rf $ONOS_STAGE/$KARAF_DIST/demos
+[ -f $KARAF_TAR ] && tar zxf $KARAF_TAR && rm -rf $ONOS_STAGE/$KARAF_DIST/demos
 mkdir bin
 
 # Stage the ONOS admin scripts and patch in Karaf service wrapper extras
@@ -38,14 +38,7 @@
 cp -r $ONOS_ROOT/tools/package/etc/* $ONOS_STAGE/$KARAF_DIST/etc
 
 # Stage all builtin ONOS apps for factory install
-mkdir $ONOS_STAGE/apps
-find $ONOS_ROOT -name 'app.xml' | egrep -v '/src/test/|/target/|org\.foo\.' | \
-    xargs grep 'name=' | sed 's/<app name="//g;s/".*//g' | while read line; do
-        appxml=${line%:*}
-        app=${line#*:}
-        mkdir $ONOS_STAGE/apps/$app
-        cp $appxml $ONOS_STAGE/apps/$app/app.xml
-    done
+onos-stage-apps $ONOS_STAGE/apps $ONOS_STAGE/$KARAF_DIST/system
 
 # Patch-in proper Karaf version into the startup script
 sed "s/\$KARAF_VERSION/$KARAF_VERSION/g" \
@@ -54,14 +47,13 @@
     $ONOS_ROOT/tools/package/bin/onos > bin/onos
 
 # Stage the ONOS bundles, but only those that match the version
-mkdir -p $KARAF_DIST/system/org/onosproject
-# cp -r $M2_REPO/org/onosproject/ $KARAF_DIST/system/org/
+mkdir -p $ONOS_STAGE/$KARAF_DIST/system/org/onosproject
 find $M2_REPO/org/onosproject/ -type d -name $ONOS_POM_VERSION | while read line; do
     path=${line#*/onosproject/}
     artifact=${path%/$ONOS_POM_VERSION}
-    mkdir -p $KARAF_DIST/system/org/onosproject/$artifact
+    mkdir -p $ONOS_STAGE/$KARAF_DIST/system/org/onosproject/$artifact
     cp -r $M2_REPO/org/onosproject/$artifact/$ONOS_POM_VERSION \
-        $KARAF_DIST/system/org/onosproject/$artifact/$ONOS_POM_VERSION
+        $ONOS_STAGE/$KARAF_DIST/system/org/onosproject/$artifact/$ONOS_POM_VERSION
 done
 
 # ONOS Patching ----------------------------------------------------------------
@@ -84,6 +76,7 @@
 
 # Now package up the ONOS tar file
 cd $ONOS_STAGE_ROOT
+rm -f $ONOS_TAR $ONOS_ZIP
 COPYFILE_DISABLE=1 tar zcf $ONOS_TAR $ONOS_BITS
 which zip >/dev/null && zip -rq $ONOS_ZIP $ONOS_BITS
 ls -l $ONOS_TAR $ONOS_ZIP 2>/dev/null
diff --git a/tools/test/bin/onos-setup-karaf b/tools/test/bin/onos-setup-karaf
index 930fdf7..56102cb 100755
--- a/tools/test/bin/onos-setup-karaf
+++ b/tools/test/bin/onos-setup-karaf
@@ -56,7 +56,7 @@
 
 if ! grep -q ",onos-api," $KARAF_ROOT/etc/org.apache.karaf.features.cfg; then
     # Patch the Apache Karaf distribution file to load default ONOS boot features
-    export BOOT_FEATURES="webconsole,onos-api,onos-core,onos-cli,onos-rest,onos-gui,onos-openflow"
+    export BOOT_FEATURES="webconsole,onos-api,onos-core,onos-cli,onos-rest,onos-gui"
     echo "Adding ONOS boot features $BOOT_FEATURES..."
     perl -pi.old -e "s|^(featuresBoot=.*)|\1,$BOOT_FEATURES|" \
         $KARAF_ROOT/etc/org.apache.karaf.features.cfg
@@ -89,19 +89,11 @@
 perl -pi.old -e "s/192.168.56/$SUBNET/" $KARAF_ROOT/etc/hazelcast.xml
 perl -pi.old -e "s/        <name>onos</        <name>$IP</" $KARAF_ROOT/etc/hazelcast.xml
 
-
 echo "Staging builtin apps..."
 rm -fr $STAGE/apps
-mkdir -p $STAGE/apps
-find $ONOS_ROOT -name 'app.xml' | egrep -v '/src/test/|/target/|org\.foo\.' | \
-    xargs grep 'name=' | sed 's/<app name="//g;s/".*//g' | while read line; do
-        appxml=${line%:*}
-        app=${line#*:}
-        mkdir $STAGE/apps/$app
-        cp $appxml $STAGE/apps/$app/app.xml
-    done
+onos-stage-apps $STAGE/apps $KARAF_ROOT/system
 
 echo "Customizing apps to be auto-activated..."
-for app in $(echo $ONOS_APPS | tr ',' ' '); do
+for app in $(echo ${ONOS_APPS:-openflow} | tr ',' ' '); do
     touch $STAGE/apps/org.onosproject.$app/active
 done
diff --git a/tools/test/bin/onos-stage-apps b/tools/test/bin/onos-stage-apps
new file mode 100755
index 0000000..4c2c230
--- /dev/null
+++ b/tools/test/bin/onos-stage-apps
@@ -0,0 +1,29 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Stages builtin ONOS apps into the specified directory for packaging.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+export APPS=${1:-/tmp/apps}
+export KARAF_M2=${2:-/tmp/karaf/system}
+export AUX=$APPS/aux
+
+# Bail on any errors
+set -e
+
+mkdir -p $APPS $KARAF_M2
+rm -fr $AUX
+
+find $M2_REPO/org/onosproject/ -name "*.oar" -path "*/${ONOS_POM_VERSION}/*" | while read line; do
+    mkdir -p $AUX && cd $AUX
+    cp $line $AUX
+    jar -xf $AUX/*.oar
+    name=$(grep "name=" $AUX/app.xml | sed 's/<app name="//g;s/".*//g')
+    mkdir -p $APPS/$name
+    cp $AUX/app.xml $APPS/$name/app.xml
+    cp $AUX/*.oar $APPS/$name/$name.oar
+    cp -rf $AUX/m2/* $KARAF_M2
+    rm -fr $AUX
+done
diff --git a/web/gui/pom.xml b/web/gui/pom.xml
index 283a961..426faba 100644
--- a/web/gui/pom.xml
+++ b/web/gui/pom.xml
@@ -77,6 +77,7 @@
                             org.slf4j,
                             org.osgi.framework,
                             javax.ws.rs,javax.ws.rs.core,javax.ws.rs.ext,
+                            javax.servlet.*,
                             com.sun.jersey.api,
                             com.sun.jersey.spi.container.servlet,
                             com.sun.jersey.server.impl.container.servlet,
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/ApplicationViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/ApplicationViewMessageHandler.java
index 7f4f9b2..d19c987 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/ApplicationViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/ApplicationViewMessageHandler.java
@@ -18,9 +18,11 @@
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.google.common.collect.ImmutableSet;
+import org.onosproject.app.ApplicationAdminService;
 import org.onosproject.app.ApplicationService;
 import org.onosproject.app.ApplicationState;
 import org.onosproject.core.Application;
+import org.onosproject.core.ApplicationId;
 
 import java.util.Arrays;
 import java.util.List;
@@ -37,11 +39,20 @@
      * Creates a new message handler for the application messages.
      */
     protected ApplicationViewMessageHandler() {
-        super(ImmutableSet.of("appDataRequest"));
+        super(ImmutableSet.of("appDataRequest", "appManagementRequest"));
     }
 
     @Override
     public void process(ObjectNode message) {
+        String type = string(message, "event", "unknown");
+        if (type.equals("appDataRequest")) {
+            sendAppList(message);
+        } else if (type.equals("appManagementRequest")) {
+            processManagementCommand(message);
+        }
+    }
+
+    private void sendAppList(ObjectNode message) {
         ObjectNode payload = payload(message);
         String sortCol = string(payload, "sortCol", "id");
         String sortDir = string(payload, "sortDir", "asc");
@@ -58,6 +69,24 @@
         connection().sendMessage("appDataResponse", 0, rootNode);
     }
 
+    private void processManagementCommand(ObjectNode message) {
+        ObjectNode payload = payload(message);
+        String action = string(payload, "action");
+        String name = string(payload, "name");
+        if (action != null && name != null) {
+            ApplicationAdminService service = get(ApplicationAdminService.class);
+            ApplicationId appId = service.getId(name);
+            if (action.equals("activate")) {
+                service.activate(appId);
+            } else if (action.equals("deactivate")) {
+                service.deactivate(appId);
+            } else if (action.equals("uninstall")) {
+                service.uninstall(appId);
+            }
+            sendAppList(message);
+        }
+    }
+
     private TableRow[] generateTableRows(ApplicationService service) {
         List<TableRow> list = service.getApplications().stream()
                 .map(application -> new ApplicationTableRow(service, application))
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
index 3cc12b3..3be244e 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
@@ -628,7 +628,9 @@
         public void event(MastershipEvent event) {
             sendAllInstances("updateInstance");
             Device device = deviceService.getDevice(event.subject());
-            sendMessage(deviceMessage(new DeviceEvent(DEVICE_UPDATED, device)));
+            if (device != null) {
+                sendMessage(deviceMessage(new DeviceEvent(DEVICE_UPDATED, device)));
+            }
         }
     }
 
diff --git a/web/gui/src/main/webapp/WEB-INF/web.xml b/web/gui/src/main/webapp/WEB-INF/web.xml
index e6807fa..f83fbad 100644
--- a/web/gui/src/main/webapp/WEB-INF/web.xml
+++ b/web/gui/src/main/webapp/WEB-INF/web.xml
@@ -160,7 +160,6 @@
         <url-pattern>/websock/*</url-pattern>
     </servlet-mapping>
 
-
     <servlet>
         <servlet-name>Legacy Web Socket Service</servlet-name>
         <servlet-class>org.onosproject.ui.impl.GuiWebSocketServlet</servlet-class>
diff --git a/web/gui/src/main/webapp/app/view/app/app.css b/web/gui/src/main/webapp/app/view/app/app.css
index 481708d..a44b219 100644
--- a/web/gui/src/main/webapp/app/view/app/app.css
+++ b/web/gui/src/main/webapp/app/view/app/app.css
@@ -37,25 +37,45 @@
     cursor: pointer;
 }
 
-.light .ctrl-btns g.icon use {
-    fill: #fff;
+
+/* Inactive */
+.light .ctrl-btns div g.icon rect,
+.light .ctrl-btns div:hover g.icon rect {
+    fill: #eee;
 }
-.dark .ctrl-btns g.icon use {
+.dark .ctrl-btns div g.icon rect,
+.dark .ctrl-btns div:hover g.icon rect {
+    fill: #222;
+}
+
+.light .ctrl-btns div g.icon use {
+    fill: #ddd;
+}
+.dark .ctrl-btns div g.icon use {
     fill: #333;
 }
 
-.light .ctrl-btns g.icon rect {
-    fill: #bbb;
-}
-.dark .ctrl-btns g.icon rect {
-    fill: #444;
+/* Active hover */
+.light .ctrl-btns div.active:hover g.icon rect {
+    fill: #800;
 }
 
-/* Inactive */
-.light .ctrl-btns .disabled g.icon rect {
+.dark .ctrl-btns div.active:hover g.icon rect {
+    fill: #CE5650;
+}
+
+/* Active */
+.light .ctrl-btns div.active g.icon use {
+    fill: #fff;
+}
+.dark .ctrl-btns div.active g.icon use {
     fill: #eee;
 }
-.dark .ctrl-btns .disabled g.icon rect {
-    fill: #111;
+
+.light .ctrl-btns div.active g.icon rect {
+    fill: #bbb;
+}
+.dark .ctrl-btns div.active g.icon rect {
+    fill: #444;
 }
 
diff --git a/web/gui/src/main/webapp/app/view/app/app.html b/web/gui/src/main/webapp/app/view/app/app.html
index ced8ec2..e1e1647 100644
--- a/web/gui/src/main/webapp/app/view/app/app.html
+++ b/web/gui/src/main/webapp/app/view/app/app.html
@@ -3,11 +3,16 @@
     <div class="tabular-header">
         <h2>Applications ({{ctrl.tableData.length}} total)</h2>
         <div class="ctrl-btns">
-            <div icon icon-size="36" icon-id="plus"></div>
-            <div icon icon-size="36" icon-id="minus" class="disabled"></div>
-            <div icon icon-size="36" icon-id="play" class="disabled"></div>
-            <div icon icon-size="36" icon-id="stop" class="disabled"></div>
+            <div id="app-install"    icon icon-size="36" icon-id="plus" class="active"></div>
+            <div id="app-activate"   icon icon-size="36" icon-id="play"></div>
+            <div id="app-deactivate" icon icon-size="36" icon-id="stop"></div>
+            <div id="app-uninstall"  icon icon-size="36" icon-id="minus"></div>
         </div>
+
+        <form id="app-form" method="POST" action="/onos/v1/applications/upload" enctype="multipart/form-data" style="display:none">
+            <input type="file" id="file" accept=".oar">
+            <button type="submit" id="app-upload">Upload</button>
+        </form>
     </div>
 
     <table class="summary-list"
@@ -20,7 +25,7 @@
                 <th colId="id" sortable>App ID </th>
                 <th colId="version" sortable>Version </th>
                 <th colId="origin" sortable>Origin </th>
-                <th colId="desc" col-width="400px">Description </th>
+                <th colId="desc" col-width="640px">Description </th>
             </tr>
         </thead>
 
diff --git a/web/gui/src/main/webapp/app/view/app/app.js b/web/gui/src/main/webapp/app/view/app/app.js
index 1d46471..236099d 100644
--- a/web/gui/src/main/webapp/app/view/app/app.js
+++ b/web/gui/src/main/webapp/app/view/app/app.js
@@ -1,14 +1,14 @@
 /*
  * Copyright 2015 Open Networking Laboratory
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
+ * Licensed 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,
+ * 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.
@@ -21,19 +21,49 @@
 (function () {
     'use strict';
 
-    var selRow;
+    var selRow, selection;
 
     angular.module('ovApp', [])
     .controller('OvAppCtrl',
-        ['$log', '$scope', 'TableBuilderService',
+        ['$log', '$scope', 'TableBuilderService', 'WebSocketService',
 
-    function ($log, $scope, tbs) {
+    function ($log, $scope, tbs, wss) {
         function selCb($event, row) {
             selRow = angular.element($event.currentTarget);
-            // adjust which toolbar buttons are selected
+            selection = row;
             $log.debug('Got a click on:', row);
+            // adjust which toolbar buttons are selected
+            d3.select('#app-activate').classed('active', row && row.state === 'INSTALLED');
+            d3.select('#app-deactivate').classed('active', row && row.state === 'ACTIVE');
+            d3.select('#app-uninstall').classed('active', row);
         }
 
+        d3.select('#app-install').on('click', function () {
+            $log.debug('Initiating install');
+            var evt = document.createEvent("HTMLEvents");
+            evt.initEvent("click", true, true);
+            document.getElementById('file').dispatchEvent(evt);
+        });
+
+        function appAction(action) {
+            if (selection) {
+                $log.debug('Initiating uninstall of', selection);
+                wss.sendEvent('appManagementRequest', {action: action, name: selection.id});
+            }
+        }
+
+        d3.select('#file').on('change', function () {
+            var file = document.getElementById('file').value.replace('C:\\fakepath\\', '');
+            $log.info('Handling file', file);
+            var evt = document.createEvent("HTMLEvents");
+            evt.initEvent("click", true, true);
+            document.getElementById('app-upload').dispatchEvent(evt);
+        });
+
+        d3.select('#app-uninstall').on('click', function () { appAction('uninstall'); });
+        d3.select('#app-activate').on('click', function () { appAction('activate'); });
+        d3.select('#app-deactivate').on('click', function () { appAction('deactivate'); });
+
         tbs.buildTable({
             self: this,
             scope: $scope,