diff --git a/utils/stc/src/main/java/org/onlab/stc/MonitorLayout.java b/utils/stc/src/main/java/org/onlab/stc/MonitorLayout.java
new file mode 100644
index 0000000..1c0e731
--- /dev/null
+++ b/utils/stc/src/main/java/org/onlab/stc/MonitorLayout.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+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;
+        }
+    }
+}
