diff --git a/apps/test/demo/app.xml b/apps/test/demo/app.xml
new file mode 100644
index 0000000..0318f9c
--- /dev/null
+++ b/apps/test/demo/app.xml
@@ -0,0 +1,20 @@
+<?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.demo" origin="ON.Lab" version="1.2.0"
+        features="onos-app-demo">
+    <description>Flow throughput test application</description>
+</app>
diff --git a/apps/test/demo/pom.xml b/apps/test/demo/pom.xml
new file mode 100644
index 0000000..adac250
--- /dev/null
+++ b/apps/test/demo/pom.xml
@@ -0,0 +1,111 @@
+<?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-apps-test</artifactId>
+        <version>1.2.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>onos-app-demo</artifactId>
+    <packaging>bundle</packaging>
+
+    <description>ONOS demo app bundle</description>
+
+    <properties>
+        <web.context>/onos/demo</web.context>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-rest</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-rest</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-servlet</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.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <_wab>src/main/webapp/</_wab>
+                        <Bundle-SymbolicName>
+                            ${project.groupId}.${project.artifactId}
+                        </Bundle-SymbolicName>
+                        <Import-Package>
+                            org.slf4j,
+                            org.osgi.framework,
+                            javax.ws.rs,javax.ws.rs.core,
+                            com.sun.jersey.api.core,
+                            com.sun.jersey.spi.container.servlet,
+                            com.sun.jersey.server.impl.container.servlet,
+                            com.fasterxml.jackson.databind,
+                            com.fasterxml.jackson.databind.node,
+                            org.apache.commons.lang.math.*,
+                            com.google.common.*,
+                            org.onlab.packet.*,
+                            org.onlab.rest.*,
+                            org.onosproject.*,
+                            org.onlab.util.*,
+                            org.jboss.netty.util.*
+                        </Import-Package>
+                        <Web-ContextPath>${web.context}</Web-ContextPath>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/apps/test/demo/src/main/java/org/onosproject/demo/DemoAPI.java b/apps/test/demo/src/main/java/org/onosproject/demo/DemoAPI.java
new file mode 100644
index 0000000..eded291
--- /dev/null
+++ b/apps/test/demo/src/main/java/org/onosproject/demo/DemoAPI.java
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+package org.onosproject.demo;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import java.util.Optional;
+
+/**
+ * Simple demo api interface.
+ */
+public interface DemoAPI {
+
+    enum InstallType { MESH, RANDOM };
+
+    /**
+     * Tests flow subsystem based on the parameters supplied.
+     *
+     * @param params the test parameters
+     * @return JSON representation
+     */
+    JsonNode flowTest(Optional<JsonNode> params);
+
+    /**
+     * Installs intents based on the installation type.
+     * @param type the installation type.
+     * @param runParams run params
+     */
+    void setup(InstallType type, Optional<JsonNode> runParams);
+
+    /**
+     * Uninstalls all existing intents.
+     */
+    void tearDown();
+
+}
diff --git a/apps/test/demo/src/main/java/org/onosproject/demo/DemoInstaller.java b/apps/test/demo/src/main/java/org/onosproject/demo/DemoInstaller.java
new file mode 100644
index 0000000..1bad7a7
--- /dev/null
+++ b/apps/test/demo/src/main/java/org/onosproject/demo/DemoInstaller.java
@@ -0,0 +1,600 @@
+/*
+ * 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.
+ */
+package org.onosproject.demo;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.base.Predicate;
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import org.apache.commons.lang.math.RandomUtils;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.MacAddress;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.Device;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRuleOperations;
+import org.onosproject.net.flow.FlowRuleOperationsContext;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.HostToHostIntent;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentService;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Application to set up demos.
+ */
+@Component(immediate = true)
+@Service
+public class DemoInstaller implements DemoAPI {
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentService intentService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowRuleService flowService;
+
+    private ExecutorService worker;
+
+    private ExecutorService installWorker;
+
+    private ApplicationId appId;
+
+    private final Set<Intent> existingIntents = new HashSet<>();
+    private RandomInstaller randomInstaller;
+
+    private ObjectMapper mapper = new ObjectMapper();
+
+
+
+    @Activate
+    public void activate() {
+        String nodeId = clusterService.getLocalNode().ip().toString();
+        appId = coreService.registerApplication("org.onosproject.demo.installer."
+                                                        + nodeId);
+        worker = Executors.newFixedThreadPool(1,
+                                              new ThreadFactoryBuilder()
+                                                      .setNameFormat("demo-app-worker")
+                                                      .build());
+        log.info("Started with Application ID {}", appId.id());
+    }
+
+    @Deactivate
+    public void deactivate() {
+        shutdownAndAwaitTermination(worker);
+        if (installWorker != null && !installWorker.isShutdown()) {
+            shutdownAndAwaitTermination(installWorker);
+        }
+        log.info("Stopped");
+    }
+
+    @Override
+    public JsonNode flowTest(Optional<JsonNode> params) {
+        int flowsPerDevice = 1000;
+        int neighbours = 0;
+        boolean remove = true;
+        if (params.isPresent()) {
+            flowsPerDevice = params.get().get("flowsPerDevice").asInt();
+            neighbours = params.get().get("neighbours").asInt();
+            remove = params.get().get("remove").asBoolean();
+        }
+
+        Future<JsonNode> future = worker.submit(new FlowTest(flowsPerDevice, neighbours, remove));
+
+        try {
+            return future.get(10, TimeUnit.SECONDS);
+        } catch (InterruptedException | ExecutionException | TimeoutException e) {
+            ObjectNode node = mapper.createObjectNode();
+            node.put("Error", e.getMessage());
+            return node;
+        }
+    }
+
+    @Override
+    public void setup(InstallType type, Optional<JsonNode> runParams) {
+        switch (type) {
+            case MESH:
+                log.debug("Installing mesh intents");
+                worker.execute(new MeshInstaller());
+                break;
+            case RANDOM:
+                //check that we do not have a random installer running
+                if (installWorker == null || installWorker.isShutdown()) {
+                    installWorker = Executors.newFixedThreadPool(1,
+                                                                 new ThreadFactoryBuilder()
+                                                                         .setNameFormat("random-worker")
+                                                                         .build());
+                    log.debug("Installing random sequence of intents");
+                    randomInstaller = new RandomInstaller(runParams);
+                    installWorker.execute(randomInstaller);
+                } else {
+                    log.warn("Random installer is already running");
+                }
+                break;
+            default:
+                throw new IllegalArgumentException("What is it you want exactly?");
+        }
+    }
+
+    @Override
+    public void tearDown() {
+        worker.submit(new UnInstaller());
+    }
+
+
+    /**
+     * Simply installs a mesh of intents from all the hosts existing in the network.
+     */
+    private class MeshInstaller implements Runnable {
+
+        @Override
+        public void run() {
+            TrafficSelector selector = DefaultTrafficSelector.emptySelector();
+            TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+            List<Constraint> constraint = Lists.newArrayList();
+            List<Host> hosts = Lists.newArrayList(hostService.getHosts());
+            while (!hosts.isEmpty()) {
+                Host src = hosts.remove(0);
+                for (Host dst : hosts) {
+                    HostToHostIntent intent = HostToHostIntent.builder()
+                            .appId(appId)
+                            .one(src.id())
+                            .two(dst.id())
+                            .selector(selector)
+                            .treatment(treatment)
+                            .constraints(constraint)
+                            .build();
+                    existingIntents.add(intent);
+                    intentService.submit(intent);
+                }
+            }
+        }
+    }
+
+    /**
+     * Randomly installs and withdraws intents.
+     */
+    private class RandomInstaller implements Runnable {
+
+        private final boolean isLocal;
+        private final Set<Host> hosts;
+
+        private final Random random = new Random(System.currentTimeMillis());
+
+        private Set<HostPair> uninstalledOrWithdrawn;
+        private Set<HostPair> installed;
+
+        private CountDownLatch latch;
+
+        //used to wait on a batch to be processed.
+        private static final int ITERATIONMAX = 50000000;
+
+
+        public RandomInstaller(Optional<JsonNode> runParams) {
+            /*
+                Check if we have params and honour them. Otherwise
+                    set defaults to processing only local stuff and
+                    all local hosts.
+             */
+            if (runParams.isPresent()) {
+                JsonNode node = runParams.get();
+                isLocal = node.get("local").asBoolean();
+                hosts = node.get("hosts") == null ? Sets.newHashSet(hostService.getHosts()) :
+                        constructHostIds(node.get("hosts").elements());
+            } else {
+                isLocal = true;
+                hosts = Sets.newHashSet(hostService.getHosts());
+            }
+
+            //construct list of intents.
+            installed = Sets.newHashSet();
+            if (isLocal) {
+                uninstalledOrWithdrawn = buildPairs(pruneHostsByMasterShip());
+            } else {
+                uninstalledOrWithdrawn = buildPairs(hosts);
+            }
+
+        }
+
+        private Set<Host> constructHostIds(Iterator<JsonNode> elements) {
+            Set<Host> hostIds = Sets.newHashSet();
+            JsonNode n;
+            while (elements.hasNext()) {
+                n = elements.next();
+                hostIds.add(hostService.getHost(HostId.hostId(n.textValue())));
+            }
+            return hostIds;
+        }
+
+        @Override
+        public void run() {
+            if (!installWorker.isShutdown()) {
+                randomize();
+                latch = new CountDownLatch(1);
+                try {
+                    trackIntents();
+                } catch (InterruptedException e) {
+                    shutdown();
+                }
+            }
+
+        }
+
+
+        /**
+         *   Check whether the previously submitted batch is in progress
+         *   and if yes submit the next one. If things hang, wait for at
+         *   most 5 seconds and bail.
+         * @throws InterruptedException if the thread go interupted
+         */
+        private void trackIntents() throws InterruptedException {
+            //FIXME
+            // TODO generate keys for each set of intents to allow manager to throttle
+            // TODO may also look into the store to see how many operations are pending
+
+            //if everything is good proceed.
+            if (!installWorker.isShutdown()) {
+                installWorker.execute(this);
+            }
+
+        }
+
+        public void shutdown() {
+            log.warn("Shutting down random installer!");
+            cleanUp();
+        }
+
+
+        /**
+         *   Shuffle the uninstalled and installed list (separately) and select
+         *   a random number of them and install or uninstall them respectively.
+         */
+        private void randomize() {
+            List<HostPair> hostList = new LinkedList<>(uninstalledOrWithdrawn);
+            Collections.shuffle(hostList);
+            List<HostPair> toInstall = hostList.subList(0,
+                                                        random.nextInt(hostList.size() - 1));
+            List<HostPair> toRemove;
+            if (!installed.isEmpty()) {
+                hostList = new LinkedList<>(installed);
+                Collections.shuffle(hostList);
+                toRemove = hostList.subList(0,
+                                            random.nextInt(hostList.size() - 1));
+                uninstallIntents(toRemove);
+            }
+            installIntents(toInstall);
+
+        }
+
+        private void installIntents(List<HostPair> toInstall) {
+            for (HostPair pair : toInstall) {
+                installed.add(pair);
+                uninstalledOrWithdrawn.remove(pair);
+                intentService.submit(pair.h2hIntent());
+            }
+        }
+
+        private void uninstallIntents(Collection<HostPair> toRemove) {
+            for (HostPair pair : toRemove) {
+                installed.remove(pair);
+                uninstalledOrWithdrawn.add(pair);
+                intentService.withdraw(pair.h2hIntent());
+            }
+        }
+
+        /**
+         *  Take everything and remove it all.
+         */
+        private void cleanUp() {
+            List<HostPair> allPairs = Lists.newArrayList(installed);
+            allPairs.addAll(uninstalledOrWithdrawn);
+            for (HostPair pair : allPairs) {
+                intentService.withdraw(pair.h2hIntent());
+            }
+        }
+
+
+        private Set<HostPair> buildPairs(Set<Host> hosts) {
+            Set<HostPair> pairs = Sets.newHashSet();
+            Iterator<Host> it = Sets.newHashSet(hosts).iterator();
+            while (it.hasNext()) {
+                Host src = it.next();
+                it.remove();
+                for (Host dst : hosts) {
+                    pairs.add(new HostPair(src, dst));
+                }
+            }
+            return pairs;
+        }
+
+        private Set<Host> pruneHostsByMasterShip() {
+            return FluentIterable.from(hosts)
+                    .filter(hasLocalMaster())
+                    .toSet();
+
+        }
+
+        private Predicate<? super Host> hasLocalMaster() {
+            return new Predicate<Host>() {
+                @Override
+                public boolean apply(Host host) {
+                    return mastershipService.getLocalRole(
+                            host.location().deviceId()).equals(MastershipRole.MASTER);
+                }
+            };
+        }
+
+
+        /**
+         * Simple class representing a pair of hosts and precomputes the associated
+         * h2h intent.
+         */
+        private class HostPair {
+
+            private final Host src;
+            private final Host dst;
+
+            private final TrafficSelector selector = DefaultTrafficSelector.emptySelector();
+            private final TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+            private final List<Constraint> constraint = Lists.newArrayList();
+            private final HostToHostIntent intent;
+
+            public HostPair(Host src, Host dst) {
+                this.src = src;
+                this.dst = dst;
+                this.intent = HostToHostIntent.builder()
+                        .appId(appId)
+                        .one(src.id())
+                        .two(dst.id())
+                        .selector(selector)
+                        .treatment(treatment)
+                        .constraints(constraint)
+                        .build();
+            }
+
+            public HostToHostIntent h2hIntent() {
+                return intent;
+            }
+
+            @Override
+            public boolean equals(Object o) {
+                if (this == o) {
+                    return true;
+                }
+                if (o == null || getClass() != o.getClass()) {
+                    return false;
+                }
+
+                HostPair hostPair = (HostPair) o;
+
+                return Objects.equals(src, hostPair.src) &&
+                        Objects.equals(dst, hostPair.dst);
+
+            }
+
+            @Override
+            public int hashCode() {
+                return Objects.hash(src, dst);
+            }
+
+
+        }
+
+    }
+
+    /**
+     * Remove anything that is running and clear it all out.
+     */
+    private class UnInstaller implements Runnable {
+        @Override
+        public void run() {
+            if (!existingIntents.isEmpty()) {
+                clearExistingIntents();
+            }
+
+            if (installWorker != null && !installWorker.isShutdown()) {
+                shutdownAndAwaitTermination(installWorker);
+                randomInstaller.shutdown();
+            }
+        }
+
+        private void clearExistingIntents() {
+            for (Intent i : existingIntents) {
+                intentService.withdraw(i);
+            }
+            existingIntents.clear();
+        }
+    }
+
+    /**
+     * Shutdown a pool cleanly if possible.
+     *
+     * @param pool an executorService
+     */
+    private void shutdownAndAwaitTermination(ExecutorService pool) {
+        pool.shutdown(); // Disable new tasks from being submitted
+        try {
+            // Wait a while for existing tasks to terminate
+            if (!pool.awaitTermination(10, TimeUnit.SECONDS)) {
+                pool.shutdownNow(); // Cancel currently executing tasks
+                // Wait a while for tasks to respond to being cancelled
+                if (!pool.awaitTermination(10, TimeUnit.SECONDS)) {
+                    log.error("Pool did not terminate");
+                }
+            }
+        } catch (Exception ie) {
+            // (Re-)Cancel if current thread also interrupted
+            pool.shutdownNow();
+            // Preserve interrupt status
+            Thread.currentThread().interrupt();
+        }
+    }
+
+    private class FlowTest implements Callable<JsonNode> {
+        private final int flowPerDevice;
+        private final int neighbours;
+        private final boolean remove;
+        private FlowRuleOperations.Builder adds;
+        private FlowRuleOperations.Builder removes;
+
+        public FlowTest(int flowsPerDevice, int neighbours, boolean remove) {
+            this.flowPerDevice = flowsPerDevice;
+            this.neighbours = neighbours;
+            this.remove = remove;
+            prepareInstallation();
+        }
+
+        private void prepareInstallation() {
+            Set<ControllerNode> instances = Sets.newHashSet(clusterService.getNodes());
+            instances.remove(clusterService.getLocalNode());
+            Set<NodeId> acceptableNodes = Sets.newHashSet();
+            if (neighbours >= instances.size()) {
+                instances.forEach(instance -> acceptableNodes.add(instance.id()));
+            } else {
+                Iterator<ControllerNode> nodes = instances.iterator();
+                for (int i = neighbours; i > 0; i--) {
+                    acceptableNodes.add(nodes.next().id());
+                }
+            }
+            acceptableNodes.add(clusterService.getLocalNode().id());
+
+            Set<Device> devices = Sets.newHashSet();
+            for (Device dev : deviceService.getDevices()) {
+                if (acceptableNodes.contains(
+                        mastershipService.getMasterFor(dev.id()))) {
+                    devices.add(dev);
+                }
+            }
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(PortNumber.portNumber(RandomUtils.nextInt())).build();
+            TrafficSelector.Builder sbuilder;
+            FlowRuleOperations.Builder rules = FlowRuleOperations.builder();
+            FlowRuleOperations.Builder remove = FlowRuleOperations.builder();
+
+            for (Device d : devices) {
+                for (int i = 0; i < this.flowPerDevice; i++) {
+                    sbuilder = DefaultTrafficSelector.builder();
+
+                    sbuilder.matchEthSrc(MacAddress.valueOf(RandomUtils.nextInt() * i))
+                            .matchEthDst(MacAddress.valueOf((Integer.MAX_VALUE - i) * RandomUtils.nextInt()));
+
+
+                    int randomPriority = RandomUtils.nextInt();
+                    DefaultFlowRule f = new DefaultFlowRule(d.id(), sbuilder.build(), treatment,
+                                                            randomPriority, appId, 10, false);
+                    rules.add(f);
+                    remove.remove(f);
+
+                }
+            }
+
+            this.adds = rules;
+            this.removes = remove;
+        }
+
+        @Override
+        public JsonNode call() throws Exception {
+            ObjectNode node = mapper.createObjectNode();
+            CountDownLatch latch = new CountDownLatch(1);
+            flowService.apply(adds.build(new FlowRuleOperationsContext() {
+
+                private final Stopwatch timer = Stopwatch.createStarted();
+
+                @Override
+                public void onSuccess(FlowRuleOperations ops) {
+
+                    long elapsed = timer.elapsed(TimeUnit.MILLISECONDS);
+                    node.put("elapsed", elapsed);
+
+
+                    latch.countDown();
+                }
+            }));
+
+            latch.await(10, TimeUnit.SECONDS);
+            if (this.remove) {
+                flowService.apply(removes.build());
+            }
+            return node;
+        }
+    }
+}
+
+
diff --git a/apps/test/demo/src/main/java/org/onosproject/demo/DemoResource.java b/apps/test/demo/src/main/java/org/onosproject/demo/DemoResource.java
new file mode 100644
index 0000000..29c55d1
--- /dev/null
+++ b/apps/test/demo/src/main/java/org/onosproject/demo/DemoResource.java
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+package org.onosproject.demo;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.onlab.rest.BaseResource;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Optional;
+
+/**
+ * Rest API for demos.
+ */
+@Path("intents")
+public class DemoResource extends BaseResource {
+
+
+
+    @POST
+    @Path("flowTest")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response flowTest(InputStream input) throws IOException {
+        ObjectMapper mapper = new ObjectMapper();
+        JsonNode cfg = mapper.readTree(input);
+        DemoAPI demo = get(DemoAPI.class);
+        return Response.ok(demo.flowTest(Optional.ofNullable(cfg)).toString()).build();
+    }
+
+    @POST
+    @Path("setup")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response setup(InputStream input) throws IOException {
+        ObjectMapper mapper = new ObjectMapper();
+        JsonNode cfg = mapper.readTree(input);
+        if (!cfg.has("type")) {
+            return Response.status(Response.Status.BAD_REQUEST)
+                    .entity("Expected type field containing either mesh or random.").build();
+        }
+
+
+        DemoAPI.InstallType type = DemoAPI.InstallType.valueOf(
+                cfg.get("type").asText().toUpperCase());
+        DemoAPI demo = get(DemoAPI.class);
+        demo.setup(type, Optional.ofNullable(cfg.get("runParams")));
+
+        return Response.ok(mapper.createObjectNode().toString()).build();
+    }
+
+    @GET
+    @Path("teardown")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response tearDown() throws IOException {
+        ObjectMapper mapper = new ObjectMapper();
+        DemoAPI demo = get(DemoAPI.class);
+        demo.tearDown();
+        return Response.ok(mapper.createObjectNode().toString()).build();
+    }
+
+}
diff --git a/apps/test/demo/src/main/java/org/onosproject/demo/package-info.java b/apps/test/demo/src/main/java/org/onosproject/demo/package-info.java
new file mode 100644
index 0000000..f583a0e
--- /dev/null
+++ b/apps/test/demo/src/main/java/org/onosproject/demo/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ *  Demo applications live here.
+ */
+package org.onosproject.demo;
diff --git a/apps/test/demo/src/main/webapp/WEB-INF/web.xml b/apps/test/demo/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..29716df
--- /dev/null
+++ b/apps/test/demo/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,44 @@
+<?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.
+  -->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
+         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         id="ONOS" version="2.5">
+    <display-name>ONOS DEMO APP API v1.0</display-name>
+
+    <servlet>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+        <init-param>
+            <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
+            <param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value>
+        </init-param>
+        <init-param>
+            <param-name>com.sun.jersey.config.property.classnames</param-name>
+            <param-value>
+                org.onosproject.demo.DemoResource
+            </param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+
+</web-app>
diff --git a/apps/test/pom.xml b/apps/test/pom.xml
index 1d7ba6f..daab99b 100644
--- a/apps/test/pom.xml
+++ b/apps/test/pom.xml
@@ -34,6 +34,7 @@
     <modules>
         <module>election</module>
         <module>intent-perf</module>
+        <module>demo</module>
     </modules>
 
 </project>
