Removed STC as it has been moved to a separate repository.

Change-Id: I419079b4ce539e5c082dd3f9dcf2bf8a91e2e45a
diff --git a/utils/pom.xml b/utils/pom.xml
index 84e6f4e..0091b48 100644
--- a/utils/pom.xml
+++ b/utils/pom.xml
@@ -37,7 +37,6 @@
         <module>yangutils</module>
         <module>osgi</module>
         <module>rest</module>
-        <module>stc</module>
         <module>jdvue</module>
         <module>osgiwrap</module>
     </modules>
diff --git a/utils/stc/bin/stc b/utils/stc/bin/stc
deleted file mode 100755
index eefc25e..0000000
--- a/utils/stc/bin/stc
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-#-------------------------------------------------------------------------------
-#   System Test Coordinator
-#-------------------------------------------------------------------------------
-
-STC_ROOT=${STC_ROOT:-$(dirname $0)/..}
-cd $STC_ROOT
-VER=1.7.0-SNAPSHOT
-
-PATH=$PWD/bin:$PATH
-
-java -jar target/onlab-stc-$VER.jar "$@"
diff --git a/utils/stc/bin/stc-launcher b/utils/stc/bin/stc-launcher
deleted file mode 100755
index 0d56017..0000000
--- a/utils/stc/bin/stc-launcher
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-#-------------------------------------------------------------------------------
-#   System Test Coordinator process launcher
-#-------------------------------------------------------------------------------
-
-env=$1 && shift
-cwd=$1 && shift
-
-if [ $env != "-" ]; then
-    [ ! -f $env ] && echo "$env file not found" && exit 1
-    source $env
-fi
-
-if [ $cwd != "-" ]; then
-    [ ! -d $cwd ] && echo "$cwd directory not found" && exit 1
-    cd $cwd
-fi
-
-"$@" 2>&1
diff --git a/utils/stc/pom.xml b/utils/stc/pom.xml
deleted file mode 100644
index 0456630..0000000
--- a/utils/stc/pom.xml
+++ /dev/null
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ Copyright 2015-present 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>onlab-utils</artifactId>
-        <version>1.7.0-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <artifactId>onlab-stc</artifactId>
-    <packaging>jar</packaging>
-
-    <description>System Test Coordinator</description>
-
-    <dependencies>
-        <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>commons-configuration</groupId>
-            <artifactId>commons-configuration</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>commons-collections</groupId>
-            <artifactId>commons-collections</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-databind</artifactId>
-            <version>2.7.3</version>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-annotations</artifactId>
-            <version>2.7.3</version>
-            <scope>compile</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-server</artifactId>
-            <version>8.1.19.v20160209</version>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-servlet</artifactId>
-            <version>8.1.19.v20160209</version>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-websocket</artifactId>
-            <version>8.1.19.v20160209</version>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-shade-plugin</artifactId>
-                <version>2.4.2</version>
-                <configuration>
-                    <transformers>
-                        <transformer
-                                implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
-                            <mainClass>org.onlab.stc.Main
-                            </mainClass>
-                        </transformer>
-                    </transformers>
-                    <filters>
-                        <filter>
-                            <artifact>*:*</artifact>
-                            <excludes>
-                                <exclude>META-INF/*.SF</exclude>
-                                <exclude>META-INF/*.DSA</exclude>
-                                <exclude>META-INF/*.RSA</exclude>
-                            </excludes>
-                        </filter>
-                    </filters>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>shade</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>
diff --git a/utils/stc/sample/scenario.xml b/utils/stc/sample/scenario.xml
deleted file mode 100644
index 0d6a990..0000000
--- a/utils/stc/sample/scenario.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!--
-  ~ Copyright 2015-present 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.
-  -->
-<scenario name="sample" description="Sample Test Scenario">
-    <step name="alpha" exec="/bin/ls -l"/>
-    <step name="beta" exec="/bin/ls -lF"/>
-    <step name="gamma" exec="/bin/ls" requires="alpha,beta"/>
-</scenario>
\ No newline at end of file
diff --git a/utils/stc/src/main/java/org/onlab/stc/Compiler.java b/utils/stc/src/main/java/org/onlab/stc/Compiler.java
deleted file mode 100644
index 1595f96..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/Compiler.java
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import org.apache.commons.configuration.HierarchicalConfiguration;
-import org.onlab.graph.DepthFirstSearch;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static com.google.common.base.Preconditions.*;
-import static com.google.common.base.Strings.isNullOrEmpty;
-import static java.lang.Integer.parseInt;
-import static org.onlab.graph.DepthFirstSearch.EdgeType.BACK_EDGE;
-import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
-import static org.onlab.stc.Scenario.loadScenario;
-
-/**
- * Entity responsible for loading a scenario and producing a redy-to-execute
- * process flow graph.
- */
-public class Compiler {
-
-    private static final String DEFAULT_LOG_DIR = "${WORKSPACE}/tmp/stc/";
-
-    private static final String IMPORT = "import";
-    private static final String GROUP = "group";
-    private static final String STEP = "step";
-    private static final String PARALLEL = "parallel";
-    private static final String SEQUENTIAL = "sequential";
-    private static final String DEPENDENCY = "dependency";
-
-    private static final String LOG_DIR = "[@logDir]";
-    private static final String NAME = "[@name]";
-    private static final String COMMAND = "[@exec]";
-    private static final String ENV = "[@env]";
-    private static final String CWD = "[@cwd]";
-    private static final String DELAY = "[@delay]";
-    private static final String REQUIRES = "[@requires]";
-    private static final String IF = "[@if]";
-    private static final String UNLESS = "[@unless]";
-    private static final String VAR = "[@var]";
-    private static final String STARTS = "[@starts]";
-    private static final String ENDS = "[@ends]";
-    private static final String FILE = "[@file]";
-    private static final String NAMESPACE = "[@namespace]";
-
-    static final String PROP_START = "${";
-    static final String PROP_END = "}";
-
-    private static final String HASH = "#";
-    private static final String HASH_PREV = "#-1";
-
-    private final Scenario scenario;
-
-    private final Map<String, Step> steps = Maps.newHashMap();
-    private final Map<String, Step> inactiveSteps = Maps.newHashMap();
-    private final Map<String, String> requirements = Maps.newHashMap();
-    private final Set<Dependency> dependencies = Sets.newHashSet();
-    private final List<Integer> clonables = Lists.newArrayList();
-
-    private ProcessFlow processFlow;
-    private File logDir;
-
-    private String previous = null;
-    private String pfx = "";
-    private boolean debugOn = System.getenv("debug") != null;
-
-    /**
-     * Creates a new compiler for the specified scenario.
-     *
-     * @param scenario scenario to be compiled
-     */
-    public Compiler(Scenario scenario) {
-        this.scenario = scenario;
-    }
-
-    /**
-     * Returns the scenario being compiled.
-     *
-     * @return test scenario
-     */
-    public Scenario scenario() {
-        return scenario;
-    }
-
-    /**
-     * Compiles the specified scenario to produce a final process flow graph.
-     */
-    public void compile() {
-        compile(scenario.definition(), null, null);
-        compileRequirements();
-
-        // Produce the process flow
-        processFlow = new ProcessFlow(ImmutableSet.copyOf(steps.values()),
-                                      ImmutableSet.copyOf(dependencies));
-
-        scanForCycles();
-
-        // Extract the log directory if there was one specified
-        String defaultPath = DEFAULT_LOG_DIR + scenario.name();
-        String path = scenario.definition().getString(LOG_DIR, defaultPath);
-        logDir = new File(expand(path));
-    }
-
-    /**
-     * Returns the step with the specified name.
-     *
-     * @param name step or group name
-     * @return test step or group
-     */
-    public Step getStep(String name) {
-        return steps.get(name);
-    }
-
-    /**
-     * Returns the process flow generated from this scenario definition.
-     *
-     * @return process flow as a graph
-     */
-    public ProcessFlow processFlow() {
-        return processFlow;
-    }
-
-    /**
-     * Returns the log directory where scenario logs should be kept.
-     *
-     * @return scenario logs directory
-     */
-    public File logDir() {
-        return logDir;
-    }
-
-    /**
-     * Recursively elaborates this definition to produce a final process flow graph.
-     *
-     * @param cfg         hierarchical definition
-     * @param namespace   optional namespace
-     * @param parentGroup optional parent group
-     */
-    private void compile(HierarchicalConfiguration cfg,
-                         String namespace, Group parentGroup) {
-        String opfx = pfx;
-        pfx = pfx + ">";
-        print("pfx=%s namespace=%s", pfx, namespace);
-
-        // Scan all imports
-        cfg.configurationsAt(IMPORT)
-                .forEach(c -> processImport(c, namespace, parentGroup));
-
-        // Scan all steps
-        cfg.configurationsAt(STEP)
-                .forEach(c -> processStep(c, namespace, parentGroup));
-
-        // Scan all groups
-        cfg.configurationsAt(GROUP)
-                .forEach(c -> processGroup(c, namespace, parentGroup));
-
-        // Scan all parallel groups
-        cfg.configurationsAt(PARALLEL)
-                .forEach(c -> processParallelGroup(c, namespace, parentGroup));
-
-        // Scan all sequential groups
-        cfg.configurationsAt(SEQUENTIAL)
-                .forEach(c -> processSequentialGroup(c, namespace, parentGroup));
-
-        // Scan all dependencies
-        cfg.configurationsAt(DEPENDENCY)
-                .forEach(c -> processDependency(c, namespace));
-
-        pfx = opfx;
-    }
-
-    /**
-     * Compiles requirements for all steps and groups accrued during the
-     * overall compilation process.
-     */
-    private void compileRequirements() {
-        requirements.forEach((name, requires) ->
-                                     compileRequirements(getStep(name), requires));
-    }
-
-    private void compileRequirements(Step src, String requires) {
-        split(requires).forEach(n -> {
-            boolean isSoft = n.startsWith("~");
-            String name = n.replaceFirst("^~", "");
-            Step dst = getStep(name);
-            if (dst != null) {
-                dependencies.add(new Dependency(src, dst, isSoft));
-            }
-        });
-    }
-
-    /**
-     * Processes an import directive.
-     *
-     * @param cfg         hierarchical definition
-     * @param namespace   optional namespace
-     * @param parentGroup optional parent group
-     */
-    private void processImport(HierarchicalConfiguration cfg,
-                               String namespace, Group parentGroup) {
-        String file = checkNotNull(expand(cfg.getString(FILE)),
-                                   "Import directive must specify 'file'");
-        String newNamespace = expand(prefix(cfg.getString(NAMESPACE), namespace));
-        print("import file=%s namespace=%s", file, newNamespace);
-        try {
-            Scenario importScenario = loadScenario(new FileInputStream(file));
-            compile(importScenario.definition(), newNamespace, parentGroup);
-        } catch (IOException e) {
-            throw new IllegalArgumentException("Unable to import scenario", e);
-        }
-    }
-
-    /**
-     * Processes a step directive.
-     *
-     * @param cfg         hierarchical definition
-     * @param namespace   optional namespace
-     * @param parentGroup optional parent group
-     */
-    private void processStep(HierarchicalConfiguration cfg,
-                             String namespace, Group parentGroup) {
-        String name = expand(prefix(cfg.getString(NAME), namespace));
-        String command = expand(cfg.getString(COMMAND, parentGroup != null ? parentGroup.command() : null), true);
-        String env = expand(cfg.getString(ENV, parentGroup != null ? parentGroup.env() : null));
-        String cwd = expand(cfg.getString(CWD, parentGroup != null ? parentGroup.cwd() : null));
-        int delay = parseInt(expand(cfg.getString(DELAY, parentGroup != null ? "" + parentGroup.delay() : "0")));
-
-        print("step name=%s command=%s env=%s cwd=%s delay=%d", name, command, env, cwd, delay);
-        Step step = new Step(name, command, env, cwd, parentGroup, delay);
-        registerStep(step, cfg, namespace, parentGroup);
-    }
-
-    /**
-     * Processes a group directive.
-     *
-     * @param cfg         hierarchical definition
-     * @param namespace   optional namespace
-     * @param parentGroup optional parent group
-     */
-    private void processGroup(HierarchicalConfiguration cfg,
-                              String namespace, Group parentGroup) {
-        String name = expand(prefix(cfg.getString(NAME), namespace));
-        String command = expand(cfg.getString(COMMAND, parentGroup != null ? parentGroup.command() : null), true);
-        String env = expand(cfg.getString(ENV, parentGroup != null ? parentGroup.env() : null));
-        String cwd = expand(cfg.getString(CWD, parentGroup != null ? parentGroup.cwd() : null));
-        int delay = parseInt(expand(cfg.getString(DELAY, parentGroup != null ? "" + parentGroup.delay() : "0")));
-
-        print("group name=%s command=%s env=%s cwd=%s delay=%d", name, command, env, cwd, delay);
-        Group group = new Group(name, command, env, cwd, parentGroup, delay);
-        if (registerStep(group, cfg, namespace, parentGroup)) {
-            compile(cfg, namespace, group);
-        }
-    }
-
-    /**
-     * Registers the specified step or group.
-     *
-     * @param step        step or group
-     * @param cfg         hierarchical definition
-     * @param namespace   optional namespace
-     * @param parentGroup optional parent group
-     * @return true of the step or group was registered as active
-     */
-    private boolean registerStep(Step step, HierarchicalConfiguration cfg,
-                                 String namespace, Group parentGroup) {
-        checkState(!steps.containsKey(step.name()), "Step %s already exists", step.name());
-        String ifClause = expand(cfg.getString(IF));
-        String unlessClause = expand(cfg.getString(UNLESS));
-
-        if ((ifClause != null && ifClause.length() == 0) ||
-                (unlessClause != null && unlessClause.length() > 0) ||
-                (parentGroup != null && inactiveSteps.containsValue(parentGroup))) {
-            inactiveSteps.put(step.name(), step);
-            return false;
-        }
-
-        if (parentGroup != null) {
-            parentGroup.addChild(step);
-        }
-
-        steps.put(step.name(), step);
-        processRequirements(step, expand(cfg.getString(REQUIRES)), namespace);
-        previous = step.name();
-        return true;
-    }
-
-    /**
-     * Processes a parallel clone group directive.
-     *
-     * @param cfg         hierarchical definition
-     * @param namespace   optional namespace
-     * @param parentGroup optional parent group
-     */
-    private void processParallelGroup(HierarchicalConfiguration cfg,
-                                      String namespace, Group parentGroup) {
-        String var = cfg.getString(VAR);
-        print("parallel var=%s", var);
-
-        int i = 1;
-        while (condition(var, i).length() > 0) {
-            clonables.add(0, i);
-            compile(cfg, namespace, parentGroup);
-            clonables.remove(0);
-            i++;
-        }
-    }
-
-    /**
-     * Processes a sequential clone group directive.
-     *
-     * @param cfg         hierarchical definition
-     * @param namespace   optional namespace
-     * @param parentGroup optional parent group
-     */
-    private void processSequentialGroup(HierarchicalConfiguration cfg,
-                                        String namespace, Group parentGroup) {
-        String var = cfg.getString(VAR);
-        String starts = cfg.getString(STARTS);
-        String ends = cfg.getString(ENDS);
-        print("sequential var=%s", var);
-
-        int i = 1;
-        while (condition(var, i).length() > 0) {
-            clonables.add(0, i);
-            compile(cfg, namespace, parentGroup);
-            if (i > 1) {
-                processSequentialRequirements(starts, ends, namespace);
-            }
-            clonables.remove(0);
-            i++;
-        }
-    }
-
-    /**
-     * Hooks starts of this sequence tier to the previous tier.
-     *
-     * @param starts    comma-separated list of start steps
-     * @param ends      comma-separated list of end steps
-     * @param namespace optional namespace
-     */
-    private void processSequentialRequirements(String starts, String ends,
-                                               String namespace) {
-        for (String s : split(starts)) {
-            String start = expand(prefix(s, namespace));
-            String reqs = requirements.get(s);
-            for (String n : split(ends)) {
-                boolean isSoft = n.startsWith("~");
-                String name = n.replaceFirst("^~", "");
-                name = (isSoft ? "~" : "") + expand(prefix(name, namespace));
-                reqs = reqs == null ? name : (reqs + "," + name);
-            }
-            requirements.put(start, reqs);
-        }
-    }
-
-    /**
-     * Returns the elaborated repetition construct conditional.
-     *
-     * @param var repetition var property
-     * @param i   index to elaborate
-     * @return elaborated string
-     */
-    private String condition(String var, Integer i) {
-        return expand(var.replaceFirst("#", i.toString())).trim();
-    }
-
-    /**
-     * Processes a dependency directive.
-     *
-     * @param cfg       hierarchical definition
-     * @param namespace optional namespace
-     */
-    private void processDependency(HierarchicalConfiguration cfg, String namespace) {
-        String name = expand(prefix(cfg.getString(NAME), namespace));
-        String requires = expand(cfg.getString(REQUIRES));
-
-        print("dependency name=%s requires=%s", name, requires);
-        Step step = getStep(name, namespace);
-        if (!inactiveSteps.containsValue(step)) {
-            processRequirements(step, requires, namespace);
-        }
-    }
-
-    /**
-     * Processes the specified requiremenst string and adds dependency for
-     * each requirement of the given step.
-     *
-     * @param src       source step
-     * @param requires  comma-separated list of required steps
-     * @param namespace optional namespace
-     */
-    private void processRequirements(Step src, String requires, String namespace) {
-        String reqs = requirements.get(src.name());
-        for (String n : split(requires)) {
-            boolean isSoft = n.startsWith("~");
-            String name = n.replaceFirst("^~", "");
-            name = previous != null && name.equals("^") ? previous : name;
-            name = (isSoft ? "~" : "") + expand(prefix(name, namespace));
-            reqs = reqs == null ? name : (reqs + "," + name);
-        }
-        requirements.put(src.name(), reqs);
-    }
-
-    /**
-     * Retrieves the step or group with the specified name.
-     *
-     * @param name      step or group name
-     * @param namespace optional namespace
-     * @return step or group; null if none found in active or inactive steps
-     */
-    private Step getStep(String name, String namespace) {
-        String dName = prefix(name, namespace);
-        Step step = steps.get(dName);
-        step = step != null ? step : inactiveSteps.get(dName);
-        checkArgument(step != null, "Unknown step %s", dName);
-        return step;
-    }
-
-    /**
-     * Prefixes the specified name with the given namespace.
-     *
-     * @param name      name of a step or a group
-     * @param namespace optional namespace
-     * @return composite name
-     */
-    private String prefix(String name, String namespace) {
-        return isNullOrEmpty(namespace) ? name : namespace + "." + name;
-    }
-
-    /**
-     * Expands any environment variables in the specified string. These are
-     * specified as ${property} tokens.
-     *
-     * @param string     string to be processed
-     * @param keepTokens true if the original unresolved tokens should be kept
-     * @return original string with expanded substitutions
-     */
-    private String expand(String string, boolean... keepTokens) {
-        if (string == null) {
-            return null;
-        }
-
-        String pString = string;
-        StringBuilder sb = new StringBuilder();
-        int start, end, last = 0;
-        while ((start = pString.indexOf(PROP_START, last)) >= 0) {
-            end = pString.indexOf(PROP_END, start + PROP_START.length());
-            checkArgument(end > start, "Malformed property in %s", pString);
-            sb.append(pString.substring(last, start));
-            String prop = pString.substring(start + PROP_START.length(), end);
-            String value;
-            if (prop.equals(HASH)) {
-                value = Integer.toString(clonables.get(0));
-            } else if (prop.equals(HASH_PREV)) {
-                value = Integer.toString(clonables.get(0) - 1);
-            } else if (prop.endsWith(HASH)) {
-                pString = pString.replaceFirst("#}", clonables.get(0) + "}");
-                last = start;
-                continue;
-            } else {
-                // Try system property first, then fall back to env. variable.
-                value = System.getProperty(prop);
-                if (value == null) {
-                    value = System.getenv(prop);
-                }
-            }
-            if (value == null && keepTokens.length == 1 && keepTokens[0]) {
-                sb.append("${").append(prop).append("}");
-            } else {
-                sb.append(value != null ? value : "");
-            }
-            last = end + 1;
-        }
-        sb.append(pString.substring(last));
-        return sb.toString().replace('\n', ' ').replace('\r', ' ');
-    }
-
-    /**
-     * Splits the comma-separated string into a list of strings.
-     *
-     * @param string string to split
-     * @return list of strings
-     */
-    private List<String> split(String string) {
-        ImmutableList.Builder<String> builder = ImmutableList.builder();
-        String[] fields = string != null ? string.split(",") : new String[0];
-        for (String field : fields) {
-            builder.add(field.trim());
-        }
-        return builder.build();
-    }
-
-    /**
-     * Scans the process flow graph for cyclic dependencies.
-     */
-    private void scanForCycles() {
-        DepthFirstSearch<Step, Dependency> dfs = new DepthFirstSearch<>();
-        // Use a brute-force method of searching paths from all vertices.
-        processFlow().getVertexes().forEach(s -> {
-            DepthFirstSearch<Step, Dependency>.SpanningTreeResult r =
-                    dfs.search(processFlow, s, null, null, ALL_PATHS);
-            r.edges().forEach((e, et) -> checkArgument(et != BACK_EDGE,
-                                                       "Process flow has a cycle involving dependency from %s to %s",
-                                                       e.src().name, e.dst().name));
-        });
-    }
-
-
-    /**
-     * Prints formatted output.
-     *
-     * @param format printf format string
-     * @param args   arguments to be printed
-     */
-    private void print(String format, Object... args) {
-        if (debugOn) {
-            System.err.println(pfx + String.format(format, args));
-        }
-    }
-
-}
diff --git a/utils/stc/src/main/java/org/onlab/stc/Coordinator.java b/utils/stc/src/main/java/org/onlab/stc/Coordinator.java
deleted file mode 100644
index 1c59b9f..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/Coordinator.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-import java.io.File;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.concurrent.Executors.newFixedThreadPool;
-import static org.onlab.stc.Compiler.PROP_END;
-import static org.onlab.stc.Compiler.PROP_START;
-import static org.onlab.stc.Coordinator.Directive.*;
-import static org.onlab.stc.Coordinator.Status.*;
-
-/**
- * Coordinates execution of a scenario process flow.
- */
-public class Coordinator {
-
-    private static final int MAX_THREADS = 64;
-
-    private final ExecutorService executor = newFixedThreadPool(MAX_THREADS);
-
-    private final ProcessFlow processFlow;
-
-    private final StepProcessListener delegate;
-    private final CountDownLatch latch;
-    private final ScenarioStore store;
-
-    private static final Pattern PROP_ERE = Pattern.compile("^@stc ([a-zA-Z0-9_.]+)=(.*$)");
-    private final Map<String, String> properties = Maps.newConcurrentMap();
-
-    private final Set<StepProcessListener> listeners = Sets.newConcurrentHashSet();
-    private File logDir;
-
-    /**
-     * Represents action to be taken on a test step.
-     */
-    public enum Directive {
-        NOOP, RUN, SKIP
-    }
-
-    /**
-     * Represents processor state.
-     */
-    public enum Status {
-        WAITING, IN_PROGRESS, SUCCEEDED, FAILED, SKIPPED
-    }
-
-    /**
-     * Creates a process flow coordinator.
-     *
-     * @param scenario    test scenario to coordinate
-     * @param processFlow process flow to coordinate
-     * @param logDir      scenario log directory
-     */
-    public Coordinator(Scenario scenario, ProcessFlow processFlow, File logDir) {
-        this.processFlow = processFlow;
-        this.logDir = logDir;
-        this.store = new ScenarioStore(processFlow, logDir, scenario.name());
-        this.delegate = new Delegate();
-        this.latch = new CountDownLatch(1);
-    }
-
-    /**
-     * Resets any previously accrued status and events.
-     */
-    public void reset() {
-        store.reset();
-    }
-
-    /**
-     * Resets all previously accrued status and events for steps that lie
-     * in the range between the steps or groups whose names match the specified
-     * patterns.
-     *
-     * @param runFromPatterns list of starting step patterns
-     * @param runToPatterns   list of ending step patterns
-     */
-    public void reset(List<String> runFromPatterns, List<String> runToPatterns) {
-        List<Step> fromSteps = matchSteps(runFromPatterns);
-        List<Step> toSteps = matchSteps(runToPatterns);
-
-        // FIXME: implement this
-    }
-
-    /**
-     * Returns number of milliseconds it took to execute.
-     *
-     * @return number of millis elapsed during the run
-     */
-    public long duration() {
-        return store.endTime() - store.startTime();
-    }
-
-    /**
-     * Returns a list of steps that match the specified list of patterns.
-     *
-     * @param runToPatterns list of patterns
-     * @return list of steps with matching names
-     */
-    private List<Step> matchSteps(List<String> runToPatterns) {
-        ImmutableList.Builder<Step> builder = ImmutableList.builder();
-        store.getSteps().forEach(step -> {
-            runToPatterns.forEach(p -> {
-                if (step.name().matches(p)) {
-                    builder.add(step);
-                }
-            });
-        });
-        return builder.build();
-    }
-
-    /**
-     * Starts execution of the process flow graph.
-     */
-    public void start() {
-        executeRoots(null);
-    }
-
-    /**
-     * Waits for completion of the entire process flow.
-     *
-     * @return exit code to use
-     * @throws InterruptedException if interrupted while waiting for completion
-     */
-    public int waitFor() throws InterruptedException {
-        while (!store.isComplete()) {
-            latch.await(1, TimeUnit.SECONDS);
-        }
-        return store.hasFailures() ? 1 : 0;
-    }
-
-    /**
-     * Returns set of all test steps.
-     *
-     * @return set of steps
-     */
-    public Set<Step> getSteps() {
-        return store.getSteps();
-    }
-
-    /**
-     * Returns a chronological list of step or group records.
-     *
-     * @return list of events
-     */
-    List<StepEvent> getRecords() {
-        return store.getEvents();
-    }
-
-    /**
-     * Returns the status record of the specified test step.
-     *
-     * @param step test step or group
-     * @return step status record
-     */
-    public Status getStatus(Step step) {
-        return store.getStatus(step);
-    }
-
-    /**
-     * Adds the specified listener.
-     *
-     * @param listener step process listener
-     */
-    public void addListener(StepProcessListener listener) {
-        listeners.add(checkNotNull(listener, "Listener cannot be null"));
-    }
-
-    /**
-     * Removes the specified listener.
-     *
-     * @param listener step process listener
-     */
-    public void removeListener(StepProcessListener listener) {
-        listeners.remove(checkNotNull(listener, "Listener cannot be null"));
-    }
-
-    /**
-     * Executes the set of roots in the scope of the specified group or globally
-     * if no group is given.
-     *
-     * @param group optional group
-     */
-    private void executeRoots(Group group) {
-        // FIXME: add ability to skip past completed steps
-        Set<Step> steps =
-                group != null ? group.children() : processFlow.getVertexes();
-        steps.forEach(step -> {
-            if (processFlow.getEdgesFrom(step).isEmpty() && step.group() == group) {
-                execute(step);
-            }
-        });
-    }
-
-    /**
-     * Executes the specified step.
-     *
-     * @param step step to execute
-     */
-    private synchronized void execute(Step step) {
-        Directive directive = nextAction(step);
-        if (directive == RUN) {
-            store.markStarted(step);
-            if (step instanceof Group) {
-                Group group = (Group) step;
-                delegate.onStart(group, null);
-                executeRoots(group);
-            } else {
-                executor.execute(new StepProcessor(step, logDir, delegate,
-                                                   substitute(step.command())));
-            }
-        } else if (directive == SKIP) {
-            skipStep(step);
-        }
-    }
-
-    /**
-     * Recursively skips the specified step or group and any steps/groups within.
-     *
-     * @param step step or group
-     */
-    private void skipStep(Step step) {
-        if (step instanceof Group) {
-            Group group = (Group) step;
-            store.markComplete(step, SKIPPED);
-            group.children().forEach(this::skipStep);
-        }
-        delegate.onCompletion(step, SKIPPED);
-
-    }
-
-    /**
-     * Determines the state of the specified step.
-     *
-     * @param step test step
-     * @return state of the step process
-     */
-    private Directive nextAction(Step step) {
-        Status status = store.getStatus(step);
-        if (status != WAITING) {
-            return NOOP;
-        }
-
-        for (Dependency dependency : processFlow.getEdgesFrom(step)) {
-            Status depStatus = store.getStatus(dependency.dst());
-            if (depStatus == WAITING || depStatus == IN_PROGRESS) {
-                return NOOP;
-            } else if (((depStatus == FAILED || depStatus == SKIPPED) && !dependency.isSoft()) ||
-                    (step.group() != null && store.getStatus(step.group()) == SKIPPED)) {
-                return SKIP;
-            }
-        }
-        return RUN;
-    }
-
-    /**
-     * Executes the successors to the specified step.
-     *
-     * @param step step whose successors are to be executed
-     */
-    private void executeSucessors(Step step) {
-        processFlow.getEdgesTo(step).forEach(dependency -> execute(dependency.src()));
-        completeParentIfNeeded(step.group());
-    }
-
-    /**
-     * Checks whether the specified parent group, if any, should be marked
-     * as complete.
-     *
-     * @param group parent group that should be checked
-     */
-    private synchronized void completeParentIfNeeded(Group group) {
-        if (group != null && getStatus(group) == IN_PROGRESS) {
-            boolean done = true;
-            boolean failed = false;
-            for (Step child : group.children()) {
-                Status status = store.getStatus(child);
-                done = done && (status == SUCCEEDED || status == FAILED || status == SKIPPED);
-                failed = failed || status == FAILED;
-            }
-            if (done) {
-                delegate.onCompletion(group, failed ? FAILED : SUCCEEDED);
-            }
-        }
-    }
-
-    /**
-     * Expands the var references with values from the properties map.
-     *
-     * @param string string to perform substitutions on
-     */
-    private String substitute(String string) {
-        StringBuilder sb = new StringBuilder();
-        int start, end, last = 0;
-        while ((start = string.indexOf(PROP_START, last)) >= 0) {
-            end = string.indexOf(PROP_END, start + PROP_START.length());
-            checkArgument(end > start, "Malformed property in %s", string);
-            sb.append(string.substring(last, start));
-            String prop = string.substring(start + PROP_START.length(), end);
-            String value = properties.get(prop);
-            sb.append(value != null ? value : "");
-            last = end + 1;
-        }
-        sb.append(string.substring(last));
-        return sb.toString().replace('\n', ' ').replace('\r', ' ');
-    }
-
-    /**
-     * Scrapes the line of output for any variables to be captured and posted
-     * in the properties for later use.
-     *
-     * @param line line of output to scrape for property exports
-     */
-    private void scrapeForVariables(String line) {
-        Matcher matcher = PROP_ERE.matcher(line);
-        if (matcher.matches()) {
-            String prop = matcher.group(1);
-            String value = matcher.group(2);
-            properties.put(prop, value);
-        }
-    }
-
-
-    /**
-     * Prints formatted output.
-     *
-     * @param format printf format string
-     * @param args   arguments to be printed
-     */
-    public static void print(String format, Object... args) {
-        System.out.println(String.format(format, args));
-    }
-
-    /**
-     * Internal delegate to monitor the process execution.
-     */
-    private class Delegate implements StepProcessListener {
-        @Override
-        public void onStart(Step step, String command) {
-            listeners.forEach(listener -> listener.onStart(step, command));
-        }
-
-        @Override
-        public void onCompletion(Step step, Status status) {
-            store.markComplete(step, status);
-            listeners.forEach(listener -> listener.onCompletion(step, status));
-            executeSucessors(step);
-            if (store.isComplete()) {
-                latch.countDown();
-            }
-        }
-
-        @Override
-        public void onOutput(Step step, String line) {
-            scrapeForVariables(line);
-            listeners.forEach(listener -> listener.onOutput(step, line));
-        }
-    }
-
-}
diff --git a/utils/stc/src/main/java/org/onlab/stc/Dependency.java b/utils/stc/src/main/java/org/onlab/stc/Dependency.java
deleted file mode 100644
index 36df677..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/Dependency.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import com.google.common.base.MoreObjects;
-import org.onlab.graph.AbstractEdge;
-
-import java.util.Objects;
-
-/**
- * Representation of a dependency from one step on completion of another.
- */
-public class Dependency extends AbstractEdge<Step> {
-
-    private boolean isSoft;
-
-    /**
-     * Creates a new edge between the specified source and destination vertexes.
-     *
-     * @param src    source vertex
-     * @param dst    destination vertex
-     * @param isSoft indicates whether this is a hard or soft dependency
-     */
-    public Dependency(Step src, Step dst, boolean isSoft) {
-        super(src, dst);
-        this.isSoft = isSoft;
-    }
-
-    /**
-     * Indicates whether this is a soft or hard dependency, i.e. one that
-     * requires successful completion of the dependency or just any completion.
-     *
-     * @return true if dependency is a soft one
-     */
-    public boolean isSoft() {
-        return isSoft;
-    }
-
-    @Override
-    public int hashCode() {
-        return 31 * super.hashCode() + Objects.hash(isSoft);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof Dependency) {
-            final Dependency other = (Dependency) obj;
-            return super.equals(other) && Objects.equals(this.isSoft, other.isSoft);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(this)
-                .add("name", src().name())
-                .add("requires", dst().name())
-                .add("isSoft", isSoft)
-                .toString();
-    }
-}
diff --git a/utils/stc/src/main/java/org/onlab/stc/Group.java b/utils/stc/src/main/java/org/onlab/stc/Group.java
deleted file mode 100644
index 1d86c67..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/Group.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-
-import java.util.Set;
-
-/**
- * Represenation of a related group of steps.
- */
-public class Group extends Step {
-
-    private final Set<Step> children = Sets.newHashSet();
-
-    /**
-     * Creates a new test step.
-     *
-     * @param name    group name
-     * @param command default command
-     * @param env     default path to file to be sourced into the environment
-     * @param cwd     default path to current working directory for the step
-     * @param group   optional group to which this step belongs
-     * @param delay   seconds to delay before executing
-     */
-    public Group(String name, String command, String env, String cwd, Group group, int delay) {
-        super(name, command, env, cwd, group, delay);
-    }
-
-    /**
-     * Returns the set of child steps and groups contained within this group.
-     *
-     * @return set of children
-     */
-    public Set<Step> children() {
-        return ImmutableSet.copyOf(children);
-    }
-
-    /**
-     * Adds the specified step or group as a child of this group.
-     *
-     * @param child child step or group to add
-     */
-    public void addChild(Step child) {
-        children.add(child);
-    }
-}
diff --git a/utils/stc/src/main/java/org/onlab/stc/Main.java b/utils/stc/src/main/java/org/onlab/stc/Main.java
deleted file mode 100644
index 98a08f4..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/Main.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.io.Files;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.servlet.ServletHandler;
-import org.eclipse.jetty.util.log.Logger;
-import org.onlab.stc.Coordinator.Status;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-import static java.lang.System.currentTimeMillis;
-import static org.onlab.stc.Coordinator.Status.*;
-import static org.onlab.stc.Coordinator.print;
-
-/**
- * Main program for executing system test coordinator.
- */
-public final class Main {
-
-    private static final String NONE = "\u001B[0m";
-    private static final String GRAY = "\u001B[30;1m";
-    private static final String RED = "\u001B[31;1m";
-    private static final String GREEN = "\u001B[32;1m";
-    private static final String BLUE = "\u001B[36m";
-
-    private static final String SUCCESS_SUMMARY =
-            "%s %sPassed! %d steps succeeded%s";
-    private static final String MIXED_SUMMARY =
-            "%s%d steps succeeded; %s%d steps failed; %s%d steps skipped%s";
-    private static final String FAILURE_SUMMARY = "%s %sFailed! " + MIXED_SUMMARY;
-    private static final String ABORTED_SUMMARY = "%s %sAborted! " + MIXED_SUMMARY;
-
-    private boolean isReported = false;
-
-    private enum Command {
-        LIST, RUN, RUN_RANGE, HELP
-    }
-
-    private final String scenarioFile;
-
-    private Command command = Command.HELP;
-    private String runFromPatterns = "";
-    private String runToPatterns = "";
-
-    private Coordinator coordinator;
-    private Compiler compiler;
-    private Monitor monitor;
-    private Listener delegate = new Listener();
-
-    private static boolean useColor = Objects.equals("true", System.getenv("stcColor"));
-    private static boolean dumpLogs = Objects.equals("true", System.getenv("stcDumpLogs"));
-
-    // usage: stc [<scenario-file>] [run]
-    // usage: stc [<scenario-file>] run [from <from-patterns>] [to <to-patterns>]]
-    // usage: stc [<scenario-file>] list
-
-    // Public construction forbidden
-    private Main(String[] args) {
-        this.scenarioFile = args[0];
-
-        if (args.length <= 1 || args.length == 2 && args[1].equals("run")) {
-            command = Command.RUN;
-        } else if (args.length == 2 && args[1].equals("list")) {
-            command = Command.LIST;
-        } else if (args.length >= 4 && args[1].equals("run")) {
-            int i = 2;
-            if (args[i].equals("from")) {
-                command = Command.RUN_RANGE;
-                runFromPatterns = args[i + 1];
-                i += 2;
-            }
-
-            if (args.length >= i + 2 && args[i].equals("to")) {
-                command = Command.RUN_RANGE;
-                runToPatterns = args[i + 1];
-            }
-        }
-    }
-
-    /**
-     * Main entry point for coordinating test scenario execution.
-     *
-     * @param args command-line arguments
-     */
-    public static void main(String[] args) {
-        Main main = new Main(args);
-        main.run();
-    }
-
-    // Runs the scenario processing
-    private void run() {
-        try {
-            // Load scenario
-            Scenario scenario = Scenario.loadScenario(new FileInputStream(scenarioFile));
-
-            // Elaborate scenario
-            compiler = new Compiler(scenario);
-            compiler.compile();
-
-            // Setup the process flow coordinator
-            coordinator = new Coordinator(scenario, compiler.processFlow(),
-                                          compiler.logDir());
-            coordinator.addListener(delegate);
-
-            // Prepare the GUI monitor
-            monitor = new Monitor(coordinator, compiler);
-            startMonitorServer(monitor);
-
-            // Execute process flow
-            processCommand();
-
-        } catch (FileNotFoundException e) {
-            print("Unable to find scenario file %s", scenarioFile);
-        }
-    }
-
-    // Initiates a web-server for the monitor GUI.
-    private static void startMonitorServer(Monitor monitor) {
-        org.eclipse.jetty.util.log.Log.setLog(new NullLogger());
-        Server server = new Server(9999);
-        ServletHandler handler = new ServletHandler();
-        server.setHandler(handler);
-        MonitorWebSocketServlet.setMonitor(monitor);
-        handler.addServletWithMapping(MonitorWebSocketServlet.class, "/*");
-        try {
-            server.start();
-        } catch (Exception e) {
-            print("GUI already active; running without...");
-        }
-    }
-
-    // Processes the appropriate command
-    private void processCommand() {
-        switch (command) {
-            case RUN:
-                processRun();
-                break;
-            case LIST:
-                processList();
-                break;
-            case RUN_RANGE:
-                processRunRange();
-                break;
-            default:
-                print("Unsupported command %s", command);
-        }
-    }
-
-    // Processes the scenario 'run' command.
-    private void processRun() {
-        coordinator.reset();
-        runCoordinator();
-    }
-
-    // Processes the scenario 'run' command for range of steps.
-    private void processRunRange() {
-        coordinator.reset(list(runFromPatterns), list(runToPatterns));
-        runCoordinator();
-    }
-
-    // Processes the scenario 'list' command.
-    private void processList() {
-        coordinator.getRecords()
-                .forEach(event -> logStatus(event.time(), event.name(), event.status(), event.command()));
-        printSummary(0, false);
-        System.exit(0);
-    }
-
-    // Runs the coordinator and waits for it to finish.
-    private void runCoordinator() {
-        try {
-            Runtime.getRuntime().addShutdownHook(new ShutdownHook());
-            coordinator.start();
-            int exitCode = coordinator.waitFor();
-            pause(100); // allow stdout to flush
-            printSummary(exitCode, false);
-            System.exit(exitCode);
-        } catch (InterruptedException e) {
-            print("Unable to execute scenario %s", scenarioFile);
-        }
-    }
-
-    private synchronized void printSummary(int exitCode, boolean isAborted) {
-        if (!isReported) {
-            isReported = true;
-            Set<Step> steps = coordinator.getSteps();
-            String duration = formatDuration((int) (coordinator.duration() / 1_000));
-            int count = steps.size();
-            if (exitCode == 0) {
-                print(SUCCESS_SUMMARY, duration, color(SUCCEEDED), count, color(null));
-            } else {
-                long success = steps.stream().filter(s -> coordinator.getStatus(s) == SUCCEEDED).count();
-                long failed = steps.stream().filter(s -> coordinator.getStatus(s) == FAILED).count();
-                long skipped = steps.stream().filter(s -> coordinator.getStatus(s) == SKIPPED).count();
-                print(isAborted ? ABORTED_SUMMARY : FAILURE_SUMMARY, duration,
-                      color(FAILED), color(SUCCEEDED), success,
-                      color(FAILED), failed, color(SKIPPED), skipped, color(null));
-            }
-        }
-    }
-
-    /**
-     * Internal delegate to monitor the process execution.
-     */
-    private class Listener implements StepProcessListener {
-        @Override
-        public void onStart(Step step, String command) {
-            logStatus(currentTimeMillis(), step.name(), IN_PROGRESS, command);
-        }
-
-        @Override
-        public void onCompletion(Step step, Status status) {
-            logStatus(currentTimeMillis(), step.name(), status, null);
-            if (dumpLogs && !(step instanceof Group) && status == FAILED) {
-                dumpLogs(step);
-            }
-        }
-
-        @Override
-        public void onOutput(Step step, String line) {
-        }
-    }
-
-    // Logs the step status.
-    private static void logStatus(long time, String name, Status status, String cmd) {
-        if (cmd != null) {
-            print("%s  %s%s %s%s -- %s", time(time), color(status), name, action(status), color(null), cmd);
-        } else {
-            print("%s  %s%s %s%s", time(time), color(status), name, action(status), color(null));
-        }
-    }
-
-    // Dumps the step logs to standard output.
-    private void dumpLogs(Step step) {
-        File logFile = new File(compiler.logDir(), step.name() + ".log");
-        try {
-            print(">>>>>");
-            Files.copy(logFile, System.out);
-            print("<<<<<");
-        } catch (IOException e) {
-            print("Unable to dump log file %s", logFile.getName());
-        }
-    }
-
-    // Produces a description of event using the specified step status.
-    private static String action(Status status) {
-        return status == IN_PROGRESS ? "started" :
-                (status == SUCCEEDED ? "completed" :
-                        (status == FAILED ? "failed" :
-                                (status == SKIPPED ? "skipped" : "waiting")));
-    }
-
-    // Produces an ANSI escape code for color using the specified step status.
-    private static String color(Status status) {
-        if (!useColor) {
-            return "";
-        }
-        return status == null ? NONE :
-                (status == IN_PROGRESS ? BLUE :
-                        (status == SUCCEEDED ? GREEN :
-                                (status == FAILED ? RED : GRAY)));
-    }
-
-    // Produces a list from the specified comma-separated string.
-    private static List<String> list(String patterns) {
-        return ImmutableList.copyOf(patterns.split(","));
-    }
-
-    // Produces a formatted time stamp.
-    private static String time(long time) {
-        return new SimpleDateFormat("YYYY-MM-dd HH:mm:ss").format(new Date(time));
-    }
-
-    // Pauses for the specified number of millis.
-    private static void pause(int ms) {
-        try {
-            Thread.sleep(ms);
-        } catch (InterruptedException e) {
-            print("Interrupted!");
-        }
-    }
-
-    // Formats time duration
-    private static String formatDuration(int totalSeconds) {
-        int seconds = totalSeconds % 60;
-        int totalMinutes = totalSeconds / 60;
-        int minutes = totalMinutes % 60;
-        int hours = totalMinutes / 60;
-        return hours > 0 ?
-                String.format("%d:%02d:%02d", hours, minutes, seconds) :
-                String.format("%d:%02d", minutes, seconds);
-    }
-
-    // Shutdown hook to report status even when aborted.
-    private class ShutdownHook extends Thread {
-        @Override
-        public void run() {
-            printSummary(1, true);
-        }
-    }
-
-    // Logger to quiet Jetty down
-    private static class NullLogger implements Logger {
-        @Override
-        public String getName() {
-            return "quiet";
-        }
-
-        @Override
-        public void warn(String msg, Object... args) {
-        }
-
-        @Override
-        public void warn(Throwable thrown) {
-        }
-
-        @Override
-        public void warn(String msg, Throwable thrown) {
-        }
-
-        @Override
-        public void info(String msg, Object... args) {
-        }
-
-        @Override
-        public void info(Throwable thrown) {
-        }
-
-        @Override
-        public void info(String msg, Throwable thrown) {
-        }
-
-        @Override
-        public boolean isDebugEnabled() {
-            return false;
-        }
-
-        @Override
-        public void setDebugEnabled(boolean enabled) {
-        }
-
-        @Override
-        public void debug(String msg, Object... args) {
-        }
-
-        @Override
-        public void debug(Throwable thrown) {
-        }
-
-        @Override
-        public void debug(String msg, Throwable thrown) {
-        }
-
-        @Override
-        public Logger getLogger(String name) {
-            return this;
-        }
-
-        @Override
-        public void ignore(Throwable ignored) {
-        }
-    }
-}
diff --git a/utils/stc/src/main/java/org/onlab/stc/Monitor.java b/utils/stc/src/main/java/org/onlab/stc/Monitor.java
deleted file mode 100644
index 371e0d2..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/Monitor.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.collect.Maps;
-import org.onlab.stc.MonitorLayout.Box;
-
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Map;
-
-import static org.onlab.stc.Coordinator.Status.IN_PROGRESS;
-
-/**
- * Scenario test monitor.
- */
-public class Monitor implements StepProcessListener {
-
-    private final ObjectMapper mapper = new ObjectMapper();
-
-    private final Coordinator coordinator;
-    private final Compiler compiler;
-    private final MonitorLayout layout;
-
-    private MonitorDelegate delegate;
-
-    private Map<Step, Box> boxes = Maps.newHashMap();
-
-    /**
-     * Creates a new shared process flow monitor.
-     *
-     * @param coordinator process flow coordinator
-     * @param compiler    scenario compiler
-     */
-    Monitor(Coordinator coordinator, Compiler compiler) {
-        this.coordinator = coordinator;
-        this.compiler = compiler;
-        this.layout = new MonitorLayout(compiler);
-        coordinator.addListener(this);
-    }
-
-    /**
-     * Sets the process monitor delegate.
-     *
-     * @param delegate process monitor delegate
-     */
-    void setDelegate(MonitorDelegate delegate) {
-        this.delegate = delegate;
-    }
-
-    /**
-     * Notifies the process monitor delegate with the specified event.
-     *
-     * @param event JSON event data
-     */
-    public void notify(ObjectNode event) {
-        if (delegate != null) {
-            delegate.notify(event);
-        }
-    }
-
-    /**
-     * Returns the scenario process flow as JSON data.
-     *
-     * @return scenario process flow data
-     */
-    ObjectNode scenarioData() {
-        ObjectNode root = mapper.createObjectNode();
-        ArrayNode steps = mapper.createArrayNode();
-        ArrayNode requirements = mapper.createArrayNode();
-
-        ProcessFlow pf = compiler.processFlow();
-        pf.getVertexes().forEach(step -> add(step, steps));
-        pf.getEdges().forEach(requirement -> add(requirement, requirements));
-
-        root.set("steps", steps);
-        root.set("requirements", requirements);
-
-        try (FileWriter fw = new FileWriter("/tmp/data.json");
-             PrintWriter pw = new PrintWriter(fw)) {
-            pw.println(root.toString());
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return root;
-    }
-
-
-    private void add(Step step, ArrayNode steps) {
-        Box box = layout.get(step);
-        ObjectNode sn = mapper.createObjectNode()
-                .put("name", step.name())
-                .put("isGroup", step instanceof Group)
-                .put("status", status(coordinator.getStatus(step)))
-                .put("tier", box.tier())
-                .put("depth", box.depth());
-        if (step.group() != null) {
-            sn.put("group", step.group().name());
-        }
-        steps.add(sn);
-    }
-
-    private String status(Coordinator.Status status) {
-        return status.toString().toLowerCase();
-    }
-
-    private void add(Dependency requirement, ArrayNode requirements) {
-        ObjectNode rn = mapper.createObjectNode();
-        rn.put("src", requirement.src().name())
-                .put("dst", requirement.dst().name())
-                .put("isSoft", requirement.isSoft());
-        requirements.add(rn);
-    }
-
-    @Override
-    public void onStart(Step step, String command) {
-        notify(event(step, status(IN_PROGRESS)));
-    }
-
-    @Override
-    public void onCompletion(Step step, Coordinator.Status status) {
-        notify(event(step, status(status)));
-    }
-
-    @Override
-    public void onOutput(Step step, String line) {
-
-    }
-
-    private ObjectNode event(Step step, String status) {
-        ObjectNode event = mapper.createObjectNode()
-                .put("name", step.name())
-                .put("status", status);
-        return event;
-    }
-
-}
diff --git a/utils/stc/src/main/java/org/onlab/stc/MonitorDelegate.java b/utils/stc/src/main/java/org/onlab/stc/MonitorDelegate.java
deleted file mode 100644
index 8643f6d..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/MonitorDelegate.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-/**
- * Delegate to which monitor can send notifications.
- */
-public interface MonitorDelegate {
-
-    /**
-     * Issues JSON event to be sent to any connected monitor clients.
-     *
-     * @param event JSON event data
-     */
-    void notify(ObjectNode event);
-}
diff --git a/utils/stc/src/main/java/org/onlab/stc/MonitorLayout.java b/utils/stc/src/main/java/org/onlab/stc/MonitorLayout.java
deleted file mode 100644
index 0b4d130..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/MonitorLayout.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
-/**
- * Computes scenario process flow layout for the Monitor GUI.
- */
-public class MonitorLayout {
-
-    public static final int WIDTH = 210;
-    public static final int HEIGHT = 30;
-    public static final int W_GAP = 40;
-    public static final int H_GAP = 50;
-    public static final int SLOT_WIDTH = WIDTH + H_GAP;
-
-    private final Compiler compiler;
-    private final ProcessFlow flow;
-
-    private Map<Step, Box> boxes = Maps.newHashMap();
-
-    /**
-     * Creates a new shared process flow monitor.
-     *
-     * @param compiler scenario compiler
-     */
-    MonitorLayout(Compiler compiler) {
-        this.compiler = compiler;
-        this.flow = compiler.processFlow();
-
-        // Extract the flow and create initial bounding boxes.
-        boxes.put(null, new Box(null, 0));
-        flow.getVertexes().forEach(this::createBox);
-
-        computeLayout(null, 0, 1);
-    }
-
-    // Computes the graph layout giving preference to group associations.
-    private void computeLayout(Group group, int absoluteTier, int tier) {
-        Box box = boxes.get(group);
-
-        // Find all children of the group, or items with no group if at top.
-        Set<Step> children = group != null ? group.children() :
-                flow.getVertexes().stream().filter(s -> s.group() == null)
-                        .collect(Collectors.toSet());
-
-        children.forEach(s -> visit(s, absoluteTier, 1, group));
-
-        // Figure out what the group root vertexes are.
-        Set<Step> roots = findRoots(group);
-
-        // Compute the boxes for each of the roots.
-        roots.forEach(s -> updateBox(s, absoluteTier + 1, 1, group));
-
-        // Update the tier and depth of the group bounding box.
-        computeTiersAndDepth(group, box, absoluteTier, tier, children);
-
-        // Compute the minimum breadth of this group's bounding box.
-        computeBreadth(group, box, children);
-
-        // Compute child placements
-        computeChildPlacements(group, box, children);
-    }
-
-    // Updates the box for the specified step, given the tier number, which
-    // is relative to the parent.
-    private Box updateBox(Step step, int absoluteTier, int tier, Group group) {
-        Box box = boxes.get(step);
-        if (step instanceof Group) {
-            computeLayout((Group) step, absoluteTier, tier);
-        } else {
-            box.setTierAndDepth(absoluteTier, tier, 1, group);
-        }
-
-        // Follow the steps downstream of this one.
-        follow(step, absoluteTier + box.depth(), box.tier() + box.depth());
-        return box;
-    }
-
-    // Backwards follows edges leading towards the specified step to visit
-    // the source vertex and compute layout of those vertices that had
-    // sufficient number of visits to compute their tier.
-    private void follow(Step step, int absoluteTier, int tier) {
-        Group from = step.group();
-        flow.getEdgesTo(step).stream()
-                .filter(d -> visit(d.src(), absoluteTier, tier, from))
-                .forEach(d -> updateBox(d.src(), absoluteTier, tier, from));
-    }
-
-    // Visits each step, records maximum tier and returns true if this
-    // was the last expected visit.
-    private boolean visit(Step step, int absoluteTier, int tier, Group from) {
-        Box box = boxes.get(step);
-        return box.visitAndLatchMaxTier(absoluteTier, tier, from);
-    }
-
-    // Computes the absolute and relative tiers and the depth of the group
-    // bounding box.
-    private void computeTiersAndDepth(Group group, Box box,
-                                      int absoluteTier, int tier, Set<Step> children) {
-        int depth = children.stream().mapToInt(this::bottomMostTier).max().getAsInt();
-        box.setTierAndDepth(absoluteTier, tier, depth, group);
-    }
-
-    // Returns the bottom-most tier this step occupies relative to its parent.
-    private int bottomMostTier(Step step) {
-        Box box = boxes.get(step);
-        return box.tier() + box.depth();
-    }
-
-    // Computes breadth of the specified group.
-    private void computeBreadth(Group group, Box box, Set<Step> children) {
-        if (box.breadth() == 0) {
-            // Scan through all tiers and determine the maximum breadth of each.
-            IntStream.range(1, box.depth)
-                    .forEach(t -> computeTierBreadth(t, box, children));
-            box.latchBreadth(children.stream()
-                                     .mapToInt(s -> boxes.get(s).breadth())
-                                     .max().getAsInt());
-        }
-    }
-
-    // Computes tier width.
-    private void computeTierBreadth(int t, Box box, Set<Step> children) {
-        box.latchBreadth(children.stream().map(boxes::get)
-                                 .filter(b -> isSpanningTier(b, t))
-                                 .mapToInt(Box::breadth).sum());
-    }
-
-    // Computes the actual child box placements relative to the parent using
-    // the previously established tier, depth and breadth attributes.
-    private void computeChildPlacements(Group group, Box box,
-                                        Set<Step> children) {
-        // Order the root-nodes in alphanumeric order first.
-        List<Box> tierBoxes = Lists.newArrayList(boxesOnTier(1, children));
-        tierBoxes.sort((a, b) -> a.step().name().compareTo(b.step().name()));
-
-        // Place the boxes centered on the parent box; left to right.
-        int tierBreadth = tierBoxes.stream().mapToInt(Box::breadth).sum();
-        int slot = 1;
-        for (Box b : tierBoxes) {
-            b.updateCenter(1, slot(slot, tierBreadth));
-            slot += b.breadth();
-        }
-    }
-
-    // Returns the horizontal offset off the parent center.
-    private int slot(int slot, int tierBreadth) {
-        boolean even = tierBreadth % 2 == 0;
-        int multiplier = -tierBreadth / 2 + slot - 1;
-        return even ? multiplier * SLOT_WIDTH + SLOT_WIDTH / 2 : multiplier * SLOT_WIDTH;
-    }
-
-    // Returns a list of all child step boxes that start on the specified tier.
-    private List<Box> boxesOnTier(int tier, Set<Step> children) {
-        return boxes.values().stream()
-                .filter(b -> b.tier() == tier && children.contains(b.step()))
-                .collect(Collectors.toList());
-    }
-
-    // Determines whether the specified box spans, or occupies a tier.
-    private boolean isSpanningTier(Box b, int tier) {
-        return (b.depth() == 1 && b.tier() == tier) ||
-                (b.tier() <= tier && tier < b.tier() + b.depth());
-    }
-
-
-    // Determines roots of the specified group or of the entire graph.
-    private Set<Step> findRoots(Group group) {
-        Set<Step> steps = group != null ? group.children() : flow.getVertexes();
-        return steps.stream().filter(s -> isRoot(s, group)).collect(Collectors.toSet());
-    }
-
-    private boolean isRoot(Step step, Group group) {
-        if (step.group() != group) {
-            return false;
-        }
-
-        Set<Dependency> requirements = flow.getEdgesFrom(step);
-        return requirements.stream().filter(r -> r.dst().group() == group)
-                .collect(Collectors.toSet()).isEmpty();
-    }
-
-    /**
-     * Returns the bounding box for the specified step. If null is given, it
-     * returns the overall bounding box.
-     *
-     * @param step step or group; null for the overall bounding box
-     * @return bounding box
-     */
-    public Box get(Step step) {
-        return boxes.get(step);
-    }
-
-    /**
-     * Returns the bounding box for the specified step name. If null is given,
-     * it returns the overall bounding box.
-     *
-     * @param name name of step or group; null for the overall bounding box
-     * @return bounding box
-     */
-    public Box get(String name) {
-        return get(name == null ? null : compiler.getStep(name));
-    }
-
-    // Creates a bounding box for the specified step or group.
-    private void createBox(Step step) {
-        boxes.put(step, new Box(step, flow.getEdgesFrom(step).size()));
-    }
-
-    /**
-     * Bounding box data for a step or group.
-     */
-    final class Box {
-
-        private Step step;
-        private int remainingRequirements;
-
-        private int absoluteTier = 0;
-        private int tier;
-        private int depth = 1;
-        private int breadth;
-        private int center, top;
-
-        private Box(Step step, int remainingRequirements) {
-            this.step = step;
-            this.remainingRequirements = remainingRequirements + 1;
-            breadth = step == null || step instanceof Group ? 0 : 1;
-        }
-
-        private void latchTiers(int absoluteTier, int tier, Group from) {
-            this.absoluteTier = Math.max(this.absoluteTier, absoluteTier);
-            if (step == null || step.group() == from) {
-                this.tier = Math.max(this.tier, tier);
-            }
-        }
-
-        public void latchBreadth(int breadth) {
-            this.breadth = Math.max(this.breadth, breadth);
-        }
-
-        void setTierAndDepth(int absoluteTier, int tier, int depth, Group from) {
-            latchTiers(absoluteTier, tier, from);
-            this.depth = depth;
-        }
-
-        boolean visitAndLatchMaxTier(int absoluteTier, int tier, Group from) {
-            latchTiers(absoluteTier, tier, from);
-            --remainingRequirements;
-            return remainingRequirements == 0;
-        }
-
-        Step step() {
-            return step;
-        }
-
-        public int absoluteTier() {
-            return absoluteTier;
-        }
-
-        int tier() {
-            return tier;
-        }
-
-        int depth() {
-            return depth;
-        }
-
-        int breadth() {
-            return breadth;
-        }
-
-        int top() {
-            return top;
-        }
-
-        int center() {
-            return center;
-        }
-
-        public void updateCenter(int top, int center) {
-            this.top = top;
-            this.center = center;
-        }
-    }
-}
diff --git a/utils/stc/src/main/java/org/onlab/stc/MonitorWebSocket.java b/utils/stc/src/main/java/org/onlab/stc/MonitorWebSocket.java
deleted file mode 100644
index b6d14b0..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/MonitorWebSocket.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.eclipse.jetty.websocket.WebSocket;
-
-import java.io.IOException;
-
-import static org.onlab.stc.Coordinator.print;
-
-/**
- * Web socket capable of interacting with the STC monitor GUI.
- */
-public class MonitorWebSocket implements WebSocket.OnTextMessage, WebSocket.OnControl {
-
-    private static final long MAX_AGE_MS = 30_000;
-
-    private static final byte PING = 0x9;
-    private static final byte PONG = 0xA;
-    private static final byte[] PING_DATA = new byte[]{(byte) 0xde, (byte) 0xad};
-
-    private final Monitor monitor;
-
-    private Connection connection;
-    private FrameConnection control;
-
-    private final ObjectMapper mapper = new ObjectMapper();
-
-    private long lastActive = System.currentTimeMillis();
-
-    /**
-     * Creates a new monitor client GUI web-socket.
-     *
-     * @param monitor shared process flow monitor
-     */
-    MonitorWebSocket(Monitor monitor) {
-        this.monitor = monitor;
-    }
-
-    /**
-     * Issues a close on the connection.
-     */
-    synchronized void close() {
-        destroyHandlers();
-        if (connection.isOpen()) {
-            connection.close();
-        }
-    }
-
-    /**
-     * Indicates if this connection is idle.
-     *
-     * @return true if idle or closed
-     */
-    synchronized boolean isIdle() {
-        long quietFor = System.currentTimeMillis() - lastActive;
-        boolean idle = quietFor > MAX_AGE_MS;
-        if (idle || (connection != null && !connection.isOpen())) {
-            return true;
-        } else if (connection != null) {
-            try {
-                control.sendControl(PING, PING_DATA, 0, PING_DATA.length);
-            } catch (IOException e) {
-                print("Unable to send ping message due to: %s", e);
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public void onOpen(Connection connection) {
-        this.connection = connection;
-        this.control = (FrameConnection) connection;
-        try {
-            createHandlers();
-            sendMessage(message("flow", monitor.scenarioData()));
-
-        } catch (Exception e) {
-            print("Unable to open monitor connection: %s", e);
-            this.connection.close();
-            this.connection = null;
-            this.control = null;
-        }
-    }
-
-    @Override
-    public synchronized void onClose(int closeCode, String message) {
-        destroyHandlers();
-    }
-
-    @Override
-    public boolean onControl(byte controlCode, byte[] data, int offset, int length) {
-        lastActive = System.currentTimeMillis();
-        return true;
-    }
-
-    @Override
-    public void onMessage(String data) {
-        lastActive = System.currentTimeMillis();
-        try {
-            ObjectNode message = (ObjectNode) mapper.reader().readTree(data);
-            // TODO:
-            print("Got message: %s", message);
-        } catch (Exception e) {
-            print("Unable to parse GUI message %s due to %s", data, e);
-        }
-    }
-
-    public synchronized void sendMessage(ObjectNode message) {
-        try {
-            if (connection.isOpen()) {
-                connection.sendMessage(message.toString());
-            }
-        } catch (IOException e) {
-            print("Unable to send message %s to GUI due to %s", message, e);
-        }
-    }
-
-    public ObjectNode message(String type, ObjectNode payload) {
-        ObjectNode message = mapper.createObjectNode().put("event", type);
-        message.set("payload", payload);
-        return message;
-    }
-
-    // Creates new message handlers.
-    private synchronized void createHandlers() {
-    }
-
-    // Destroys message handlers.
-    private synchronized void destroyHandlers() {
-    }
-
-}
-
diff --git a/utils/stc/src/main/java/org/onlab/stc/MonitorWebSocketServlet.java b/utils/stc/src/main/java/org/onlab/stc/MonitorWebSocketServlet.java
deleted file mode 100644
index 2e45dc6..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/MonitorWebSocketServlet.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.io.ByteStreams;
-import com.google.common.net.MediaType;
-import org.eclipse.jetty.websocket.WebSocket;
-import org.eclipse.jetty.websocket.WebSocketServlet;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
-
-/**
- * Web socket servlet capable of creating web sockets for the STC monitor.
- */
-public class MonitorWebSocketServlet extends WebSocketServlet
-        implements MonitorDelegate {
-
-    private static final long PING_DELAY_MS = 5000;
-    private static final String DOT = ".";
-
-    private static Monitor monitor;
-    private static MonitorWebSocketServlet instance;
-
-    private final Set<MonitorWebSocket> sockets = new HashSet<>();
-    private final Timer timer = new Timer();
-    private final TimerTask pruner = new Pruner();
-
-    /**
-     * Binds the shared process flow monitor.
-     *
-     * @param m process monitor reference
-     */
-    public static void setMonitor(Monitor m) {
-        monitor = m;
-    }
-
-    /**
-     * Closes all currently open monitor web-sockets.
-     */
-    public static void closeAll() {
-        if (instance != null) {
-            instance.sockets.forEach(MonitorWebSocket::close);
-            instance.sockets.clear();
-        }
-    }
-
-    @Override
-    public void init() throws ServletException {
-        super.init();
-        instance = this;
-        monitor.setDelegate(this);
-        timer.schedule(pruner, PING_DELAY_MS, PING_DELAY_MS);
-    }
-
-    @Override
-    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
-            throws ServletException, IOException {
-        String uri = req.getRequestURI();
-        uri = uri.length() <= 1 ? "/index.html" : uri;
-        InputStream resource = getClass().getResourceAsStream(uri);
-        if (resource == null) {
-            resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
-        } else {
-            byte[] entity = ByteStreams.toByteArray(resource);
-            resp.setStatus(HttpServletResponse.SC_OK);
-            resp.setContentType(contentType(uri).toString());
-            resp.setContentLength(entity.length);
-            resp.getOutputStream().write(entity);
-        }
-    }
-
-    private MediaType contentType(String uri) {
-        int sep = uri.lastIndexOf(DOT);
-        String ext = sep > 0 ? uri.substring(sep + 1) : null;
-        return ext == null ? MediaType.APPLICATION_BINARY :
-                ext.equals("html") ? MediaType.HTML_UTF_8 :
-                        ext.equals("js") ? MediaType.JAVASCRIPT_UTF_8 :
-                                ext.equals("css") ? MediaType.CSS_UTF_8 :
-                                        MediaType.APPLICATION_BINARY;
-    }
-
-    @Override
-    public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
-        MonitorWebSocket socket = new MonitorWebSocket(monitor);
-        synchronized (sockets) {
-            sockets.add(socket);
-        }
-        return socket;
-    }
-
-    @Override
-    public void notify(ObjectNode event) {
-        if (instance != null) {
-            instance.sockets.forEach(ws -> ws.sendMessage(event));
-        }
-    }
-
-    // Task for pruning web-sockets that are idle.
-    private class Pruner extends TimerTask {
-        @Override
-        public void run() {
-            synchronized (sockets) {
-                Iterator<MonitorWebSocket> it = sockets.iterator();
-                while (it.hasNext()) {
-                    MonitorWebSocket socket = it.next();
-                    if (socket.isIdle()) {
-                        it.remove();
-                        socket.close();
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/utils/stc/src/main/java/org/onlab/stc/ProcessFlow.java b/utils/stc/src/main/java/org/onlab/stc/ProcessFlow.java
deleted file mode 100644
index 6561f5f..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/ProcessFlow.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import org.onlab.graph.MutableAdjacencyListsGraph;
-
-import java.util.Set;
-
-/**
- * Graph representation of a test process flow.
- */
-public class ProcessFlow extends MutableAdjacencyListsGraph<Step, Dependency> {
-
-    /**
-     * Creates a graph comprising of the specified vertexes and edges.
-     *
-     * @param vertexes set of graph vertexes
-     * @param edges    set of graph edges
-     */
-    public ProcessFlow(Set<Step> vertexes, Set<Dependency> edges) {
-        super(vertexes, edges);
-    }
-
-}
diff --git a/utils/stc/src/main/java/org/onlab/stc/Scenario.java b/utils/stc/src/main/java/org/onlab/stc/Scenario.java
deleted file mode 100644
index de373cc..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/Scenario.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.HierarchicalConfiguration;
-import org.apache.commons.configuration.XMLConfiguration;
-
-import java.io.InputStream;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-/**
- * Representation of a re-usable test scenario.
- */
-public final class Scenario {
-
-    private static final String SCENARIO = "scenario";
-    private static final String NAME = "[@name]";
-    private static final String DESCRIPTION = "[@description]";
-
-    private final String name;
-    private final String description;
-    private final HierarchicalConfiguration definition;
-
-    // Creates a new scenario from the specified definition.
-    private Scenario(String name, String description, HierarchicalConfiguration definition) {
-        this.name = checkNotNull(name, "Name cannot be null");
-        this.description = checkNotNull(description, "Description cannot be null");
-        this.definition = checkNotNull(definition, "Definition cannot be null");
-    }
-
-    /**
-     * Loads a new scenario from the specified hierarchical configuration.
-     *
-     * @param definition scenario definition
-     * @return loaded scenario
-     */
-    public static Scenario loadScenario(HierarchicalConfiguration definition) {
-        String name = definition.getString(NAME);
-        String description = definition.getString(DESCRIPTION, "");
-        checkState(name != null, "Scenario name must be specified");
-        return new Scenario(name, description, definition);
-    }
-
-    /**
-     * Loads a new scenario from the specified input stream.
-     *
-     * @param stream scenario definition stream
-     * @return loaded scenario
-     */
-    public static Scenario loadScenario(InputStream stream) {
-        XMLConfiguration cfg = new XMLConfiguration();
-        cfg.setAttributeSplittingDisabled(true);
-        cfg.setDelimiterParsingDisabled(true);
-        cfg.setRootElementName(SCENARIO);
-        try {
-            cfg.load(stream);
-            return loadScenario(cfg);
-        } catch (ConfigurationException e) {
-            throw new IllegalArgumentException("Unable to load scenario from the stream", e);
-        }
-    }
-
-    /**
-     * Returns the scenario name.
-     *
-     * @return scenario name
-     */
-    public String name() {
-        return name;
-    }
-
-    /**
-     * Returns the scenario description.
-     *
-     * @return scenario description
-     */
-    public String description() {
-        return description;
-    }
-
-    /**
-     * Returns the scenario definition.
-     *
-     * @return scenario definition
-     */
-    public HierarchicalConfiguration definition() {
-        return definition;
-    }
-
-}
diff --git a/utils/stc/src/main/java/org/onlab/stc/ScenarioStore.java b/utils/stc/src/main/java/org/onlab/stc/ScenarioStore.java
deleted file mode 100644
index 8b8e653..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/ScenarioStore.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.PropertiesConfiguration;
-import org.onlab.stc.Coordinator.Status;
-
-import java.io.File;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onlab.stc.Coordinator.Status.*;
-import static org.onlab.stc.Coordinator.print;
-
-/**
- * Maintains state of scenario execution.
- */
-class ScenarioStore {
-
-    private final ProcessFlow processFlow;
-    private final File storeFile;
-    private final File logDir;
-
-    private final List<StepEvent> events = Lists.newArrayList();
-    private final Map<String, Status> statusMap = Maps.newConcurrentMap();
-
-    private long startTime = Long.MAX_VALUE;
-    private long endTime = Long.MIN_VALUE;
-
-    /**
-     * Creates a new scenario store for the specified process flow.
-     *
-     * @param processFlow scenario process flow
-     * @param logDir      scenario log directory
-     * @param name        scenario name
-     */
-    ScenarioStore(ProcessFlow processFlow, File logDir, String name) {
-        this.processFlow = processFlow;
-        this.logDir = logDir;
-        this.storeFile = new File(logDir, name + ".stc");
-        load();
-    }
-
-    /**
-     * Resets status of all steps to waiting and clears all events.
-     */
-    void reset() {
-        events.clear();
-        statusMap.clear();
-        processFlow.getVertexes().forEach(step -> statusMap.put(step.name(), WAITING));
-        try {
-            removeLogs();
-            PropertiesConfiguration cfg = new PropertiesConfiguration(storeFile);
-            cfg.clear();
-            cfg.save();
-            startTime = Long.MAX_VALUE;
-            endTime = Long.MIN_VALUE;
-        } catch (ConfigurationException e) {
-            print("Unable to store file %s", storeFile);
-        }
-
-    }
-
-    /**
-     * Returns set of all test steps.
-     *
-     * @return set of steps
-     */
-    Set<Step> getSteps() {
-        return processFlow.getVertexes();
-    }
-
-    /**
-     * Returns a chronological list of step or group records.
-     *
-     * @return list of events
-     */
-    synchronized List<StepEvent> getEvents() {
-        return ImmutableList.copyOf(events);
-    }
-
-    /**
-     * Returns the status record of the specified test step.
-     *
-     * @param step test step or group
-     * @return step status record
-     */
-    Status getStatus(Step step) {
-        return checkNotNull(statusMap.get(step.name()), "Step %s not found", step.name());
-    }
-
-    /**
-     * Marks the specified test step as being in progress.
-     *
-     * @param step test step or group
-     */
-    synchronized void markStarted(Step step) {
-        add(new StepEvent(step.name(), IN_PROGRESS, step.command()));
-        save();
-    }
-
-    /**
-     * Marks the specified test step as being complete.
-     *
-     * @param step   test step or group
-     * @param status new step status
-     */
-    synchronized void markComplete(Step step, Status status) {
-        add(new StepEvent(step.name(), status, null));
-        save();
-    }
-
-    /**
-     * Returns true if all steps in the store have been marked as completed
-     * regardless of the completion status.
-     *
-     * @return true if all steps completed one way or another
-     */
-    synchronized boolean isComplete() {
-        return !statusMap.values().stream().anyMatch(s -> s == WAITING || s == IN_PROGRESS);
-    }
-
-    /**
-     * Indicates whether there are any failures.
-     *
-     * @return true if there are failed steps
-     */
-    boolean hasFailures() {
-        for (Status status : statusMap.values()) {
-            if (status == FAILED) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Registers a new step record.
-     *
-     * @param event step event
-     */
-    private synchronized void add(StepEvent event) {
-        events.add(event);
-        statusMap.put(event.name(), event.status());
-        startTime = Math.min(startTime, event.time());
-        endTime = Math.max(endTime, event.time());
-    }
-
-    /**
-     * Loads the states from disk.
-     */
-    private void load() {
-        try {
-            PropertiesConfiguration cfg = new PropertiesConfiguration(storeFile);
-            cfg.getKeys().forEachRemaining(prop -> add(StepEvent.fromString(cfg.getString(prop))));
-            cfg.save();
-        } catch (ConfigurationException e) {
-            print("Unable to load file %s", storeFile);
-        }
-    }
-
-    /**
-     * Saves the states to disk.
-     */
-    private void save() {
-        try {
-            PropertiesConfiguration cfg = new PropertiesConfiguration(storeFile);
-            events.forEach(event -> cfg.setProperty("T" + event.time(), event.toString()));
-            cfg.save();
-        } catch (ConfigurationException e) {
-            print("Unable to store file %s", storeFile);
-        }
-    }
-
-    /**
-     * Removes all scenario log files.
-     */
-    private void removeLogs() {
-        File[] logFiles = logDir.listFiles();
-        if (logFiles != null && logFiles.length > 0) {
-            for (File file : logFiles) {
-                if (!file.delete()) {
-                    print("Unable to delete log file %s", file);
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns the scenario run start time.
-     *
-     * @return start time in mills since start of epoch
-     */
-    public long startTime() {
-        return startTime;
-    }
-
-    /**
-     * Returns the scenario run end time or current time if the scenario
-     * is still running.
-     *
-     * @return end time (or current time) in mills since start of epoch
-     */
-    public long endTime() {
-        return endTime > 0 ? endTime : System.currentTimeMillis();
-    }
-}
diff --git a/utils/stc/src/main/java/org/onlab/stc/Step.java b/utils/stc/src/main/java/org/onlab/stc/Step.java
deleted file mode 100644
index 4fa03af..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/Step.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import com.google.common.base.MoreObjects;
-import org.onlab.graph.Vertex;
-
-import java.util.Objects;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Representation of a test step.
- */
-public class Step implements Vertex {
-
-    protected final String name;
-    protected final String command;
-    protected final String env;
-    protected final String cwd;
-    protected final Group group;
-    protected final int delay;
-
-    /**
-     * Creates a new test step.
-     *
-     * @param name    step name
-     * @param command step command to execute
-     * @param env     path to file to be sourced into the environment
-     * @param cwd     path to current working directory for the step
-     * @param group   optional group to which this step belongs
-     * @param delay   seconds to delay before executing
-     */
-    public Step(String name, String command, String env, String cwd, Group group, int delay) {
-        this.name = checkNotNull(name, "Name cannot be null");
-        this.group = group;
-        this.delay = delay;
-
-        // Set the command, environment and cwd
-        // If one is not given use the value from the enclosing group
-        this.command = command != null ? command : group != null && group.command != null ? group.command : null;
-        this.env = env != null ? env : group != null && group.env != null ? group.env : null;
-        this.cwd = cwd != null ? cwd : group != null && group.cwd != null ? group.cwd : null;
-    }
-
-    /**
-     * Returns the step name.
-     *
-     * @return step name
-     */
-    public String name() {
-        return name;
-    }
-
-    /**
-     * Returns the step command string.
-     *
-     * @return command string
-     */
-    public String command() {
-        return command;
-    }
-
-    /**
-     * Returns the step environment script path.
-     *
-     * @return env script path
-     */
-    public String env() {
-        return env;
-    }
-
-    /**
-     * Returns the step current working directory path.
-     *
-     * @return current working dir path
-     */
-    public String cwd() {
-        return cwd;
-    }
-
-    /**
-     * Returns the enclosing group; null if none.
-     *
-     * @return enclosing group or null
-     */
-    public Group group() {
-        return group;
-    }
-
-    /**
-     * Returns the start delay in seconds.
-     *
-     * @return number of seconds
-     */
-    public int delay() {
-        return delay;
-    }
-
-    @Override
-    public int hashCode() {
-        return name.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof Step) {
-            final Step other = (Step) obj;
-            return Objects.equals(this.name, other.name);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(this)
-                .add("name", name)
-                .add("command", command)
-                .add("env", env)
-                .add("cwd", cwd)
-                .add("group", group)
-                .add("delay", delay)
-                .toString();
-    }
-}
diff --git a/utils/stc/src/main/java/org/onlab/stc/StepEvent.java b/utils/stc/src/main/java/org/onlab/stc/StepEvent.java
deleted file mode 100644
index 692073f..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/StepEvent.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import org.onlab.stc.Coordinator.Status;
-
-import static java.lang.Long.parseLong;
-import static org.onlab.stc.Coordinator.Status.valueOf;
-
-/**
- * Represents an event of execution of a scenario step or group.
- */
-public class StepEvent {
-
-    private static final String SEP = "~";
-
-    private final String name;
-    private final long time;
-    private final Status status;
-    private final String command;
-
-    /**
-     * Creates a new step record.
-     *
-     * @param name    test step or group name
-     * @param time    time in millis since start of epoch
-     * @param status  step completion status
-     * @param command step command
-     */
-    public StepEvent(String name, long time, Status status, String command) {
-        this.name = name;
-        this.time = time;
-        this.status = status;
-        this.command = command;
-    }
-
-    /**
-     * Creates a new step record for non-running status.
-     *
-     * @param name    test step or group name
-     * @param status  status
-     * @param command step command
-     */
-    public StepEvent(String name, Status status, String command) {
-        this(name, System.currentTimeMillis(), status, command);
-    }
-
-    /**
-     * Returns the test step or test group name.
-     *
-     * @return step or group name
-     */
-    public String name() {
-        return name;
-    }
-
-    /**
-     * Returns the step event  time.
-     *
-     * @return time in millis since start of epoch
-     */
-    public long time() {
-        return time;
-    }
-
-    /**
-     * Returns the step completion status.
-     *
-     * @return completion status
-     */
-    public Status status() {
-        return status;
-    }
-
-    /**
-     * Returns the step command.
-     *
-     * @return step command
-     */
-    public String command() {
-        return command;
-    }
-
-
-    @Override
-    public String toString() {
-        return name + SEP + time + SEP + status + SEP + command;
-    }
-
-    /**
-     * Returns a record parsed from the specified string.
-     *
-     * @param string string encoding
-     * @return step record
-     */
-    public static StepEvent fromString(String string) {
-        String[] fields = string.split("~");
-        return fields.length == 4 ?
-                new StepEvent(fields[0], parseLong(fields[1]), valueOf(fields[2]),
-                              fields[3].equals("null") ? null : fields[3]) :
-                new StepEvent(fields[0], 0, Status.WAITING, null);
-    }
-}
diff --git a/utils/stc/src/main/java/org/onlab/stc/StepProcessListener.java b/utils/stc/src/main/java/org/onlab/stc/StepProcessListener.java
deleted file mode 100644
index 10381c4..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/StepProcessListener.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-/**
- * Entity capable of receiving notifications of process step execution events.
- */
-public interface StepProcessListener {
-
-    /**
-     * Indicates that process step has started.
-     *
-     * @param step    subject step
-     * @param command actual command executed; includes run-time substitutions
-     */
-    default void onStart(Step step, String command) {
-    }
-
-    /**
-     * Indicates that process step has completed.
-     *
-     * @param step   subject step
-     * @param status step completion status
-     */
-    default void onCompletion(Step step, Coordinator.Status status) {
-    }
-
-    /**
-     * Notifies when a new line of output becomes available.
-     *
-     * @param step subject step
-     * @param line line of output
-     */
-    default void onOutput(Step step, String line) {
-    }
-
-}
diff --git a/utils/stc/src/main/java/org/onlab/stc/StepProcessor.java b/utils/stc/src/main/java/org/onlab/stc/StepProcessor.java
deleted file mode 100644
index 3ef2ae5..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/StepProcessor.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import org.onlab.stc.Coordinator.Status;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.PrintWriter;
-
-import static java.lang.String.format;
-import static org.onlab.stc.Coordinator.Status.FAILED;
-import static org.onlab.stc.Coordinator.Status.SUCCEEDED;
-import static org.onlab.stc.Coordinator.print;
-
-/**
- * Manages execution of the specified step or a group.
- */
-class StepProcessor implements Runnable {
-
-    private static final String IGNORE_CODE = "~";
-    private static final String NEGATE_CODE = "!";
-
-    private static final int FAIL = -1;
-    private static final int SECONDS = 1_000;
-
-    static String launcher = "stc-launcher ";
-
-    private final Step step;
-    private final File logDir;
-    private String command;
-
-    private Process process;
-    private StepProcessListener delegate;
-
-    /**
-     * Creates a process monitor.
-     *
-     * @param step     step or group to be executed
-     * @param logDir   directory where step process log should be stored
-     * @param delegate process lifecycle listener
-     * @param command  actual command to execute
-     */
-    StepProcessor(Step step, File logDir, StepProcessListener delegate,
-                  String command) {
-        this.step = step;
-        this.logDir = logDir;
-        this.delegate = delegate;
-        this.command = command;
-    }
-
-    @Override
-    public void run() {
-        delegate.onStart(step, command);
-        delayIfNeeded();
-        int code = execute();
-        boolean ignoreCode = step.env() != null && step.env.equals(IGNORE_CODE);
-        boolean negateCode = step.env() != null && step.env.equals(NEGATE_CODE);
-        Status status = ignoreCode || code == 0 && !negateCode || code != 0 && negateCode ?
-                SUCCEEDED : FAILED;
-        delegate.onCompletion(step, status);
-    }
-
-    /**
-     * Pauses if the step requires it.
-     */
-    private void delayIfNeeded() {
-        if (step.delay() > 0) {
-            try {
-                Thread.sleep(step.delay() * SECONDS);
-            } catch (InterruptedException e) {
-                throw new RuntimeException("Interrupted", e);
-            }
-        }
-    }
-
-    /**
-     * Executes the step process.
-     *
-     * @return exit code
-     */
-    private int execute() {
-        try (PrintWriter pw = new PrintWriter(logFile())) {
-            process = Runtime.getRuntime().exec(command());
-            processOutput(pw);
-
-            // Wait for the process to complete and get its exit code.
-            if (process.isAlive()) {
-                process.waitFor();
-            }
-            return process.exitValue();
-
-        } catch (IOException e) {
-            print("Unable to run step %s using command %s", step.name(), step.command());
-        } catch (InterruptedException e) {
-            print("Step %s interrupted", step.name());
-        }
-        return FAIL;
-    }
-
-    /**
-     * Returns ready-to-run command for the step.
-     *
-     * @return command to execute
-     */
-    private String command() {
-        return format("%s %s %s %s", launcher,
-                      step.env() != null ? step.env() : "-",
-                      step.cwd() != null ? step.cwd() : "-",
-                      command);
-    }
-
-    /**
-     * Captures output of the step process.
-     *
-     * @param pw print writer to send output to
-     * @throws IOException if unable to read output or write logs
-     */
-    private void processOutput(PrintWriter pw) throws IOException {
-        InputStream out = process.getInputStream();
-        BufferedReader br = new BufferedReader(new InputStreamReader(out));
-
-        // Slurp its combined stderr/stdout
-        String line;
-        while ((line = br.readLine()) != null) {
-            pw.println(line);
-            delegate.onOutput(step, line);
-        }
-    }
-
-    /**
-     * Returns the log file for the step output.
-     *
-     * @return log file
-     */
-    private File logFile() {
-        return new File(logDir, step.name() + ".log");
-    }
-
-}
diff --git a/utils/stc/src/main/java/org/onlab/stc/package-info.java b/utils/stc/src/main/java/org/onlab/stc/package-info.java
deleted file mode 100644
index cd4ddb0..0000000
--- a/utils/stc/src/main/java/org/onlab/stc/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2015-present 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.
- */
-
-/**
- * System Test Coordinator tool for modular scenario-based testing.
- */
-package org.onlab.stc;
\ No newline at end of file
diff --git a/utils/stc/src/main/resources/data.json b/utils/stc/src/main/resources/data.json
deleted file mode 100644
index f582374..0000000
--- a/utils/stc/src/main/resources/data.json
+++ /dev/null
@@ -1,1087 +0,0 @@
-{
-    "requirements": [
-        {
-            "dst": "Reactive-Forwarding.Ping-2",
-            "isSoft": false,
-            "src": "Reactive-Forwarding.Link-2-Down"
-        },
-        {
-            "dst": "Final-Check-Logs-2",
-            "isSoft": true,
-            "src": "Fetch-Logs-2"
-        },
-        {
-            "dst": "Host-Intent.Ping-4",
-            "isSoft": false,
-            "src": "Host-Intent.Link-2-Up"
-        },
-        {
-            "dst": "Install-1",
-            "isSoft": false,
-            "src": "Wait-for-Start-1"
-        },
-        {
-            "dst": "Host-Intent.Link-1-Down",
-            "isSoft": false,
-            "src": "Host-Intent.Ping-2"
-        },
-        {
-            "dst": "Host-Intent.Link-2-Up",
-            "isSoft": false,
-            "src": "Host-Intent.Ping-5"
-        },
-        {
-            "dst": "Host-Intent.Ping-2",
-            "isSoft": false,
-            "src": "Host-Intent.Link-2-Down"
-        },
-        {
-            "dst": "Reinstall-App-With-CLI",
-            "isSoft": false,
-            "src": "Verify-CLI"
-        },
-        {
-            "dst": "Create-App-UI-Overlay",
-            "isSoft": false,
-            "src": "Build-App-With-UI"
-        },
-        {
-            "dst": "Secure-SSH",
-            "isSoft": true,
-            "src": "Wait-for-Start-1"
-        },
-        {
-            "dst": "Pause-For-Masters",
-            "isSoft": true,
-            "src": "Check-Flows"
-        },
-        {
-            "dst": "Secure-SSH",
-            "isSoft": true,
-            "src": "Wait-for-Start-3"
-        },
-        {
-            "dst": "Uninstall-3",
-            "isSoft": false,
-            "src": "Kill-3"
-        },
-        {
-            "dst": "Balance-Masters",
-            "isSoft": false,
-            "src": "Pause-For-Masters"
-        },
-        {
-            "dst": "Reactive-Forwarding.Net-Pingall",
-            "isSoft": true,
-            "src": "Reactive-Forwarding.Net-Link-Down-Up"
-        },
-        {
-            "dst": "Wait-for-Start-3",
-            "isSoft": true,
-            "src": "Check-Logs-3"
-        },
-        {
-            "dst": "Wait-for-Start-2",
-            "isSoft": true,
-            "src": "Check-Components-2"
-        },
-        {
-            "dst": "Uninstall-Reactive-Forwarding",
-            "isSoft": false,
-            "src": "Find-Host-1"
-        },
-        {
-            "dst": "Wipe-Out-Data-Before",
-            "isSoft": true,
-            "src": "Initial-Summary-Check"
-        },
-        {
-            "dst": "Reactive-Forwarding.Ping-3",
-            "isSoft": false,
-            "src": "Reactive-Forwarding.Link-1-Up"
-        },
-        {
-            "dst": "Archetypes",
-            "isSoft": true,
-            "src": "Wrapup"
-        },
-        {
-            "dst": "Reactive-Forwarding.Ping-4",
-            "isSoft": false,
-            "src": "Reactive-Forwarding.Link-2-Up"
-        },
-        {
-            "dst": "Host-Intent-Connectivity",
-            "isSoft": true,
-            "src": "Net-Teardown"
-        },
-        {
-            "dst": "Host-Intent.Ping-3",
-            "isSoft": false,
-            "src": "Host-Intent.Link-1-Up"
-        },
-        {
-            "dst": "Host-Intent.Ping-1",
-            "isSoft": false,
-            "src": "Host-Intent.Link-1-Down"
-        },
-        {
-            "dst": "Install-App",
-            "isSoft": false,
-            "src": "Create-App-CLI-Overlay"
-        },
-        {
-            "dst": "Final-Check-Logs-3",
-            "isSoft": true,
-            "src": "Fetch-Logs-3"
-        },
-        {
-            "dst": "Install-App",
-            "isSoft": false,
-            "src": "Verify-App"
-        },
-        {
-            "dst": "Host-Intent.Link-2-Down",
-            "isSoft": false,
-            "src": "Host-Intent.Ping-3"
-        },
-        {
-            "dst": "Prerequisites",
-            "isSoft": false,
-            "src": "Setup"
-        },
-        {
-            "dst": "Verify-App",
-            "isSoft": true,
-            "src": "Reinstall-App-With-CLI"
-        },
-        {
-            "dst": "Net-Smoke",
-            "isSoft": true,
-            "src": "Archetypes"
-        },
-        {
-            "dst": "Setup",
-            "isSoft": true,
-            "src": "Wrapup"
-        },
-        {
-            "dst": "Start-Mininet",
-            "isSoft": false,
-            "src": "Wait-For-Mininet"
-        },
-        {
-            "dst": "Verify-UI",
-            "isSoft": false,
-            "src": "Uninstall-App"
-        },
-        {
-            "dst": "Kill-3",
-            "isSoft": false,
-            "src": "Install-3"
-        },
-        {
-            "dst": "Wait-for-Start-1",
-            "isSoft": true,
-            "src": "Check-Components-1"
-        },
-        {
-            "dst": "Wait-for-Start-1",
-            "isSoft": true,
-            "src": "Check-Nodes-1"
-        },
-        {
-            "dst": "Push-Topos",
-            "isSoft": false,
-            "src": "Start-Mininet"
-        },
-        {
-            "dst": "Reactive-Forwarding.Check-Summary-For-Hosts",
-            "isSoft": true,
-            "src": "Reactive-Forwarding.Config-Topo"
-        },
-        {
-            "dst": "Reactive-Forwarding.Install-Apps",
-            "isSoft": false,
-            "src": "Reactive-Forwarding.Check-Apps"
-        },
-        {
-            "dst": "Push-Bits",
-            "isSoft": false,
-            "src": "Install-2"
-        },
-        {
-            "dst": "Install-1",
-            "isSoft": false,
-            "src": "Secure-SSH"
-        },
-        {
-            "dst": "Create-Intent",
-            "isSoft": false,
-            "src": "Host-Intent.Net-Link-Down-Up"
-        },
-        {
-            "dst": "Verify-CLI",
-            "isSoft": true,
-            "src": "Reinstall-App-With-UI"
-        },
-        {
-            "dst": "Wait-for-Start-3",
-            "isSoft": true,
-            "src": "Check-Apps-3"
-        },
-        {
-            "dst": "Net-Smoke",
-            "isSoft": true,
-            "src": "Wrapup"
-        },
-        {
-            "dst": "Initial-Summary-Check",
-            "isSoft": false,
-            "src": "Start-Mininet"
-        },
-        {
-            "dst": "Install-3",
-            "isSoft": false,
-            "src": "Wait-for-Start-3"
-        },
-        {
-            "dst": "Reactive-Forwarding.Link-1-Up",
-            "isSoft": false,
-            "src": "Reactive-Forwarding.Ping-4"
-        },
-        {
-            "dst": "Check-Summary",
-            "isSoft": true,
-            "src": "Balance-Masters"
-        },
-        {
-            "dst": "Reactive-Forwarding.Net-Link-Down-Up",
-            "isSoft": true,
-            "src": "Host-Intent-Connectivity"
-        },
-        {
-            "dst": "Secure-SSH",
-            "isSoft": true,
-            "src": "Wait-for-Start-2"
-        },
-        {
-            "dst": "Build-App-With-CLI",
-            "isSoft": false,
-            "src": "Reinstall-App-With-CLI"
-        },
-        {
-            "dst": "Uninstall-1",
-            "isSoft": false,
-            "src": "Kill-1"
-        },
-        {
-            "dst": "Find-Host-1",
-            "isSoft": false,
-            "src": "Find-Host-2"
-        },
-        {
-            "dst": "Create-App-CLI-Overlay",
-            "isSoft": false,
-            "src": "Build-App-With-CLI"
-        },
-        {
-            "dst": "Net-Setup",
-            "isSoft": false,
-            "src": "Reactive-Forwarding.Net-Link-Down-Up"
-        },
-        {
-            "dst": "Kill-2",
-            "isSoft": false,
-            "src": "Install-2"
-        },
-        {
-            "dst": "Wait-for-Start-1",
-            "isSoft": true,
-            "src": "Check-Logs-1"
-        },
-        {
-            "dst": "Wait-for-Start-2",
-            "isSoft": true,
-            "src": "Check-Nodes-2"
-        },
-        {
-            "dst": "Reactive-Forwarding.Ping-All-And-Verify",
-            "isSoft": true,
-            "src": "Reactive-Forwarding.Check-Summary-For-Hosts"
-        },
-        {
-            "dst": "Clean-Up",
-            "isSoft": false,
-            "src": "Create-App"
-        },
-        {
-            "dst": "Host-Intent.Link-1-Up",
-            "isSoft": false,
-            "src": "Host-Intent.Ping-4"
-        },
-        {
-            "dst": "Build-App-With-UI",
-            "isSoft": false,
-            "src": "Reinstall-App-With-UI"
-        },
-        {
-            "dst": "Install-2",
-            "isSoft": false,
-            "src": "Secure-SSH"
-        },
-        {
-            "dst": "Wait-For-Mininet",
-            "isSoft": false,
-            "src": "Check-Summary"
-        },
-        {
-            "dst": "Host-Intent.Net-Link-Down-Up",
-            "isSoft": false,
-            "src": "Remove-Intent"
-        },
-        {
-            "dst": "Net-Setup",
-            "isSoft": false,
-            "src": "Host-Intent-Connectivity"
-        },
-        {
-            "dst": "Net-Setup",
-            "isSoft": false,
-            "src": "Reactive-Forwarding.Net-Pingall"
-        },
-        {
-            "dst": "Reactive-Forwarding.Link-2-Down",
-            "isSoft": false,
-            "src": "Reactive-Forwarding.Ping-3"
-        },
-        {
-            "dst": "Find-Host-2",
-            "isSoft": false,
-            "src": "Create-Intent"
-        },
-        {
-            "dst": "Wait-for-Start-2",
-            "isSoft": true,
-            "src": "Check-Apps-2"
-        },
-        {
-            "dst": "Final-Check-Logs-1",
-            "isSoft": true,
-            "src": "Fetch-Logs-1"
-        },
-        {
-            "dst": "Install-2",
-            "isSoft": false,
-            "src": "Wait-for-Start-2"
-        },
-        {
-            "dst": "Reactive-Forwarding.Ping-1",
-            "isSoft": false,
-            "src": "Reactive-Forwarding.Link-1-Down"
-        },
-        {
-            "dst": "Create-App",
-            "isSoft": false,
-            "src": "Build-App"
-        },
-        {
-            "dst": "Check-Summary",
-            "isSoft": true,
-            "src": "Check-Flows"
-        },
-        {
-            "dst": "Build-App",
-            "isSoft": false,
-            "src": "Install-App"
-        },
-        {
-            "dst": "Reinstall-App-With-UI",
-            "isSoft": false,
-            "src": "Verify-UI"
-        },
-        {
-            "dst": "Uninstall-2",
-            "isSoft": false,
-            "src": "Kill-2"
-        },
-        {
-            "dst": "Setup",
-            "isSoft": false,
-            "src": "Archetypes"
-        },
-        {
-            "dst": "Setup",
-            "isSoft": false,
-            "src": "Net-Smoke"
-        },
-        {
-            "dst": "Kill-1",
-            "isSoft": false,
-            "src": "Install-1"
-        },
-        {
-            "dst": "Reactive-Forwarding.Link-1-Down",
-            "isSoft": false,
-            "src": "Reactive-Forwarding.Ping-2"
-        },
-        {
-            "dst": "Wait-for-Start-2",
-            "isSoft": true,
-            "src": "Check-Logs-2"
-        },
-        {
-            "dst": "Wait-for-Start-3",
-            "isSoft": true,
-            "src": "Check-Components-3"
-        },
-        {
-            "dst": "Wait-for-Start-3",
-            "isSoft": true,
-            "src": "Check-Nodes-3"
-        },
-        {
-            "dst": "Stop-Mininet-If-Needed",
-            "isSoft": false,
-            "src": "Start-Mininet"
-        },
-        {
-            "dst": "Reactive-Forwarding.Link-2-Up",
-            "isSoft": false,
-            "src": "Reactive-Forwarding.Ping-5"
-        },
-        {
-            "dst": "Reactive-Forwarding.Check-Apps",
-            "isSoft": false,
-            "src": "Reactive-Forwarding.Ping-All-And-Verify"
-        },
-        {
-            "dst": "Install-3",
-            "isSoft": false,
-            "src": "Secure-SSH"
-        },
-        {
-            "dst": "Push-Bits",
-            "isSoft": false,
-            "src": "Install-3"
-        },
-        {
-            "dst": "Reinstall-App-With-CLI",
-            "isSoft": false,
-            "src": "Create-App-UI-Overlay"
-        },
-        {
-            "dst": "Push-Bits",
-            "isSoft": false,
-            "src": "Install-1"
-        },
-        {
-            "dst": "Wait-for-Start-1",
-            "isSoft": true,
-            "src": "Check-Apps-1"
-        }
-    ],
-    "steps": [
-        {
-            "group": "Net-Setup",
-            "isGroup": false,
-            "name": "Check-Summary",
-            "status": "waiting"
-        },
-        {
-            "group": "Net-Setup",
-            "isGroup": false,
-            "name": "Check-Flows",
-            "status": "waiting"
-        },
-        {
-            "group": "Wrapup",
-            "isGroup": false,
-            "name": "Final-Check-Logs-1",
-            "status": "waiting"
-        },
-        {
-            "group": "Wrapup",
-            "isGroup": false,
-            "name": "Final-Check-Logs-2",
-            "status": "waiting"
-        },
-        {
-            "group": "Archetypes",
-            "isGroup": false,
-            "name": "Clean-Up",
-            "status": "waiting"
-        },
-        {
-            "group": "Archetypes",
-            "isGroup": false,
-            "name": "Build-App-With-UI",
-            "status": "waiting"
-        },
-        {
-            "group": "Archetypes",
-            "isGroup": false,
-            "name": "Uninstall-App",
-            "status": "waiting"
-        },
-        {
-            "group": "Wrapup",
-            "isGroup": false,
-            "name": "Final-Check-Logs-3",
-            "status": "waiting"
-        },
-        {
-            "group": "Host-Intent.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Host-Intent.Link-2-Down",
-            "status": "waiting"
-        },
-        {
-            "group": "Wrapup",
-            "isGroup": false,
-            "name": "Fetch-Logs-3",
-            "status": "waiting"
-        },
-        {
-            "group": "Wrapup",
-            "isGroup": false,
-            "name": "Fetch-Logs-2",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Check-Components-3",
-            "status": "waiting"
-        },
-        {
-            "group": "Wrapup",
-            "isGroup": false,
-            "name": "Fetch-Logs-1",
-            "status": "waiting"
-        },
-        {
-            "group": "Net-Setup",
-            "isGroup": false,
-            "name": "Push-Topos",
-            "status": "waiting"
-        },
-        {
-            "group": "Reactive-Forwarding.Net-Pingall",
-            "isGroup": false,
-            "name": "Reactive-Forwarding.Check-Apps",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Wait-for-Start-3",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Wait-for-Start-2",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Wait-for-Start-1",
-            "status": "waiting"
-        },
-        {
-            "group": "Net-Smoke",
-            "isGroup": true,
-            "name": "Host-Intent-Connectivity",
-            "status": "waiting"
-        },
-        {
-            "group": "Host-Intent-Connectivity",
-            "isGroup": false,
-            "name": "Create-Intent",
-            "status": "waiting"
-        },
-        {
-            "isGroup": true,
-            "name": "Prerequisites",
-            "status": "in_progress"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Push-Bits",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Check-Logs-2",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Check-Logs-3",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Kill-1",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Kill-3",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Kill-2",
-            "status": "waiting"
-        },
-        {
-            "group": "Host-Intent-Connectivity",
-            "isGroup": true,
-            "name": "Host-Intent.Net-Link-Down-Up",
-            "status": "waiting"
-        },
-        {
-            "group": "Host-Intent.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Host-Intent.Ping-1",
-            "status": "waiting"
-        },
-        {
-            "group": "Archetypes",
-            "isGroup": false,
-            "name": "Verify-UI",
-            "status": "waiting"
-        },
-        {
-            "group": "Host-Intent.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Host-Intent.Ping-2",
-            "status": "waiting"
-        },
-        {
-            "group": "Host-Intent.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Host-Intent.Ping-3",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Uninstall-1",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Check-Logs-1",
-            "status": "waiting"
-        },
-        {
-            "group": "Host-Intent.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Host-Intent.Ping-4",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Uninstall-3",
-            "status": "waiting"
-        },
-        {
-            "group": "Host-Intent.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Host-Intent.Ping-5",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Uninstall-2",
-            "status": "waiting"
-        },
-        {
-            "group": "Reactive-Forwarding.Net-Pingall",
-            "isGroup": false,
-            "name": "Reactive-Forwarding.Install-Apps",
-            "status": "waiting"
-        },
-        {
-            "group": "Net-Smoke",
-            "isGroup": true,
-            "name": "Reactive-Forwarding.Net-Link-Down-Up",
-            "status": "waiting"
-        },
-        {
-            "group": "Prerequisites",
-            "isGroup": false,
-            "name": "Check-ONOS-Bits",
-            "status": "in_progress"
-        },
-        {
-            "isGroup": true,
-            "name": "Wrapup",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Install-2",
-            "status": "waiting"
-        },
-        {
-            "group": "Host-Intent-Connectivity",
-            "isGroup": false,
-            "name": "Find-Host-1",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Install-1",
-            "status": "waiting"
-        },
-        {
-            "group": "Net-Setup",
-            "isGroup": false,
-            "name": "Wipe-Out-Data-Before",
-            "status": "waiting"
-        },
-        {
-            "group": "Net-Setup",
-            "isGroup": false,
-            "name": "Pause-For-Masters",
-            "status": "waiting"
-        },
-        {
-            "group": "Reactive-Forwarding.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Reactive-Forwarding.Link-2-Up",
-            "status": "waiting"
-        },
-        {
-            "group": "Net-Smoke",
-            "isGroup": true,
-            "name": "Reactive-Forwarding.Net-Pingall",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Check-Components-2",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Check-Components-1",
-            "status": "waiting"
-        },
-        {
-            "group": "Archetypes",
-            "isGroup": false,
-            "name": "Reinstall-App-With-UI",
-            "status": "waiting"
-        },
-        {
-            "group": "Archetypes",
-            "isGroup": false,
-            "name": "Reinstall-App-With-CLI",
-            "status": "waiting"
-        },
-        {
-            "group": "Archetypes",
-            "isGroup": false,
-            "name": "Build-App-With-CLI",
-            "status": "waiting"
-        },
-        {
-            "group": "Host-Intent-Connectivity",
-            "isGroup": false,
-            "name": "Uninstall-Reactive-Forwarding",
-            "status": "waiting"
-        },
-        {
-            "group": "Host-Intent.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Host-Intent.Link-2-Up",
-            "status": "waiting"
-        },
-        {
-            "group": "Net-Teardown",
-            "isGroup": false,
-            "name": "Stop-Mininet",
-            "status": "waiting"
-        },
-        {
-            "group": "Reactive-Forwarding.Net-Pingall",
-            "isGroup": false,
-            "name": "Reactive-Forwarding.Config-Topo",
-            "status": "waiting"
-        },
-        {
-            "group": "Archetypes",
-            "isGroup": false,
-            "name": "Create-App-CLI-Overlay",
-            "status": "waiting"
-        },
-        {
-            "group": "Reactive-Forwarding.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Reactive-Forwarding.Link-1-Down",
-            "status": "waiting"
-        },
-        {
-            "isGroup": true,
-            "name": "Net-Smoke",
-            "status": "waiting"
-        },
-        {
-            "group": "Prerequisites",
-            "isGroup": false,
-            "name": "Check-Passwordless-Login-2",
-            "status": "in_progress"
-        },
-        {
-            "group": "Prerequisites",
-            "isGroup": false,
-            "name": "Check-Passwordless-Login-1",
-            "status": "in_progress"
-        },
-        {
-            "group": "Prerequisites",
-            "isGroup": false,
-            "name": "Check-Passwordless-Login-3",
-            "status": "in_progress"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Secure-SSH",
-            "status": "waiting"
-        },
-        {
-            "group": "Net-Smoke",
-            "isGroup": true,
-            "name": "Net-Setup",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Check-Nodes-1",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Install-3",
-            "status": "waiting"
-        },
-        {
-            "group": "Host-Intent-Connectivity",
-            "isGroup": false,
-            "name": "Find-Host-2",
-            "status": "waiting"
-        },
-        {
-            "group": "Net-Setup",
-            "isGroup": false,
-            "name": "Initial-Summary-Check",
-            "status": "waiting"
-        },
-        {
-            "group": "Archetypes",
-            "isGroup": false,
-            "name": "Create-App",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Check-Nodes-3",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Check-Nodes-2",
-            "status": "waiting"
-        },
-        {
-            "group": "Reactive-Forwarding.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Reactive-Forwarding.Link-2-Down",
-            "status": "waiting"
-        },
-        {
-            "isGroup": true,
-            "name": "Setup",
-            "status": "waiting"
-        },
-        {
-            "group": "Archetypes",
-            "isGroup": false,
-            "name": "Verify-App",
-            "status": "waiting"
-        },
-        {
-            "group": "Reactive-Forwarding.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Reactive-Forwarding.Ping-1",
-            "status": "waiting"
-        },
-        {
-            "group": "Reactive-Forwarding.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Reactive-Forwarding.Ping-2",
-            "status": "waiting"
-        },
-        {
-            "group": "Net-Setup",
-            "isGroup": false,
-            "name": "Start-Mininet",
-            "status": "waiting"
-        },
-        {
-            "group": "Reactive-Forwarding.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Reactive-Forwarding.Ping-3",
-            "status": "waiting"
-        },
-        {
-            "group": "Reactive-Forwarding.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Reactive-Forwarding.Ping-4",
-            "status": "waiting"
-        },
-        {
-            "group": "Reactive-Forwarding.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Reactive-Forwarding.Ping-5",
-            "status": "waiting"
-        },
-        {
-            "group": "Archetypes",
-            "isGroup": false,
-            "name": "Verify-CLI",
-            "status": "waiting"
-        },
-        {
-            "group": "Reactive-Forwarding.Net-Pingall",
-            "isGroup": false,
-            "name": "Reactive-Forwarding.Check-Summary-For-Hosts",
-            "status": "waiting"
-        },
-        {
-            "group": "Net-Smoke",
-            "isGroup": true,
-            "name": "Net-Teardown",
-            "status": "waiting"
-        },
-        {
-            "group": "Host-Intent.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Host-Intent.Link-1-Up",
-            "status": "waiting"
-        },
-        {
-            "group": "Host-Intent-Connectivity",
-            "isGroup": false,
-            "name": "Remove-Intent",
-            "status": "waiting"
-        },
-        {
-            "group": "Archetypes",
-            "isGroup": false,
-            "name": "Install-App",
-            "status": "waiting"
-        },
-        {
-            "group": "Archetypes",
-            "isGroup": false,
-            "name": "Create-App-UI-Overlay",
-            "status": "waiting"
-        },
-        {
-            "group": "Reactive-Forwarding.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Reactive-Forwarding.Link-1-Up",
-            "status": "waiting"
-        },
-        {
-            "group": "Net-Setup",
-            "isGroup": false,
-            "name": "Wait-For-Mininet",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Check-Apps-3",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Check-Apps-2",
-            "status": "waiting"
-        },
-        {
-            "group": "Setup",
-            "isGroup": false,
-            "name": "Check-Apps-1",
-            "status": "waiting"
-        },
-        {
-            "group": "Net-Setup",
-            "isGroup": false,
-            "name": "Stop-Mininet-If-Needed",
-            "status": "waiting"
-        },
-        {
-            "group": "Prerequisites",
-            "isGroup": false,
-            "name": "Check-Environment",
-            "status": "in_progress"
-        },
-        {
-            "isGroup": true,
-            "name": "Archetypes",
-            "status": "waiting"
-        },
-        {
-            "group": "Host-Intent.Net-Link-Down-Up",
-            "isGroup": false,
-            "name": "Host-Intent.Link-1-Down",
-            "status": "waiting"
-        },
-        {
-            "group": "Net-Setup",
-            "isGroup": false,
-            "name": "Balance-Masters",
-            "status": "waiting"
-        },
-        {
-            "group": "Reactive-Forwarding.Net-Pingall",
-            "isGroup": false,
-            "name": "Reactive-Forwarding.Ping-All-And-Verify",
-            "status": "waiting"
-        },
-        {
-            "group": "Archetypes",
-            "isGroup": false,
-            "name": "Build-App",
-            "status": "waiting"
-        }
-    ]
-}
diff --git a/utils/stc/src/main/resources/index.html b/utils/stc/src/main/resources/index.html
deleted file mode 100644
index a81bd1f..0000000
--- a/utils/stc/src/main/resources/index.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<!--
-  ~ Copyright 2015-present 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.
-  -->
-<html>
-<head lang="en">
-    <meta charset="utf-8">
-    <title>Scenario Test Coordinator</title>
-
-    <link rel="stylesheet" href="stc.css">
-
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
-    <script src="stc.js"></script>
-</head>
-<body>
-</body>
-</html>
\ No newline at end of file
diff --git a/utils/stc/src/main/resources/stc.css b/utils/stc/src/main/resources/stc.css
deleted file mode 100644
index 8f65185..0000000
--- a/utils/stc/src/main/resources/stc.css
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2015-present 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.
- */
-
-.body {
-    font-family: Helvetica, Arial, sans-serif;
-}
-
-.node {
-    stroke: #fff;
-    stroke-width: 1.5px;
-}
-
-.link {
-    stroke: #999;
-    stroke-opacity: .6;
-}
-
-text {
-    font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif;
-    stroke: #000;
-    stroke-width: 0.2;
-    font-weight: normal;
-    font-size: 0.6em;
-}
\ No newline at end of file
diff --git a/utils/stc/src/main/resources/stc.js b/utils/stc/src/main/resources/stc.js
deleted file mode 100644
index 549c618..0000000
--- a/utils/stc/src/main/resources/stc.js
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright 2015-present 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.
- */
-(function () {
-
-    var ws, flow,
-        nodes = [],
-        links = [],
-        nodeIndexes = {};
-
-    var width = 2400,
-        height = 2400;
-
-    var color = d3.scale.category20();
-
-    var force = d3.layout.force()
-        .charge(-820)
-        .linkDistance(50)
-        .size([width, height]);
-
-    // Process flow graph layout
-    function createNode(n) {
-        nodeIndexes[n.name] = nodes.push(n) - 1;
-    }
-
-    function createLink(e) {
-        e.source = nodeIndexes[e.src];
-        e.target = nodeIndexes[e.dst];
-        links.push(e);
-    }
-
-    // Returns the newly computed bounding box of the rectangle
-    function adjustRectToFitText(n) {
-        var text = n.select('text'),
-            box = text.node().getBBox();
-
-        text.attr('text-anchor', 'left')
-            .attr('y', 2)
-            .attr('x', 4);
-
-        // add padding
-        box.x -= 4;
-        box.width += 8;
-        box.y -= 2;
-        box.height += 4;
-
-        n.select("rect").attr(box);
-    }
-
-    function processFlow() {
-        var svg = d3.select("body").append("svg")
-            .attr("width", width)
-            .attr("height", height);
-
-        flow.steps.forEach(createNode);
-        flow.requirements.forEach(createLink);
-
-        force
-            .nodes(nodes)
-            .links(links)
-            .start();
-
-        var link = svg.selectAll(".link")
-            .data(links)
-          .enter().append("line")
-            .attr("class", "link")
-            .style("stroke-width", function(d) { return d.isSoft ? 1 : 2; });
-
-        var node = svg.selectAll(".node")
-            .data(nodes)
-          .enter().append("g")
-            .attr("class", "node")
-            .call(force.drag);
-
-        node.append("rect")
-            .attr({ rx: 5, ry:5, width:180, height:18 })
-            .style("fill", function(d) { return color(d.group); });
-
-        node.append("text").text( function(d) { return d.name; })
-            .attr({ dy:"1.1em", width:100, height:16, x:4, y:2 });
-
-        node.append("title")
-            .text(function(d) { return d.name; });
-
-        force.on("tick", function() {
-            link.attr("x1", function(d) { return d.source.x; })
-                .attr("y1", function(d) { return d.source.y; })
-                .attr("x2", function(d) { return d.target.x; })
-                .attr("y2", function(d) { return d.target.y; });
-
-            node.attr("transform", function(d) { return "translate(" + (d.x - 180/2) + "," + (d.y - 18/2) + ")"; });
-        });
-    }
-
-
-    // Web socket callbacks
-
-    function handleOpen() {
-        console.log('WebSocket open');
-    }
-
-    // Handles the specified (incoming) message using handler bindings.
-    function handleMessage(msg) {
-        console.log('rx: ', msg);
-        evt = JSON.parse(msg.data);
-        if (evt.event === 'progress') {
-
-        } else if (evt.event === 'log') {
-
-        } else if (evt.event === 'flow') {
-            flow = evt.payload;
-            processFlow();
-        }
-    }
-
-    function handleClose() {
-        console.log('WebSocket closed');
-    }
-
-    if (false) {
-        d3.json("data.json", function (error, data) {
-            flow = data;
-            processFlow();
-        });
-        return;
-    }
-
-    // Open the web-socket
-    ws = new WebSocket(document.location.href.replace('http:', 'ws:'));
-    if (ws) {
-        ws.onopen = handleOpen;
-        ws.onmessage = handleMessage;
-        ws.onclose = handleClose;
-    }
-
-})();
\ No newline at end of file
diff --git a/utils/stc/src/test/java/org/onlab/stc/CompilerTest.java b/utils/stc/src/test/java/org/onlab/stc/CompilerTest.java
deleted file mode 100644
index ec9727f..0000000
--- a/utils/stc/src/test/java/org/onlab/stc/CompilerTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.util.Tools;
-
-import com.google.common.io.Files;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-import static com.google.common.io.ByteStreams.toByteArray;
-import static com.google.common.io.Files.write;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-import static org.onlab.stc.Scenario.loadScenario;
-
-/**
- * Test of the test scenario compiler.
- */
-public class CompilerTest {
-
-
-    private static File testDir;
-
-    @BeforeClass
-    public static void setUpClass() throws IOException {
-        testDir = Files.createTempDir();
-        stageTestResource("scenario.xml");
-        stageTestResource("simple-scenario.xml");
-        stageTestResource("one-scenario.xml");
-        stageTestResource("two-scenario.xml");
-
-        System.setProperty("prop.foo", "Foobar");
-        System.setProperty("prop.bar", "Barfoo");
-        System.setProperty("TOC1", "1.2.3.1");
-        System.setProperty("TOC2", "1.2.3.2");
-        System.setProperty("TOC3", "1.2.3.3");
-        System.setProperty("test.dir", testDir.getAbsolutePath());
-    }
-
-    @AfterClass
-    public static void tearDownClass() throws IOException {
-        Tools.removeDirectory(testDir.getPath());
-    }
-
-    static FileInputStream getStream(String name) throws FileNotFoundException {
-        return new FileInputStream(new File(testDir, name));
-    }
-
-    static void stageTestResource(String name) throws IOException {
-        byte[] bytes = toByteArray(CompilerTest.class.getResourceAsStream(name));
-        write(bytes, new File(testDir, name));
-    }
-
-    @Test
-    public void basics() throws Exception {
-        Scenario scenario = loadScenario(getStream("scenario.xml"));
-        Compiler compiler = new Compiler(scenario);
-        compiler.compile();
-        ProcessFlow flow = compiler.processFlow();
-
-        assertSame("incorrect scenario", scenario, compiler.scenario());
-        assertEquals("incorrect step count", 33, flow.getVertexes().size());
-        assertEquals("incorrect dependency count", 26, flow.getEdges().size());
-        assertEquals("incorrect logDir",
-                     new File(testDir.getAbsolutePath(), "foo"), compiler.logDir());
-
-        Step step = compiler.getStep("there");
-        assertEquals("incorrect edge count", 2, flow.getEdgesFrom(step).size());
-        assertEquals("incorrect edge count", 0, flow.getEdgesTo(step).size());
-
-        Step group = compiler.getStep("three");
-        assertEquals("incorrect edge count", 2, flow.getEdgesFrom(group).size());
-        assertEquals("incorrect edge count", 0, flow.getEdgesTo(group).size());
-    }
-
-}
\ No newline at end of file
diff --git a/utils/stc/src/test/java/org/onlab/stc/CoordinatorTest.java b/utils/stc/src/test/java/org/onlab/stc/CoordinatorTest.java
deleted file mode 100644
index 061ef7f..0000000
--- a/utils/stc/src/test/java/org/onlab/stc/CoordinatorTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.util.Tools;
-
-import java.io.IOException;
-
-import static org.onlab.stc.CompilerTest.getStream;
-import static org.onlab.stc.Coordinator.print;
-import static org.onlab.stc.Scenario.loadScenario;
-
-/**
- * Test of the test coordinator.
- */
-public class CoordinatorTest {
-
-    private Coordinator coordinator;
-    private StepProcessListener listener = new Listener();
-
-    @BeforeClass
-    public static void setUpClass() throws IOException {
-        CompilerTest.setUpClass();
-
-        StepProcessor.launcher = "true ";
-    }
-
-    @AfterClass
-    public static void tearDownClass() throws IOException {
-        CompilerTest.tearDownClass();
-    }
-
-    @Test
-    public void simple() throws IOException, InterruptedException {
-        executeTest("simple-scenario.xml");
-    }
-
-    @Test
-    public void complex() throws IOException, InterruptedException {
-        executeTest("scenario.xml");
-    }
-
-    private void executeTest(String name) throws IOException, InterruptedException {
-        Scenario scenario = loadScenario(getStream(name));
-        Compiler compiler = new Compiler(scenario);
-        compiler.compile();
-        Tools.removeDirectory(compiler.logDir());
-        coordinator = new Coordinator(scenario, compiler.processFlow(), compiler.logDir());
-        coordinator.addListener(listener);
-        coordinator.reset();
-        coordinator.start();
-        coordinator.waitFor();
-        coordinator.removeListener(listener);
-    }
-
-    private class Listener implements StepProcessListener {
-        @Override
-        public void onStart(Step step, String command) {
-            print("> %s: started; %s", step.name(), command);
-        }
-
-        @Override
-        public void onCompletion(Step step, Coordinator.Status status) {
-            print("< %s: %s", step.name(), status == Coordinator.Status.SUCCEEDED ? "completed" : "failed");
-        }
-
-        @Override
-        public void onOutput(Step step, String line) {
-            print("  %s: %s", step.name(), line);
-        }
-    }
-}
\ No newline at end of file
diff --git a/utils/stc/src/test/java/org/onlab/stc/DependencyTest.java b/utils/stc/src/test/java/org/onlab/stc/DependencyTest.java
deleted file mode 100644
index bb5d1cc..0000000
--- a/utils/stc/src/test/java/org/onlab/stc/DependencyTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import com.google.common.testing.EqualsTester;
-import org.apache.commons.configuration.ConfigurationException;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Test of the test step dependency.
- */
-public class DependencyTest extends StepTest {
-
-    protected Step step1, step2;
-
-    @Override
-    @Before
-    public void setUp() throws ConfigurationException {
-        super.setUp();
-        step1 = new Step("step1", CMD, null, null, null, 0);
-        step2 = new Step("step2", CMD, null, null, null, 0);
-    }
-
-    @Test
-    public void hard() {
-        Dependency hard = new Dependency(step1, step2, false);
-        assertSame("incorrect src", step1, hard.src());
-        assertSame("incorrect dst", step2, hard.dst());
-        assertFalse("incorrect isSoft", hard.isSoft());
-    }
-
-    @Test
-    public void soft() {
-        Dependency soft = new Dependency(step2, step1, true);
-        assertSame("incorrect src", step2, soft.src());
-        assertSame("incorrect dst", step1, soft.dst());
-        assertTrue("incorrect isSoft", soft.isSoft());
-    }
-
-    @Override
-    @Test
-    public void equality() {
-        Dependency d1 = new Dependency(step1, step2, false);
-        Dependency d2 = new Dependency(step1, step2, false);
-        Dependency d3 = new Dependency(step1, step2, true);
-        Dependency d4 = new Dependency(step2, step1, true);
-        new EqualsTester()
-                .addEqualityGroup(d1, d2)
-                .addEqualityGroup(d3)
-                .addEqualityGroup(d4)
-                .testEquals();
-    }
-
-}
\ No newline at end of file
diff --git a/utils/stc/src/test/java/org/onlab/stc/GroupTest.java b/utils/stc/src/test/java/org/onlab/stc/GroupTest.java
deleted file mode 100644
index 3533d84..0000000
--- a/utils/stc/src/test/java/org/onlab/stc/GroupTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import com.google.common.testing.EqualsTester;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-
-/**
- * Test of the test scenario entity.
- */
-public class GroupTest extends StepTest {
-
-    @Test
-    public void basics() {
-        Group group = new Group(NAME, CMD, ENV, CWD, parent, 1);
-        assertEquals("incorrect name", NAME, group.name());
-        assertEquals("incorrect command", CMD, group.command());
-        assertEquals("incorrect env", ENV, group.env());
-        assertEquals("incorrect cwd", CWD, group.cwd());
-        assertSame("incorrect group", parent, group.group());
-        assertEquals("incorrect delay", 1, group.delay());
-
-        Step step = new Step("step", null, null, null, group, 0);
-        group.addChild(step);
-        assertSame("incorrect child", step, group.children().iterator().next());
-    }
-
-    @Test
-    public void equality() {
-        Group g1 = new Group(NAME, CMD, null, null, parent, 0);
-        Group g2 = new Group(NAME, CMD, ENV, CWD, null, 0);
-        Group g3 = new Group("foo", null, null, null, parent, 0);
-        new EqualsTester()
-                .addEqualityGroup(g1, g2)
-                .addEqualityGroup(g3)
-                .testEquals();
-    }
-
-}
\ No newline at end of file
diff --git a/utils/stc/src/test/java/org/onlab/stc/MonitorLayoutTest.java b/utils/stc/src/test/java/org/onlab/stc/MonitorLayoutTest.java
deleted file mode 100644
index 0259971..0000000
--- a/utils/stc/src/test/java/org/onlab/stc/MonitorLayoutTest.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.stc.MonitorLayout.Box;
-
-import java.io.IOException;
-
-import static org.junit.Assert.assertEquals;
-import static org.onlab.stc.CompilerTest.getStream;
-import static org.onlab.stc.CompilerTest.stageTestResource;
-import static org.onlab.stc.MonitorLayout.SLOT_WIDTH;
-import static org.onlab.stc.Scenario.loadScenario;
-
-/**
- * Tests of the monitor layout functionality.
- */
-public class MonitorLayoutTest {
-
-    private MonitorLayout layout;
-
-    @BeforeClass
-    public static void setUpClass() throws IOException {
-        CompilerTest.setUpClass();
-    }
-
-    @AfterClass
-    public static void tearDownClass() throws IOException {
-        CompilerTest.tearDownClass();
-    }
-
-    private Compiler getCompiler(String name) throws IOException {
-        stageTestResource(name);
-        Scenario scenario = loadScenario(getStream(name));
-        Compiler compiler = new Compiler(scenario);
-        compiler.compile();
-        return compiler;
-    }
-
-    @Test
-    public void basic() throws IOException {
-        layout = new MonitorLayout(getCompiler("layout-basic.xml"));
-        validate(layout, null, 0, 1, 5, 2);
-        validate(layout, "a", 1, 1, 1, 1, 1, -SLOT_WIDTH / 2);
-        validate(layout, "b", 2, 2, 1, 1, 0, 0);
-        validate(layout, "f", 3, 3, 1);
-
-        validate(layout, "g", 1, 1, 4, 1, 1, SLOT_WIDTH / 2);
-        validate(layout, "c", 2, 1, 1);
-        validate(layout, "d", 3, 2, 1);
-        validate(layout, "e", 4, 3, 1);
-    }
-
-    @Test
-    public void basicNest() throws IOException {
-        layout = new MonitorLayout(getCompiler("layout-basic-nest.xml"));
-        validate(layout, null, 0, 1, 6, 2);
-        validate(layout, "a", 1, 1, 1, 1, 1, -SLOT_WIDTH / 2);
-        validate(layout, "b", 2, 2, 1);
-        validate(layout, "f", 3, 3, 1);
-
-        validate(layout, "g", 1, 1, 5, 1);
-        validate(layout, "c", 2, 1, 1);
-
-        validate(layout, "gg", 3, 2, 3, 1);
-        validate(layout, "d", 4, 1, 1);
-        validate(layout, "e", 5, 2, 1);
-    }
-
-    @Test
-    public void staggeredDependencies() throws IOException {
-        layout = new MonitorLayout(getCompiler("layout-staggered-dependencies.xml"));
-        validate(layout, null, 0, 1, 7, 4);
-        validate(layout, "a", 1, 1, 1, 1, 1, -SLOT_WIDTH - SLOT_WIDTH / 2);
-        validate(layout, "aa", 1, 1, 1, 1, 1, -SLOT_WIDTH / 2);
-        validate(layout, "b", 2, 2, 1);
-        validate(layout, "f", 3, 3, 1);
-
-        validate(layout, "g", 1, 1, 5, 2, 1, +SLOT_WIDTH / 2);
-        validate(layout, "c", 2, 1, 1);
-
-        validate(layout, "gg", 3, 2, 3, 2);
-        validate(layout, "d", 4, 1, 1);
-        validate(layout, "dd", 4, 1, 1);
-        validate(layout, "e", 5, 2, 1);
-
-        validate(layout, "i", 6, 6, 1);
-    }
-
-    @Test
-    public void deepNext() throws IOException {
-        layout = new MonitorLayout(getCompiler("layout-deep-nest.xml"));
-        validate(layout, null, 0, 1, 7, 6);
-        validate(layout, "a", 1, 1, 1);
-        validate(layout, "aa", 1, 1, 1);
-        validate(layout, "b", 2, 2, 1);
-        validate(layout, "f", 3, 3, 1);
-
-        validate(layout, "g", 1, 1, 5, 2);
-        validate(layout, "c", 2, 1, 1);
-
-        validate(layout, "gg", 3, 2, 3, 2);
-        validate(layout, "d", 4, 1, 1);
-        validate(layout, "dd", 4, 1, 1);
-        validate(layout, "e", 5, 2, 1);
-
-        validate(layout, "i", 6, 6, 1);
-
-        validate(layout, "g1", 1, 1, 6, 2);
-        validate(layout, "g2", 2, 1, 5, 2);
-        validate(layout, "g3", 3, 1, 4, 2);
-        validate(layout, "u", 4, 1, 1);
-        validate(layout, "v", 4, 1, 1);
-        validate(layout, "w", 5, 2, 1);
-        validate(layout, "z", 6, 3, 1);
-    }
-
-
-    private void validate(MonitorLayout layout, String name,
-                          int absoluteTier, int tier, int depth, int breadth) {
-        Box b = layout.get(name);
-        assertEquals("incorrect absolute tier", absoluteTier, b.absoluteTier());
-        assertEquals("incorrect tier", tier, b.tier());
-        assertEquals("incorrect depth", depth, b.depth());
-        assertEquals("incorrect breadth", breadth, b.breadth());
-    }
-
-    private void validate(MonitorLayout layout, String name,
-                          int absoluteTier, int tier, int depth, int breadth,
-                          int top, int center) {
-        validate(layout, name, absoluteTier, tier, depth, breadth);
-        Box b = layout.get(name);
-        assertEquals("incorrect top", top, b.top());
-        assertEquals("incorrect center", center, b.center());
-    }
-
-    private void validate(MonitorLayout layout, String name,
-                          int absoluteTier, int tier, int depth) {
-        validate(layout, name, absoluteTier, tier, depth, 1);
-    }
-
-}
\ No newline at end of file
diff --git a/utils/stc/src/test/java/org/onlab/stc/ScenarioTest.java b/utils/stc/src/test/java/org/onlab/stc/ScenarioTest.java
deleted file mode 100644
index 2c93b19..0000000
--- a/utils/stc/src/test/java/org/onlab/stc/ScenarioTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.onlab.stc.Scenario.loadScenario;
-
-/**
- * Test of the test scenario entity.
- */
-public class ScenarioTest {
-
-    @Test
-    public void basics() throws ConfigurationException {
-        Scenario scenario = loadScenario(getClass().getResourceAsStream("scenario.xml"));
-        assertEquals("incorrect name", "foo", scenario.name());
-        assertEquals("incorrect description", "Test Scenario", scenario.description());
-        assertEquals("incorrect logDir", "Test Scenario", scenario.description());
-        assertEquals("incorrect definition", "Test Scenario",
-                     scenario.definition().getString("[@description]"));
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void badStream() throws ConfigurationException {
-       loadScenario(getClass().getResourceAsStream("no.xml"));
-    }
-
-}
\ No newline at end of file
diff --git a/utils/stc/src/test/java/org/onlab/stc/StepProcessorTest.java b/utils/stc/src/test/java/org/onlab/stc/StepProcessorTest.java
deleted file mode 100644
index 23a5bbb..0000000
--- a/utils/stc/src/test/java/org/onlab/stc/StepProcessorTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import java.io.File;
-import static com.google.common.base.Preconditions.checkState;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.onlab.stc.Coordinator.Status.SUCCEEDED;
-
-/**
- * Test of the step processor.
- */
-public class StepProcessorTest {
-
-    @ClassRule
-    public static TemporaryFolder testFolder = new TemporaryFolder();
-
-    private static File dir;
-    private final Listener delegate = new Listener();
-
-    @BeforeClass
-    public static void setUpClass() {
-        dir = testFolder.getRoot();
-        StepProcessor.launcher = "echo";
-        checkState(dir.exists() || dir.mkdirs(), "Unable to create directory");
-    }
-
-    @Test
-    public void basics() {
-        Step step = new Step("foo", "ls " + dir.getAbsolutePath(), null, null, null, 0);
-        StepProcessor processor = new StepProcessor(step, dir, delegate, step.command());
-        processor.run();
-        assertTrue("should be started", delegate.started);
-        assertTrue("should be stopped", delegate.stopped);
-        assertEquals("incorrect status", SUCCEEDED, delegate.status);
-        assertTrue("should have output", delegate.output);
-    }
-
-    private class Listener implements StepProcessListener {
-
-        private Coordinator.Status status;
-        private boolean started, stopped, output;
-
-        @Override
-        public void onStart(Step step, String command) {
-            started = true;
-        }
-
-        @Override
-        public void onCompletion(Step step, Coordinator.Status status) {
-            stopped = true;
-            this.status = status;
-        }
-
-        @Override
-        public void onOutput(Step step, String line) {
-            output = true;
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/utils/stc/src/test/java/org/onlab/stc/StepTest.java b/utils/stc/src/test/java/org/onlab/stc/StepTest.java
deleted file mode 100644
index 0713afc..0000000
--- a/utils/stc/src/test/java/org/onlab/stc/StepTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2015-present 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.onlab.stc;
-
-import com.google.common.testing.EqualsTester;
-import org.apache.commons.configuration.ConfigurationException;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-
-/**
- * Test of the test step entity.
- */
-public class StepTest {
-
-    protected static final String NAME = "step";
-    protected static final String CMD = "command";
-    protected static final String ENV = "environment";
-    protected static final String CWD = "directory";
-    protected Group parent;
-
-    @Before
-    public void setUp() throws ConfigurationException {
-        parent = new Group("parent", null, null, null, null, 0);
-    }
-
-    @Test
-    public void basics() {
-        Step step = new Step(NAME, CMD, ENV, CWD, parent, 1);
-        assertEquals("incorrect name", NAME, step.name());
-        assertEquals("incorrect command", CMD, step.command());
-        assertEquals("incorrect env", ENV, step.env());
-        assertEquals("incorrect cwd", CWD, step.cwd());
-        assertSame("incorrect group", parent, step.group());
-        assertEquals("incorrect delay", 1, step.delay());
-    }
-
-    @Test
-    public void equality() {
-        Step s1 = new Step(NAME, CMD, null, null, parent, 0);
-        Step s2 = new Step(NAME, CMD, ENV, CWD, null, 0);
-        Step s3 = new Step("foo", null, null, null, parent, 0);
-        new EqualsTester()
-                .addEqualityGroup(s1, s2)
-                .addEqualityGroup(s3)
-                .testEquals();
-    }
-}
\ No newline at end of file
diff --git a/utils/stc/src/test/resources/org/onlab/stc/layout-basic-nest.xml b/utils/stc/src/test/resources/org/onlab/stc/layout-basic-nest.xml
deleted file mode 100644
index da8133d..0000000
--- a/utils/stc/src/test/resources/org/onlab/stc/layout-basic-nest.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-  ~ Copyright 2015-present 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.
-  -->
-<scenario name="basic-nest">
-    <step name="a"/>
-    <step name="b" requires="a"/>
-    <step name="f" requires="b"/>
-    <group name="g">
-        <step name="c"/>
-        <group name="gg" requires="c">
-            <step name="d"/>
-            <step name="e" requires="d"/>
-        </group>
-    </group>
-</scenario>
\ No newline at end of file
diff --git a/utils/stc/src/test/resources/org/onlab/stc/layout-basic.xml b/utils/stc/src/test/resources/org/onlab/stc/layout-basic.xml
deleted file mode 100644
index e822053..0000000
--- a/utils/stc/src/test/resources/org/onlab/stc/layout-basic.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-  ~ Copyright 2015-present 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.
-  -->
-<scenario name="basic">
-    <step name="a"/>
-    <step name="b" requires="a"/>
-    <step name="f" requires="b"/>
-    <group name="g">
-        <step name="c"/>
-        <step name="d" requires="c"/>
-        <step name="e" requires="d"/>
-    </group>
-</scenario>
\ No newline at end of file
diff --git a/utils/stc/src/test/resources/org/onlab/stc/layout-deep-nest.xml b/utils/stc/src/test/resources/org/onlab/stc/layout-deep-nest.xml
deleted file mode 100644
index b7ee4ae..0000000
--- a/utils/stc/src/test/resources/org/onlab/stc/layout-deep-nest.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<!--
-  ~ Copyright 2015-present 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.
-  -->
-<scenario name="basic-nest">
-    <step name="a"/>
-    <step name="aa"/>
-    <step name="b" requires="a"/>
-    <step name="f" requires="b,aa"/>
-    <group name="g">
-        <step name="c"/>
-        <group name="gg" requires="c">
-            <step name="d"/>
-            <step name="dd" requires="c"/>
-            <step name="e" requires="d"/>
-        </group>
-    </group>
-    <step name="i" requires="f,g"/>
-
-    <group name="g1">
-        <group name="g2">
-            <group name="g3">
-                <step name="u"/>
-                <step name="v"/>
-                <step name="w" requires="u,v"/>
-                <step name="z" requires="u,w"/>
-            </group>
-        </group>
-    </group>
-</scenario>
\ No newline at end of file
diff --git a/utils/stc/src/test/resources/org/onlab/stc/layout-staggered-dependencies.xml b/utils/stc/src/test/resources/org/onlab/stc/layout-staggered-dependencies.xml
deleted file mode 100644
index 15de145..0000000
--- a/utils/stc/src/test/resources/org/onlab/stc/layout-staggered-dependencies.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
-  ~ Copyright 2015-present 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.
-  -->
-<scenario name="basic-nest">
-    <step name="a"/>
-    <step name="aa"/>
-    <step name="b" requires="a"/>
-    <step name="f" requires="b,aa"/>
-    <group name="g">
-        <step name="c"/>
-        <group name="gg" requires="c">
-            <step name="d"/>
-            <step name="dd" requires="c"/>
-            <step name="e" requires="d"/>
-        </group>
-    </group>
-    <step name="i" requires="f,g"/>
-</scenario>
\ No newline at end of file
diff --git a/utils/stc/src/test/resources/org/onlab/stc/one-scenario.xml b/utils/stc/src/test/resources/org/onlab/stc/one-scenario.xml
deleted file mode 100644
index df12c36..0000000
--- a/utils/stc/src/test/resources/org/onlab/stc/one-scenario.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!--
-  ~ Copyright 2015-present 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.
-  -->
-
-<scenario name="one" description="" logDir="${test.dir}/junit-stc/one">
-    <step name="yolo" exec="some-command args"/>
-    <step name="hello" exec="some-command other args" requires="yolo"/>
-</scenario>
\ No newline at end of file
diff --git a/utils/stc/src/test/resources/org/onlab/stc/scenario.xml b/utils/stc/src/test/resources/org/onlab/stc/scenario.xml
deleted file mode 100644
index 37c0815..0000000
--- a/utils/stc/src/test/resources/org/onlab/stc/scenario.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<!--
-  ~ Copyright 2015-present 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.
-  -->
-<scenario name="foo" description="Test Scenario" logDir="${test.dir}/foo">
-    <import file="${test.dir}/one-scenario.xml" namespace="foo"/>
-
-    <import file="${test.dir}/two-scenario.xml"/>
-
-    <dependency name="dude" requires="~yolo"/>
-
-    <step name="yo" exec="some-command ${HOME} and ${prop.foo} args" if="${prop.foo}"/>
-    <step name="hi" exec="some-command ${prop.bar} or ${HOME} other args"/>
-    <step name="there" exec="another-command" requires="yo,hi"/>
-
-    <step name="maybe" exec="another-command" requires="~hi" unless="${prop.foo}"/>
-
-    <group name="alpha" exec="same-command args" requires="yo">
-        <step name="one" exec="asdads"/>
-        <step name="two" exec="asdads"/>
-        <group name="three" exec="asdads" requires="one,two">
-            <step name="three.a"/>
-            <step name="three.b" requires="three.a"/>
-            <step name="three.c" requires="three.b"/>
-        </group>
-    </group>
-
-    <dependency name="maybe" requires="yo"/>
-
-    <parallel var="${TOC#}" requires="alpha">
-        <step name="ping-${#}" exec="asdads ${TOC#}"/>
-        <step name="pong-${#}" exec="asdads"/>
-        <step name="ding-${#}" exec="asdads" requires="ping-${#},pong-${#}"/>
-        <dependency name="maybe" requires="ding-${#}"/>
-    </parallel>
-
-    <sequential var="${TOC#}" requires="alpha" starts="fifi-${#},gigi-${#}" ends="gaga-${#-1}">
-        <step name="fifi-${#}" exec="asdads ${TOC#}"/>
-        <step name="gigi-${#}" exec="asdads"/>
-        <step name="gaga-${#}" exec="asdads" requires="fifi-${#},gigi-${#}"/>
-        <dependency name="maybe" requires="gaga-${#}"/>
-    </sequential>
-</scenario>
\ No newline at end of file
diff --git a/utils/stc/src/test/resources/org/onlab/stc/simple-scenario.xml b/utils/stc/src/test/resources/org/onlab/stc/simple-scenario.xml
deleted file mode 100644
index f906990..0000000
--- a/utils/stc/src/test/resources/org/onlab/stc/simple-scenario.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-  ~ Copyright 2015-present 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.
-  -->
-<scenario name="foo" description="Simple Test Scenario" logDir="${test.dir}/junit-stc/foo">
-    <group name="alpha" exec="same-command args">
-        <step name="one" exec="asdads"/>
-        <step name="two" exec="asdads"/>
-        <group name="three" exec="asdads" requires="one,two">
-            <step name="three.a"/>
-            <step name="three.b" requires="three.a"/>
-            <step name="three.c" requires="three.b"/>
-        </group>
-    </group>
-</scenario>
\ No newline at end of file
diff --git a/utils/stc/src/test/resources/org/onlab/stc/two-scenario.xml b/utils/stc/src/test/resources/org/onlab/stc/two-scenario.xml
deleted file mode 100644
index 4a2155c..0000000
--- a/utils/stc/src/test/resources/org/onlab/stc/two-scenario.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-  ~ Copyright 2015-present 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.
-  -->
-
-<scenario name="two" description="" logDir="${test.dir}/junit-stc/two">
-    <step name="dude" exec="some-command args"/>
-    <step name="waz" exec="some-command other args"/>
-    <step name="up" exec="another-command" requires="dude,waz"/>
-</scenario>
\ No newline at end of file