GEODE-37 changed sequence.gemfire to org.apache.geode

Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/5ba853da
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/5ba853da
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/5ba853da

Branch: refs/heads/develop
Commit: 5ba853daac384a5d8a0b6490cedbd556682e7034
Parents: 06436db
Author: Hitesh Khamesra <hkhame...@pivotal.io>
Authored: Mon Sep 19 13:45:10 2016 -0700
Committer: Hitesh Khamesra <hkhame...@pivotal.io>
Committed: Tue Sep 20 14:29:51 2016 -0700

----------------------------------------------------------------------
 .../java/org/apache/geode/sequence/Arrow.java   | 124 +++++++
 .../geode/sequence/DefaultLineMapper.java       |  41 +++
 .../geode/sequence/GemfireSequenceDisplay.java  | 335 +++++++++++++++++++
 .../apache/geode/sequence/HydraLineMapper.java  | 134 ++++++++
 .../org/apache/geode/sequence/Lifeline.java     |  98 ++++++
 .../apache/geode/sequence/LifelineState.java    | 114 +++++++
 .../org/apache/geode/sequence/LineMapper.java   |  35 ++
 .../geode/sequence/SelectGraphDialog.java       | 155 +++++++++
 .../apache/geode/sequence/SequenceDiagram.java  | 315 +++++++++++++++++
 .../apache/geode/sequence/SequencePanel.java    |  83 +++++
 .../apache/geode/sequence/StateColorMap.java    |  66 ++++
 .../org/apache/geode/sequence/TimeAxis.java     | 122 +++++++
 .../org/apache/geode/sequence/ZoomingPanel.java | 188 +++++++++++
 .../test/java/org/apache/sequence/Arrow.java    | 124 -------
 .../test/java/org/apache/sequence/Lifeline.java |  98 ------
 .../java/org/apache/sequence/LifelineState.java | 114 -------
 .../java/org/apache/sequence/LineMapper.java    |  35 --
 .../org/apache/sequence/SequenceDiagram.java    | 315 -----------------
 .../java/org/apache/sequence/SequencePanel.java |  83 -----
 .../java/org/apache/sequence/StateColorMap.java |  66 ----
 .../test/java/org/apache/sequence/TimeAxis.java | 122 -------
 .../java/org/apache/sequence/ZoomingPanel.java  | 188 -----------
 .../sequence/gemfire/DefaultLineMapper.java     |  41 ---
 .../gemfire/GemfireSequenceDisplay.java         | 335 -------------------
 .../sequence/gemfire/HydraLineMapper.java       | 134 --------
 .../sequence/gemfire/SelectGraphDialog.java     | 155 ---------
 26 files changed, 1810 insertions(+), 1810 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/geode/sequence/Arrow.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/sequence/Arrow.java 
b/geode-core/src/test/java/org/apache/geode/sequence/Arrow.java
new file mode 100644
index 0000000..060af88
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/sequence/Arrow.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.geode.sequence;
+
+import java.awt.*;
+import java.awt.geom.GeneralPath;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dsmith
+ * Date: Nov 12, 2010
+ * Time: 12:02:20 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class Arrow {
+    private static int ARROW_WIDTH=10;
+    private static int CIRCLE_WIDTH=6;
+    private static int LABEL_OFFSET=10;
+
+    private final String label;
+    private final LifelineState startingState;
+    private final LifelineState endingState;
+
+    public Arrow(String label, LifelineState startingState, LifelineState 
endingState) {
+        this.label = label;
+        this.startingState = startingState;
+        this.endingState = endingState;
+    }
+
+
+    public void paint(Graphics2D g) {
+        Rectangle boundary = g.getClipBounds();
+        int y = endingState.getStartY();
+
+        //don't paint if we're not in the clip area
+        if(y + ARROW_WIDTH < boundary.getMinY() || y - ARROW_WIDTH > 
boundary.getMaxY()) {
+            return;
+        }
+
+        //TODO - we need to clip by X coordinate as well.
+        
+        boolean isReflexsive = getStartingLine() == getEndingLine();
+        if(isReflexsive) {
+            paintReflexive(g);
+        } else {
+            paintNormal(g);
+        }
+    }
+    
+    private Lifeline getStartingLine() {
+        return startingState.getLine();
+    }
+    
+    private Lifeline getEndingLine() {
+        return endingState.getLine();
+    }
+
+    private void paintReflexive(Graphics2D g) {
+        Lifeline startingLine = getStartingLine();
+        int x = startingLine.getX();
+        int y = endingState.getStartY();
+
+        g.drawArc(x + startingLine.getWidth() - ARROW_WIDTH / 2, y - 
ARROW_WIDTH, ARROW_WIDTH, ARROW_WIDTH, 90, -180);
+        g.drawString(label, x + startingLine.getWidth() + LABEL_OFFSET, y);
+//        GeneralPath path = new GeneralPath();
+//        path.moveTo(x, y - ARROW_WIDTH);
+//        path.quadTo(x, y - ARROW_WIDTH);
+    }
+
+    private void paintNormal(Graphics2D g) {
+        Lifeline startingLine = getStartingLine();
+        Lifeline endingLine = getEndingLine();
+        int x1 = startingLine.getX();
+        int x2 = endingLine.getX();
+        int y = endingState.getStartY();
+
+        if(x2 > x1) {
+            int startX  = x1 + startingLine.getWidth();
+            int endX = x2;
+
+            GeneralPath path = new GeneralPath();
+            path.moveTo(startX, y);
+            path.lineTo(endX, y);
+            path.lineTo(endX - ARROW_WIDTH, y - ARROW_WIDTH);
+            path.moveTo(endX, y);
+            path.lineTo(endX - ARROW_WIDTH, y + ARROW_WIDTH);
+            g.draw(path);
+            g.fillArc(startX, y - CIRCLE_WIDTH/2, CIRCLE_WIDTH, CIRCLE_WIDTH, 
0, 360);
+            g.drawString(label, startX + LABEL_OFFSET, y - LABEL_OFFSET);
+        } else {
+            int startX  = x1;
+            int endX = x2 + endingLine.getWidth();
+
+            GeneralPath path = new GeneralPath();
+            path.moveTo(startX, y);
+            path.lineTo(endX, y);
+            path.lineTo(endX + ARROW_WIDTH, y - ARROW_WIDTH);
+            path.moveTo(endX, y);
+            path.lineTo(endX + ARROW_WIDTH, y + ARROW_WIDTH);
+            g.draw(path);
+            int labelWidth = g.getFontMetrics().stringWidth(label);
+            g.fillArc(startX - CIRCLE_WIDTH/2, y - CIRCLE_WIDTH/2, 
CIRCLE_WIDTH, CIRCLE_WIDTH, 0, 360);
+            g.drawString(label, startX - LABEL_OFFSET - labelWidth, y - 
LABEL_OFFSET);
+        }
+    }
+
+    public LifelineState getStartingState() {
+      return startingState;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/geode/sequence/DefaultLineMapper.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/sequence/DefaultLineMapper.java 
b/geode-core/src/test/java/org/apache/geode/sequence/DefaultLineMapper.java
new file mode 100644
index 0000000..fcec33c
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/sequence/DefaultLineMapper.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.geode.sequence;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.geode.sequence.LineMapper;
+
+/**
+ * A lifeline mapper that just returns a shortened version of 
+ * a member id.
+ *
+ */
+public class DefaultLineMapper implements LineMapper {
+  private static Pattern MEMBER_ID_RE = 
Pattern.compile(".*\\((\\d+)(:admin)?(:loner)?\\).*:\\d+(/\\d+|.*:.*)");
+
+  public String getShortNameForLine(String name) {
+    Matcher matcher = MEMBER_ID_RE.matcher(name);
+    if(matcher.matches()) {
+      return matcher.group(1);
+    } else {
+      return name;
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/geode/sequence/GemfireSequenceDisplay.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/sequence/GemfireSequenceDisplay.java
 
b/geode-core/src/test/java/org/apache/geode/sequence/GemfireSequenceDisplay.java
new file mode 100644
index 0000000..7fb06b9
--- /dev/null
+++ 
b/geode-core/src/test/java/org/apache/geode/sequence/GemfireSequenceDisplay.java
@@ -0,0 +1,335 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.geode.sequence;
+
+import org.apache.geode.internal.sequencelog.GraphType;
+import org.apache.geode.internal.sequencelog.io.Filter;
+import org.apache.geode.internal.sequencelog.io.GraphReader;
+import org.apache.geode.internal.sequencelog.model.*;
+import org.apache.geode.sequence.*;
+
+import javax.swing.*;
+import java.awt.event.*;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.*;
+import java.util.regex.Pattern;
+
+/**
+ */
+public class GemfireSequenceDisplay {
+
+  private JLabel selectedGraphsLabel;
+  private SelectGraphDialog selectGraphDialog;
+
+  private Map<GraphID, Map<String, Lifeline>> lineMap = new HashMap();
+  private Map<GraphID, List<Arrow>> arrowMap = new HashMap();
+  private SequenceDiagram sequenceDiagram;
+  private JFrame frame;
+  private SequencePanel sequencePanel;
+
+  /**
+   * Create the GUI and show it.  For thread safety,
+   * this method should be invoked from the
+   * event-dispatching thread.
+   *
+   * @param graphs
+   * @param lineMapper 
+   */
+  private void createAndShowGUI(final GraphSet graphs, LineMapper lineMapper) {
+    //Create and set up the window.
+
+    frame = new JFrame("SequenceDiagram");
+    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+    createMenu();
+    createSequenceDiagram(graphs, lineMapper);
+    createSequenceMaps(graphs);
+
+    createSelectGraphDialog(graphs);
+
+    //        for (GraphID id : graphs.getMap().keySet()) {
+    //            showSubDiagram(id);
+    //
+    //        }
+
+    sequencePanel = new SequencePanel(sequenceDiagram);
+    frame.getContentPane().add(sequencePanel);
+    //Display the window.
+    frame.pack();
+    frame.setVisible(true);
+    showGraphSelector();
+  }
+
+  private void createMenu() {
+    JMenuBar menuBar = new JMenuBar();
+
+    JMenu sequenceMenu = new JMenu("Sequence");
+    sequenceMenu.setMnemonic(KeyEvent.VK_S);
+    sequenceMenu.getAccessibleContext().setAccessibleDescription(
+        "The only menu in this program that has menu items");
+    menuBar.add(sequenceMenu);
+    JMenuItem selectGraphs = new JMenuItem("Choose Graphs",
+        KeyEvent.VK_G);
+    selectGraphs.setAccelerator(KeyStroke.getKeyStroke(
+        KeyEvent.VK_G, ActionEvent.ALT_MASK));
+    selectGraphs.getAccessibleContext().setAccessibleDescription(
+        "Select what graphs to display");
+    selectGraphs.setActionCommand("selectgraphs");
+    selectGraphs.addActionListener(new ActionListener() {
+
+      public void actionPerformed(ActionEvent e) {
+        showGraphSelector();
+      }
+    });
+
+    sequenceMenu.add(selectGraphs);
+    frame.setJMenuBar(menuBar);
+  }
+
+  private void createSelectGraphDialog(final GraphSet graphs) {
+    selectGraphDialog = new SelectGraphDialog(graphs);
+    selectGraphDialog.addSelectionListener(new 
SelectGraphDialog.SelectionListener() {
+
+      public void selectionChanged(List<GraphID> selectedIds) {
+        updateGraphs(selectedIds);
+      }
+    });
+    selectGraphDialog.pack();
+  }
+
+  private void updateGraphs(List<GraphID> selectedIds) {
+    List<GraphID> existingDiagrams =(List) 
sequenceDiagram.getSubDiagramsNames();
+    for(GraphID id : selectedIds) {
+      showSubDiagram(id);
+      existingDiagrams.remove(id);
+    }
+    for(GraphID id : existingDiagrams) {
+      hideSubDiagram(id);
+    }
+
+    sequenceDiagram.resizeMe(sequenceDiagram.getWidth(), 
sequenceDiagram.getHeight());
+    sequencePanel.revalidate();
+    sequencePanel.repaint();
+    //        sequenceDiagram.revalidate();
+    //        sequenceDiagram.repaint();
+  }
+
+  private void showGraphSelector() {
+    selectGraphDialog.setVisible(true);
+  }
+
+  private void hideGraphSelector() {
+    selectGraphDialog.setVisible(false);
+  }
+
+  //  private static SequenceDiagram createSequenceDiagram() {
+  //      long startTime = System.currentTimeMillis();
+  //      List<Lifeline> lines = new ArrayList<Lifeline>();
+  //      List<Arrow> arrows = new ArrayList<Arrow>();
+  //      for(int i =0 ; i < 10; i++) {
+  //          List<LifelineState> states = new ArrayList<LifelineState>();
+  //          for(int j =0; j < 5; j++) {
+  //              LifelineState state = new LifelineState(startTime  + 20* j, 
startTime  + 20 * j + 20);
+  //              states.add(state);
+  //          }
+  //          Lifeline line = new Lifeline(i, states);
+  //          lines.add(line);
+  //
+  //          if(i > 0) {
+  //              Arrow arrow = new Arrow("arrow" + i, line, lines.get(i - 1), 
line.getStates().get(2));
+  //              arrows.add(arrow);
+  //          }
+  //      }
+  //
+  //      SequenceDiagram diag = new SequenceDiagram(startTime, startTime + 20 
* 5, lines, arrows);
+  //      return diag;
+  //  }
+
+  private void createSequenceMaps(GraphSet graphs) {
+
+    Map<GraphID, Graph> map = graphs.getMap();
+    for (Map.Entry<GraphID, Graph> entry : map.entrySet()) {
+      GraphID graphId = entry.getKey();
+      Graph graph = entry.getValue();
+      Map<String, Lifeline> lines = new LinkedHashMap<String, 
Lifeline>(graphs.getLocations().size());
+      List<Arrow> arrows = new ArrayList<Arrow>();
+      Map<Vertex, LifelineState> states = new HashMap<Vertex, LifelineState>();
+      for (String location : graphs.getLocations()) {
+        lines.put(location, new Lifeline(graphId, location));
+      }
+
+      Collection<Edge> edges = graph.getEdges();
+      for (Edge edge : edges) {
+        Vertex dest = edge.getDest();
+        Vertex source = edge.getSource();
+        if (dest == null) {
+          dest = source;
+        }
+        if (source == null) {
+          source = dest;
+        }
+        LifelineState destState = states.get(dest);
+        if (destState == null) {
+          final Lifeline lifeline = lines.get(dest.getName());
+          destState = createState(lifeline, graphs, dest);
+          lifeline.addState(destState);
+          states.put(dest, destState);
+        }
+        LifelineState sourceState = states.get(source);
+        if (sourceState == null) {
+          final Lifeline lifeline = lines.get(source.getName());
+          sourceState = createState(lifeline, graphs, source);
+          lifeline.addState(sourceState);
+          states.put(source, sourceState);
+        }
+        Arrow arrow = new Arrow(edge.getName(), sourceState, destState);
+        arrows.add(arrow);
+        destState.addInboundArrow(arrow);
+      }
+
+
+      lineMap.put(graphId, lines);
+      arrowMap.put(graphId, arrows);
+    }
+  }
+
+  public void showSubDiagram(GraphID id) {
+    sequenceDiagram.addSubDiagram(id, lineMap.get(id), arrowMap.get(id));
+  }
+
+  public void hideSubDiagram(GraphID id) {
+    sequenceDiagram.removeSubDiagram(id);
+  }
+
+  private SequenceDiagram createSequenceDiagram(GraphSet graphs, LineMapper 
lineMapper) {
+
+    sequenceDiagram = new SequenceDiagram(graphs.getMinTime(), 
graphs.getMaxTime(), graphs.getLocations(), lineMapper);
+    return sequenceDiagram;
+  }
+
+  private static LifelineState createState(Lifeline lifeline, GraphSet graphs, 
Vertex dest) {
+    long start = dest.getTimestamp();
+    long end = dest.getNextVertexOnDest() == null ? graphs.getMaxTime() : 
dest.getNextVertexOnDest().getTimestamp();
+    return new LifelineState(lifeline, dest.getState(), start, end);
+  }
+
+  public static void main(String[] args) throws IOException {
+    File[] files;
+    Set<String> keyFilters = new HashSet<String>();
+    boolean areGemfireLogs = false;
+    if (args.length > 0) {
+      ArrayList<File> fileList = new ArrayList<File>();
+      for (int i =0; i < args.length; i++) {
+        String arg = args[i];
+        if(arg.equals("-filterkey")) {
+          keyFilters.add(args[i+1]);
+          i++;
+        } else if(arg.equals("-logs")) {
+          areGemfireLogs = true;
+        }
+        else {
+          fileList.add(new File(args[i]));
+        }
+        
+      }
+      files = fileList.toArray(new File[0]);
+    } else {
+      System.err.println("Usage: java -jar sequence.jar (-logs) (-filterkey 
key)* <file>+\n\n" +
+                "\t-logs (expiremental) instead of using .graph files, parse 
the gemfire logs to generate the sequence display" +
+               "\t-filterkey a java regular expression to match against key 
names. If specified\n" +
+               "The list of key sequence diagrams will only contain matching 
keys");
+      System.exit(1);
+      return;
+    }
+    
+    final GraphSet graphs;
+    
+    graphs = getGraphs(areGemfireLogs, keyFilters, files);
+
+    final LineMapper lineMapper = getLineMapper(files);
+    final GemfireSequenceDisplay display = new GemfireSequenceDisplay();
+    //Schedule a job for the event-dispatching thread:
+    //creating and showing this application's GUI.
+    javax.swing.SwingUtilities.invokeLater(new Runnable() {
+      public void run() {
+        display.createAndShowGUI(graphs, lineMapper);
+      }
+    });
+  }
+
+  private static GraphSet getGraphs(boolean useLogFiles, Set<String> 
keyFilters, File[] files)
+      throws IOException {
+    Filter graphFilter = new KeyFilter(keyFilters);
+    
+    
+    GraphReader reader = new GraphReader(files);
+    final GraphSet graphs;
+    if(keyFilters.isEmpty()) {
+      graphs = reader.readGraphs(useLogFiles);
+    } else {
+      graphs = reader.readGraphs(graphFilter, useLogFiles);
+    }
+    return graphs;
+  }
+
+  /**
+   * @param files 
+   * @return
+   */
+  private static LineMapper getLineMapper(File[] files) {
+    if(HydraLineMapper.isInHydraRun(files)) {
+      return new HydraLineMapper(files);
+    } else {
+      return new DefaultLineMapper();
+    }
+  }
+  
+  private static class KeyFilter implements Filter {
+    Set<Pattern> patterns = new HashSet<Pattern>();
+    
+
+    public KeyFilter(Set<String> keyFilters) {
+      for(String filterString : keyFilters) {
+        patterns.add(Pattern.compile(filterString));
+      }
+    }
+
+    public boolean accept(GraphType graphType, String name, String edgeName,
+        String source, String dest) {
+      if(graphType.equals(GraphType.KEY)) {
+        for(Pattern pattern : patterns) {
+          if(pattern.matcher(name).find()) {
+            return true;
+          }
+        }
+        
+        return false;
+      } else {
+        return true;
+      }
+    }
+
+    public boolean acceptPattern(GraphType graphType, Pattern pattern,
+        String edgeName, String source, String dest) {
+      return true;
+    }
+    
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/geode/sequence/HydraLineMapper.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/sequence/HydraLineMapper.java 
b/geode-core/src/test/java/org/apache/geode/sequence/HydraLineMapper.java
new file mode 100644
index 0000000..af82c47
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/sequence/HydraLineMapper.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.geode.sequence;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.geode.sequence.LineMapper;
+
+/**
+ *
+ */
+public class HydraLineMapper implements LineMapper {
+  private static final Pattern VM_NAME_PATTERN = 
Pattern.compile("(vm_\\d+).*_(\\d+)(_end)?\\.log");
+  private static final Pattern DISK_DIR_PATTERN = 
Pattern.compile("vm_(\\d+).*_disk_1");
+  private final Map<String, String> processIdToVMName = new HashMap<String, 
String>();
+  private final DefaultLineMapper defaultMapper = new DefaultLineMapper();
+  
+  public HydraLineMapper(File[] graphFiles) {
+    File firstFile = graphFiles[0];
+    File directory = firstFile.getParentFile();
+    if(directory == null || ! new File(directory, "latest.prop").exists()) {
+      directory = new File(".");
+    }
+    String[] files = directory.list();
+    for(String file : files) {
+      Matcher matcher = VM_NAME_PATTERN.matcher(file);
+      if(matcher.matches()) {
+        processIdToVMName.put(matcher.group(2), matcher.group(1));
+      }
+    }
+    
+    for(String file : files) {
+      Matcher matcher = DISK_DIR_PATTERN.matcher(file);
+      if(matcher.matches()) {
+        
+        String storeId = getDiskStoreId(file);
+        if(storeId != null) {
+          processIdToVMName.put(storeId, "disk_" + matcher.group(1));
+        }
+      }
+    }
+    
+    
+  }
+
+  private String getDiskStoreId(String diskStoreDir) {
+    File dir = new File(diskStoreDir);
+    String[] files = dir.list();
+    for(String fileName : files) {
+      if(fileName.endsWith(".if")) {
+        try {
+          return getDiskStoreIdFromInitFile(dir, fileName);
+        } catch (Exception e) {
+          return null;
+        }
+      }
+    }
+    
+    return null;
+  }
+
+  private String getDiskStoreIdFromInitFile(File dir, String fileName)
+      throws FileNotFoundException, IOException {
+    FileInputStream fis = new FileInputStream(new File(dir, fileName));
+    try {
+      byte[] bytes = new byte[1 + 8 + 8];
+      fis.read(bytes);
+      ByteBuffer buffer = ByteBuffer.wrap(bytes);
+      //Skip the record type.
+      buffer.get();
+      long least = buffer.getLong();
+      long most = buffer.getLong();
+      UUID id = new UUID(most, least);
+      return id.toString();
+    } finally {
+      fis.close();
+    }
+  }
+
+  public String getShortNameForLine(String lineName) {
+    String name = defaultMapper.getShortNameForLine(lineName);
+    if(processIdToVMName.containsKey(name)) {
+      return processIdToVMName.get(name);
+    } else {
+      return name;
+    }
+  }
+  
+  public static boolean isInHydraRun(File[] graphFiles) {
+    if(graphFiles.length == 0) {
+      return false;
+    }
+    File firstFile = graphFiles[0];
+    File parentFile = firstFile.getParentFile();
+    for(File file : graphFiles) {
+      if(parentFile == null && file.getParentFile() == null) {
+        return true;
+      }
+      if (parentFile == null || file.getParentFile() == null
+          || !file.getParentFile().equals(parentFile)) {
+        return false;
+      }
+    }
+    
+    return new File(parentFile, "latest.prop").exists() 
+      || new File("latest.prop").exists();
+    
+    
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/geode/sequence/Lifeline.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/sequence/Lifeline.java 
b/geode-core/src/test/java/org/apache/geode/sequence/Lifeline.java
new file mode 100644
index 0000000..f80b533
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/sequence/Lifeline.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.geode.sequence;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dsmith
+ * Date: Oct 29, 2010
+ * Time: 3:59:02 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class Lifeline {
+    private List<LifelineState> states;
+    private final String name;
+    private final Comparable diagramName;
+    private int x;
+    private int width;
+
+    public String getName() {
+        return name;
+    }
+
+    public int getX() {
+        return x;
+    }
+
+    public int getWidth() {
+        return width;
+    }
+
+    public void addState(LifelineState state) {
+        this.states.add(state);
+    }
+    
+    public Lifeline(Comparable diagramName, String name) {
+      this.name = name;
+      this.states = new ArrayList<LifelineState>();
+      this.diagramName = diagramName;
+    }
+
+    public void resize(int x, int lineWidth, long Ybase, double Yscale) {
+        for(LifelineState state : states) {
+            state.resize(Yscale, Ybase);
+        }
+
+        this.x = x;
+        width = lineWidth;
+    }
+
+    public void paint(Graphics2D g, StateColorMap colorMap) {
+        Rectangle boundary = g.getClipBounds();
+        if(x > boundary.getMaxX() || x + width < boundary.getMinX()) {
+            //no need to paint if this line isn't displayed
+            return;
+        }
+        //TODO - we need to clip these to the visible states
+        for(LifelineState state : states) {
+            state.paint(g, colorMap);
+        }
+    }
+
+    public List<LifelineState> getStates() {
+        return states;
+    }
+
+    public LifelineState getStateAt(int y) {
+        for(LifelineState state : states) {
+            if(state.getStartY() < y && state.getStartY() + state.getHeight() 
> y) {
+                return state;
+            }
+        }
+        return null;
+    }
+
+    public Comparable getDiagramName() {
+      return diagramName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/geode/sequence/LifelineState.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/sequence/LifelineState.java 
b/geode-core/src/test/java/org/apache/geode/sequence/LifelineState.java
new file mode 100644
index 0000000..c1a57bf
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/sequence/LifelineState.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.geode.sequence;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.swing.JLabel;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dsmith
+ * Date: Oct 29, 2010
+ * Time: 3:45:07 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class LifelineState {
+    private final long startTime;
+    private final long endTime;
+    private final String stateName;
+    private int startY;
+    private int height;
+    private final Lifeline line;
+    private final Set<Arrow> inboundArrows = new HashSet<Arrow>();
+    private static final int ARC_SIZE = 10;
+
+    public int getStartY() {
+        return startY;
+    }
+
+    public int getHeight() {
+        return height;
+    }
+
+
+    public LifelineState(Lifeline line, String stateName, long startTime, long 
endTime) {
+        this.line = line;
+        this.stateName = stateName;
+        this.startTime = startTime;
+        this.endTime = endTime;
+    }
+
+    public void paint(Graphics2D g, StateColorMap colorMap) {
+        Rectangle bounds = g.getClipBounds();
+        if(startY > bounds.getMaxY()  || startY+height <bounds.getMinY()) {
+            return;
+        }
+        
+        int x = line.getX();
+        int width  = line.getWidth();
+
+        Color color = colorMap.getColor(stateName);
+        g.setColor(color);
+        g.fillRoundRect(x, startY, width, height, ARC_SIZE, ARC_SIZE);
+        g.setColor(Color.BLACK);
+    }
+    
+    public void highlight(Graphics2D g) {
+      Rectangle bounds = g.getClipBounds();
+      if(startY > bounds.getMaxY()  || startY+height <bounds.getMinY()) {
+          return;
+      }
+      
+      int x = line.getX();
+      int width  = line.getWidth();
+
+      g.drawRoundRect(x, startY, width, height, ARC_SIZE, ARC_SIZE);
+    }
+
+    public void resize(double scale, long base) {
+        startY = (int)  ((startTime - base) * scale);
+        height = (int) ((endTime - startTime) * scale);
+    }
+
+    public Component getPopup() {
+        return new JLabel("<html>Object: " + line.getDiagramName() + 
"<br>Member: " + line.getName() + "<br>State: " + stateName + "<br>Time:" + new 
Date(startTime) + "</html>");
+    }
+
+    public Lifeline getLine() {
+      return line;
+    }
+
+    public void addInboundArrow(Arrow arrow) {
+      inboundArrows.add(arrow);
+    }
+
+    public Set<Arrow> getInboundArrows() {
+      return inboundArrows;
+    }
+    
+    @Override
+    public String toString() {
+      return line.getName() + "@" + startTime + ":" + stateName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/geode/sequence/LineMapper.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/sequence/LineMapper.java 
b/geode-core/src/test/java/org/apache/geode/sequence/LineMapper.java
new file mode 100644
index 0000000..91f7d6c
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/sequence/LineMapper.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.geode.sequence;
+
+/**
+ * An interface for mapping a lifeline name to a shorter version of the same
+ * line. This could also consolodate multiple lifelines onto a single line.
+ * 
+ * The most common case for this is that a lifeline represents a VM that is
+ * restarted several times. Eg time, the line name changes, but we want to put
+ * all of the states for that "logical" vm on the same line.
+ *
+ */
+public interface LineMapper {
+  
+  /**
+   * Return the short name for this lifeline.
+   */
+  public String getShortNameForLine(String lineName);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/geode/sequence/SelectGraphDialog.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/sequence/SelectGraphDialog.java 
b/geode-core/src/test/java/org/apache/geode/sequence/SelectGraphDialog.java
new file mode 100644
index 0000000..caa37e5
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/sequence/SelectGraphDialog.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.geode.sequence;
+
+import org.apache.geode.internal.sequencelog.model.GraphID;
+import org.apache.geode.internal.sequencelog.model.GraphSet;
+
+import javax.swing.*;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.*;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dsmith
+ * Date: Dec 9, 2010
+ * Time: 3:34:38 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class SelectGraphDialog extends JDialog {
+    private List<GraphID> selectedIds = new ArrayList<GraphID>();
+    private Set<SelectionListener> listeners = new 
HashSet<SelectionListener>();
+
+    public SelectGraphDialog(final GraphSet graphs) {
+        
+        final List<GraphID> ids = new 
ArrayList<GraphID>(graphs.getMap().keySet());
+        Collections.sort(ids);
+        final FilterableListModel listModel = new FilterableListModel(ids);
+        final JList list = new JList(listModel);
+
+        JScrollPane selectGraphPane = new JScrollPane(list);
+        selectGraphPane.setPreferredSize(new Dimension(500, 500));
+
+        JButton apply = new JButton("Apply");
+        apply.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                selectedIds = (List) Arrays.asList(list.getSelectedValues());
+                fireSelectionChanged();
+                setVisible(false);
+            }
+        });
+
+        JButton cancel= new JButton("Cancel");
+        cancel.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                setVisible(false);
+            }
+        });
+
+        JPanel buttonPane = new JPanel();
+        buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS));
+        buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
+        buttonPane.add(Box.createHorizontalGlue());
+        buttonPane.add(apply);
+        buttonPane.add(cancel);
+        
+        final JTextField searchField = new JTextField(10);
+        searchField.getDocument().addDocumentListener(new DocumentListener() {
+          public void removeUpdate(DocumentEvent e) {
+            doUpdate();
+          }
+          
+          public void insertUpdate(DocumentEvent e) {
+            doUpdate();
+          }
+          
+          public void changedUpdate(DocumentEvent e) {
+            doUpdate();
+          }
+          
+          private void doUpdate() {
+            listModel.updateFilter(searchField.getText());
+          }
+        });
+        
+
+        Container contentPane = getContentPane();
+        contentPane.add(searchField, BorderLayout.PAGE_START);
+        contentPane.add(selectGraphPane, BorderLayout.CENTER);
+        contentPane.add(buttonPane, BorderLayout.PAGE_END);
+    }
+
+    private void fireSelectionChanged() {
+        for(SelectionListener listener : listeners) {
+            listener.selectionChanged(selectedIds);
+        }
+    }
+
+    public void addSelectionListener(SelectionListener listener) {
+        listeners.add(listener);
+
+    }
+
+    public void removeSelectionListener(SelectionListener listener) {
+        listeners.remove(listener);
+    }
+
+    /**
+     * A listener for changes to the graph selections
+     */
+    public static interface SelectionListener {
+        void selectionChanged(List<GraphID> selectedIds);
+    }
+    
+    private static class FilterableListModel extends AbstractListModel {
+      private final List<?> allElements;
+      private List<Object> filteredElements;
+      
+      public FilterableListModel(List<?> elements) {
+        this.allElements = elements;
+        this.filteredElements = new ArrayList<Object>(elements);
+      }
+
+      public int getSize() {
+        return filteredElements.size();
+      }
+
+      public Object getElementAt(int index) {
+        return filteredElements.get(index);
+      }
+      
+      public void updateFilter(String filter) {
+        Pattern pattern = Pattern.compile(filter);
+        filteredElements = new ArrayList<Object>();
+        for(Object element : allElements) {
+          if(pattern.matcher(element.toString()).find()) {
+            filteredElements.add(element);
+          }
+        }
+        
+        fireContentsChanged(this, 0, filteredElements.size());
+      }
+      
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/geode/sequence/SequenceDiagram.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/sequence/SequenceDiagram.java 
b/geode-core/src/test/java/org/apache/geode/sequence/SequenceDiagram.java
new file mode 100644
index 0000000..5064d8a
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/sequence/SequenceDiagram.java
@@ -0,0 +1,315 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.geode.sequence;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.*;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dsmith
+ * Date: Oct 29, 2010
+ * Time: 4:18:40 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class SequenceDiagram extends JPanel {
+
+    /**
+   * 
+   */
+  private static final Color HIGHLIGHT_COLOR = Color.RED;
+
+    private final List<String> lineNames;
+    private final Map<String, List<String>> shortLineNames;
+    private final SortedMap<Comparable, SubDiagram> subDiagrams = new 
TreeMap<Comparable, SubDiagram>();
+    private final StateColorMap colorMap = new StateColorMap();
+    private final long minTime;
+    private final long maxTime;
+
+    private static int PADDING_BETWEEN_LINES = 100;
+    private static int Y_PADDING = 20;
+    private static final int STATE_WIDTH = 20;
+    private static final int LINE_LABEL_BOUNDARY = 5;
+    private static final int AXIS_SIZE=35;
+
+    private int lineStep;
+    private int lineWidth;
+    private Popup mouseover;
+    private LifelineState mouseoverState;
+    private LifelineState selectedState;
+
+    public SequenceDiagram(long minTime, long maxTime, List<String> lineNames, 
LineMapper lineMapper) {
+        this.lineNames = lineNames;
+        this.shortLineNames = parseShortNames(lineNames, lineMapper);
+        this.minTime = minTime;
+        this.maxTime = maxTime;
+        int width = getInitialWidth();
+        int height = 500;
+        super.setPreferredSize(new Dimension(width, height));
+        resizeMe(width, height);
+        addComponentListener(new ComponentAdapter() {
+            @Override
+            public void componentResized(ComponentEvent e) {
+                Component source = (Component) e.getSource();
+                resizeMe(source.getWidth(), source.getHeight());
+            }
+        });
+        setBackground(Color.WHITE);
+    }
+
+    private Map<String, List<String>> parseShortNames(List<String> lineNames, 
LineMapper lineMapper) {
+        Map<String, List<String>> shortNames = new LinkedHashMap<String, 
List<String>>(lineNames.size());
+        for(String name : lineNames) {
+          String shortName = lineMapper.getShortNameForLine(name);
+          List<String> list = shortNames.get(shortName);
+          if(list == null) {
+            list = new ArrayList<String>();
+            shortNames.put(shortName, list);
+          }
+          list.add(name);
+        }
+          
+        return shortNames;
+    }
+
+    public List<Comparable> getSubDiagramsNames() {
+        return new ArrayList<Comparable>(subDiagrams.keySet());
+
+    }
+
+    public void addSubDiagram(Comparable name, Map<String, Lifeline> lines, 
List<Arrow> arrows) {
+        subDiagrams.put(name, new SubDiagram(name, lines, arrows));
+    }
+
+    public void removeSubDiagram(Comparable name) {
+        this.subDiagrams.remove(name);
+    }
+
+    private int getInitialWidth() {
+        return (this.shortLineNames.size()) * PADDING_BETWEEN_LINES;
+    }
+
+    public void resizeMe(int width, int height) {
+        this.setPreferredSize(new Dimension(width, height));
+        float xZoom = width / (float) getInitialWidth();
+
+
+        long elapsedTime = maxTime - minTime;
+        double yScale = height / (double) elapsedTime;
+//        long yBase = (long) (minTime - ((long) Y_PADDING / yScale));
+        long yBase = minTime;
+        lineStep = (int) (PADDING_BETWEEN_LINES * xZoom);
+        lineWidth = (int) (STATE_WIDTH * xZoom);
+
+        if(subDiagrams.size() <= 0) {
+            return;
+        }
+        
+        int sublineWidth = lineWidth / subDiagrams.size();
+        int sublineIndex = 0;
+        for(SubDiagram diagram : subDiagrams.values()) {
+            int lineIndex = 0;
+            for(List<String> fullNames : shortLineNames.values()) {
+              for(String name : fullNames) {
+                Lifeline line = diagram.lifelines.get(name);
+                if(line != null) {
+                    int lineX = lineIndex * lineStep + sublineIndex * 
sublineWidth;
+                    line.resize(lineX, sublineWidth, yBase, yScale);
+                }
+              }
+              lineIndex++;
+            }
+            sublineIndex++;
+        }
+    }
+
+    public void showPopupText(int x, int y, int xOnScreen, int yOnScreen) {
+      LifelineState state = getStateAt(x, y);
+      if(state == mouseoverState) {
+        return;
+      }
+      if(mouseover != null) {
+        mouseover.hide();
+      }
+      if(state == null) {
+        mouseover = null;
+        mouseoverState = null;
+      } else {
+        Component popupContents = state.getPopup();        
+        mouseoverState = state;
+        mouseover = PopupFactory.getSharedInstance().getPopup(this, 
popupContents, xOnScreen + 20, yOnScreen);
+        mouseover.show();
+      }
+    }
+    
+    public void selectState(int x, int y) {
+      LifelineState state = getStateAt(x, y);
+      if(state == selectedState) {
+        return;
+      }
+      
+      if(selectedState != null) {
+        fireRepaintOfDependencies(selectedState);
+      }
+      
+      selectedState = state;
+      
+      if(state != null) {
+        fireRepaintOfDependencies(state);
+      }
+    }
+    
+    private LifelineState getStateAt(int x, int y) {
+    //TODO - this needs some
+      //serious optimization to go straight to the right state
+      // I think we need a tree map of of lines, keyed by x offset
+      //and a keymap of states keyed by y offset.
+      //That could make painting faster as well.
+      List<String> reverseList = new ArrayList<String>(lineNames);
+      Collections.reverse(reverseList);
+      for(SubDiagram diagram : subDiagrams.values()) {
+        for(String name : reverseList) {
+            Lifeline line = diagram.lifelines.get(name);
+            if(line != null) {
+                if(line.getX() < x && line.getX() + line.getWidth() > x) {
+                    LifelineState state = line.getStateAt(y);
+                    if(state != null) {
+                      return state;
+                    }
+                }
+            }
+        }
+      }
+      return null;
+    }
+
+    @Override
+    protected void paintComponent(Graphics g) {
+        super.paintComponent(g);
+        Graphics2D g2 = (Graphics2D) g.create();
+        //TODO - we should clip these to the visible lines
+        for(SubDiagram subDiagram : subDiagrams.values()) {
+            subDiagram.paintStates(g2, colorMap);
+        }
+
+        for(SubDiagram subDiagram : subDiagrams.values()) {
+            subDiagram.paintArrows(g2, colorMap);
+        }
+        paintHighlightedComponents(g2, selectedState, new 
HashSet<LifelineState>());
+    }
+    
+    private void fireRepaintOfDependencies(LifelineState state) {
+      //TODO - it might be more efficient to repaint just the changed 
+      //areas, but right now this will do.
+      repaint();
+    }
+
+    private void paintHighlightedComponents(Graphics2D g2, LifelineState 
endingState, Set<LifelineState> visited) {
+      if(!visited.add(endingState)) {
+        //Prevent cycles
+        return;
+      }
+      g2.setColor(HIGHLIGHT_COLOR);
+      if(endingState != null) {
+        endingState.highlight(g2);
+        
+        for(Arrow arrow : endingState.getInboundArrows()) {
+          arrow.paint(g2);
+          paintHighlightedComponents(g2, arrow.getStartingState(), visited);
+        }
+      }
+      
+      
+    }
+
+    public long getMinTime() {
+        return minTime;
+    }
+
+    public long getMaxTime() {
+        return maxTime;
+    }
+
+    public JComponent createMemberAxis() {
+        return new MemberAxis();
+    }
+
+    private class MemberAxis extends JComponent {
+        public MemberAxis() {
+            setPreferredSize(new Dimension(getWidth(), AXIS_SIZE));
+            SequenceDiagram.this.addComponentListener(new ComponentAdapter() {
+                @Override
+                public void componentResized(ComponentEvent e) {
+                    int newWidth = e.getComponent().getWidth();
+                    setPreferredSize(new Dimension(newWidth, AXIS_SIZE));
+                    revalidate();
+                }
+            });
+        }
+        @Override
+        protected void paintComponent(Graphics g) {
+            super.paintComponent(g);
+            Rectangle bounds = g.getClipBounds();
+            int index = 0;
+            for(String name : shortLineNames.keySet()) {
+                int nameWidth = g.getFontMetrics().stringWidth(name);
+                int lineX = lineStep * index;
+                index++;
+                if(bounds.getMaxX() < lineX
+                        || bounds.getMinX() > lineX + nameWidth) {
+                    continue;
+                }
+                g.setClip(lineX + LINE_LABEL_BOUNDARY, 0, lineStep - + 
LINE_LABEL_BOUNDARY * 2, getHeight());
+                g.drawString(name, lineX + LINE_LABEL_BOUNDARY, AXIS_SIZE / 3);
+                g.setClip(null);
+            }
+        }
+    }
+
+    public static class SubDiagram {
+        private final Map<String, Lifeline> lifelines;
+        private final List<Arrow> arrows;
+        private final Comparable name;
+
+        public SubDiagram(Comparable name, Map<String, Lifeline> lines, 
List<Arrow> arrows) {
+            this.name = name;
+            this.lifelines = lines;
+            this.arrows = arrows;
+        }
+
+        public void paintStates(Graphics2D g2, StateColorMap colorMap) {
+            for(Lifeline line: lifelines.values()) {
+                line.paint(g2, colorMap);
+            }
+        }
+        public void paintArrows(Graphics2D g2, StateColorMap colorMap) {
+            Color lineColor = colorMap.getColor(name);
+            g2.setColor(lineColor);
+            for(Arrow arrow: arrows) {
+                arrow.paint(g2);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/geode/sequence/SequencePanel.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/sequence/SequencePanel.java 
b/geode-core/src/test/java/org/apache/geode/sequence/SequencePanel.java
new file mode 100644
index 0000000..daefc08
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/sequence/SequencePanel.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.geode.sequence;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dan
+ * Date: Oct 28, 2010
+ * Time: 10:29:23 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class SequencePanel extends JPanel {
+
+    public SequencePanel(SequenceDiagram sequenceDiagram) {
+         //Set up the drawing area.
+        ZoomingPanel drawingPane = new ZoomingPanel();
+        drawingPane.setBackground(Color.white);
+        drawingPane.setSequenceDiagram(sequenceDiagram);
+
+        //Put the drawing area in a scroll pane.
+        final JScrollPane scroller = new JScrollPane(drawingPane);
+        
scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
+        
scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
+        final TimeAxis timeAxis = new TimeAxis(TimeAxis.VERTICAL, 
+                sequenceDiagram.getMinTime(),
+                sequenceDiagram.getMaxTime());
+        timeAxis.setPreferredHeight(drawingPane.getHeight());
+        scroller.setRowHeaderView(timeAxis);
+        scroller.setColumnHeaderView(sequenceDiagram.createMemberAxis());
+        int preferredWidth = (int) 
(Toolkit.getDefaultToolkit().getScreenSize().getWidth() - 100);
+        int preferredHeight = (int) 
(Toolkit.getDefaultToolkit().getScreenSize().getHeight() - 100);
+        scroller.setPreferredSize(new Dimension(preferredWidth, 
preferredHeight));
+        scroller.setAutoscrolls(true);
+//        scroller.setPreferredSize(new Dimension(200,200));
+
+        sequenceDiagram.addComponentListener(new ComponentAdapter() {
+            @Override
+            public void componentResized(ComponentEvent e) {
+                int height = e.getComponent().getHeight();
+                timeAxis.setPreferredHeight(height);
+                timeAxis.revalidate();
+            }
+        });
+
+        BorderLayout layout = new BorderLayout();
+//        layout.setHgap(0);
+//        layout.setVgap(0);
+        setLayout(layout);
+        //Lay out this demo.
+//        add(instructionPanel, BorderLayout.PAGE_START);
+        add(scroller, BorderLayout.CENTER);
+
+        addComponentListener(new ComponentAdapter() {
+            @Override
+            public void componentResized(ComponentEvent e) {
+                Component source =e.getComponent();
+                scroller.setSize(source.getSize());
+                scroller.revalidate();
+            }
+        });
+
+        
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/geode/sequence/StateColorMap.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/sequence/StateColorMap.java 
b/geode-core/src/test/java/org/apache/geode/sequence/StateColorMap.java
new file mode 100644
index 0000000..0ef3ab7
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/sequence/StateColorMap.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.geode.sequence;
+
+import java.awt.*;
+import java.util.HashMap;
+import java.util.Map;
+
+import static java.lang.Math.random;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dsmith
+ * Date: Nov 12, 2010
+ * Time: 5:05:49 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class StateColorMap {
+    private Map<Object, Color> colors = new HashMap<Object, Color>();
+    private static Color[] PREDEFINED_COLORS = new Color[] { Color.BLUE, 
Color.BLACK, Color.PINK, Color.CYAN, Color.ORANGE, Color.GREEN};
+
+    private ColorList colorList = new ColorList();
+
+    public StateColorMap() {
+        colors.put("created", Color.GREEN);
+        colors.put("destroyed", Color.WHITE);
+        colors.put("persisted", new Color(0, 150, 0));
+    }
+
+
+    public Color getColor(Object state) {
+        Color color = colors.get(state);
+        if(color == null) {
+            color = colorList.nextColor();
+            colors.put(state, color);
+        }
+
+        return color;
+    }
+
+    private static class ColorList {
+        int colorIndex;
+
+        public Color nextColor() {
+            if(colorIndex < PREDEFINED_COLORS.length) {
+                return PREDEFINED_COLORS[colorIndex++];
+            } else {
+                return Color.getHSBColor((float)random(), (float)random(), 
(float)random());
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/geode/sequence/TimeAxis.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/sequence/TimeAxis.java 
b/geode-core/src/test/java/org/apache/geode/sequence/TimeAxis.java
new file mode 100644
index 0000000..39d14ff
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/sequence/TimeAxis.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.geode.sequence;
+
+import javax.swing.*;
+import java.awt.*;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dsmith
+ * Date: Oct 29, 2010
+ * Time: 5:24:54 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class TimeAxis extends JComponent {
+    public static final int HORIZONTAL = 0;
+    public static final int VERTICAL = 1;
+    public static final int SIZE = 100;
+    private static final DateFormat DATE_FORMAT = new 
SimpleDateFormat("HH:mm:ss.SSS");
+
+    public int orientation;
+    private long minTime;
+    private long maxTime;
+
+    public TimeAxis(int orientation, long minTime, long maxTime) {
+        this.orientation = orientation;
+        this.minTime = minTime;
+        this.maxTime = maxTime;
+    }
+
+    public void setPreferredHeight(int ph) {
+        setPreferredSize(new Dimension(SIZE, ph));
+    }
+
+    public void setPreferredWidth(int pw) {
+        setPreferredSize(new Dimension(pw, SIZE));
+    }
+
+    protected void paintComponent(Graphics g) {
+        Rectangle drawHere = g.getClipBounds();
+
+        int height = getHeight();
+
+        double scale = (maxTime - minTime) / height;
+        int increment = 30;
+        // Fill clipping area with dirty brown/orange.
+        g.setColor(new Color(230, 163, 4));
+        g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height);
+
+        // Do the ruler labels in a small font that's black.
+        g.setFont(new Font("SansSerif", Font.PLAIN, 10));
+        g.setColor(Color.black);
+
+        // Some vars we need.
+        int end = 0;
+        int start = 0;
+        int tickLength = 0;
+        String text = null;
+
+        // Use clipping bounds to calculate first and last tick locations.
+        if (orientation == HORIZONTAL) {
+            start = (drawHere.x / increment) * increment;
+            end = (((drawHere.x + drawHere.width) / increment) + 1)
+                  * increment;
+        } else {
+            start = (drawHere.y / increment) * increment;
+            end = (((drawHere.y + drawHere.height) / increment) + 1)
+                  * increment;
+        }
+
+        // Make a special case of 0 to display the number
+        // within the rule and draw a units label.
+        if (start == 0) {
+            text = DATE_FORMAT.format(new Date(minTime));
+            tickLength = 10;
+            if (orientation == HORIZONTAL) {
+                g.drawLine(0, SIZE-1, 0, SIZE-tickLength-1);
+                g.drawString(text, 2, 21);
+            } else {
+                g.drawLine(SIZE-1, 0, SIZE-tickLength-1, 0);
+                g.drawString(text, 9, 10);
+            }
+            text = null;
+            start = increment;
+        }
+
+        // ticks and labels
+        for (int i = start; i < end; i += increment) {
+                tickLength = 10;
+                text = DATE_FORMAT.format(new Date((long) (minTime + i  * 
scale)));
+
+            if (tickLength != 0) {
+                if (orientation == HORIZONTAL) {
+                    g.drawLine(i, SIZE-1, i, SIZE-tickLength-1);
+                    if (text != null)
+                        g.drawString(text, i-3, 21);
+                } else {
+                    g.drawLine(SIZE-1, i, SIZE-tickLength-1, i);
+                    if (text != null)
+                        g.drawString(text, 9, i+3);
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/geode/sequence/ZoomingPanel.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/sequence/ZoomingPanel.java 
b/geode-core/src/test/java/org/apache/geode/sequence/ZoomingPanel.java
new file mode 100644
index 0000000..09f6ef6
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/sequence/ZoomingPanel.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.geode.sequence;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionAdapter;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dan
+ * Date: Oct 28, 2010
+ * Time: 10:30:40 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class ZoomingPanel extends JPanel {
+    private int zoomBoxStartX;
+    private int zoomBoxStartY;
+    private int zoomBoxWidth;
+    private int zoomBoxHeight;
+    private SequenceDiagram child;
+
+
+    public ZoomingPanel() {
+        super();
+        addMouseListener(new MouseAdapter() {
+            @Override
+            public void mousePressed(MouseEvent e) {
+                startBox(e.getX(), e.getY());
+            }
+
+            @Override
+            public void mouseReleased(MouseEvent e) {
+                endBox(e.getX(), e.getY());
+            }
+
+            @Override
+            public void mouseClicked(MouseEvent e) {
+                if (e.getButton() != MouseEvent.BUTTON1) {
+                    unzoom();    
+                } else {
+                  child.selectState(e.getX(), e.getY());
+                }
+                
+            }
+        });
+
+        addMouseMotionListener(new MouseMotionAdapter() {
+            @Override
+            public void mouseDragged(MouseEvent e) {
+                Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
+                ((JPanel)e.getSource()).scrollRectToVisible(r);
+                showBox(e.getX(), e.getY());
+            }
+
+            @Override
+            public void mouseMoved(MouseEvent e) {
+              int popupX = ZoomingPanel.this.getLocationOnScreen().x + 
e.getX();
+              int popupY = ZoomingPanel.this.getLocationOnScreen().y + 
e.getY();
+              child.showPopupText(e.getX(), e.getY(), popupX, popupY);
+            }
+        });
+        BorderLayout layout = new BorderLayout();
+        layout.setHgap(0);
+        layout.setVgap(0);
+        this.setLayout(layout);
+    }
+
+    private void unzoom() {
+        resizeMe(0, 0, getWidth(), getHeight());
+    }
+
+    void resizeMe(int zoomBoxX, int zoomBoxY, int zoomBoxWidth, int 
zoomBoxHeight) {
+        Dimension viewSize = getParent().getSize();
+        double windowWidth = viewSize.getWidth();
+        double  windowHeight = viewSize.getHeight();
+        double scaleX = getWidth() / ((double) zoomBoxWidth);
+        double scaleY = getHeight() / ((double) zoomBoxHeight);
+        int oldWidth = getWidth();
+        int oldHeight = getHeight();
+        int width = (int) (scaleX * windowWidth);
+        int height = (int) (scaleY * windowHeight);
+//        this.setPreferredSize(new Dimension(width, height));
+        child.resizeMe(width, height);
+        //TODO not sure this one is needed
+        this.revalidate();
+
+        //scroll to the new rectangle
+//        int scrollX = (int) (zoomBoxX * scaleX);
+//        int scrollY = (int) (zoomBoxY * scaleY);
+//        int scrollWidth= (int) (zoomBoxWidth * scaleX);
+//        int scrollHeight = (int) (zoomBoxHeight * scaleY);
+        int scrollX = (int) (zoomBoxX  *  (width / (double) oldWidth));
+        int scrollY = (int) (zoomBoxY *  (height / (double) oldHeight));
+        int scrollWidth= (int) (zoomBoxWidth *  (width / (double) oldWidth));
+        int scrollHeight = (int) (zoomBoxHeight *  (height / (double) 
oldHeight));        
+        Rectangle r = new Rectangle(scrollX, scrollY, scrollWidth, 
scrollHeight);
+        ((JViewport)getParent()).scrollRectToVisible(r);
+        repaint();
+
+    }
+
+    public void setSequenceDiagram(SequenceDiagram diag) {
+        this.child = diag;
+        this.add(child, BorderLayout.CENTER);
+    }
+
+    private void showBox(int x, int y) {
+        if(zoomBoxWidth != -1) {
+            repaint(getBoxX(), getBoxY(), getBoxWidth(), getBoxHeight());
+        }
+
+        this.zoomBoxWidth = x - zoomBoxStartX;
+        this.zoomBoxHeight = y - zoomBoxStartY;
+
+        repaint(getBoxX(), getBoxY(), getBoxWidth(), getBoxHeight());
+    }
+
+    private void startBox(int x, int y) {
+        this.zoomBoxStartX = x;
+        this.zoomBoxStartY = y;
+    }
+
+    private void endBox(int x, int y) {
+        if(zoomBoxStartX != -1 && zoomBoxStartY != -1
+                && zoomBoxWidth != -1 && zoomBoxHeight != -1
+                && zoomBoxWidth != 0 && zoomBoxHeight != 0) {
+            resizeMe(getBoxX() , getBoxY(), getBoxWidth(), getBoxHeight());
+            repaint(getBoxX(), getBoxY(), getBoxWidth(), getBoxHeight());
+            this.zoomBoxStartX = -1;
+            this.zoomBoxStartY = -1;
+            this.zoomBoxWidth = -1;
+            this.zoomBoxHeight = -1;
+        }
+    }
+
+    public int getBoxX() {
+        return zoomBoxWidth >= 0 ? zoomBoxStartX : zoomBoxStartX + 
zoomBoxWidth;
+    }
+
+    public int getBoxY() {
+        return zoomBoxHeight >= 0 ? zoomBoxStartY : zoomBoxStartY + 
zoomBoxHeight;
+    }
+
+    public int getBoxHeight() {
+        return zoomBoxHeight >= 0 ? zoomBoxHeight : -zoomBoxHeight;
+    }
+
+    public int getBoxWidth() {
+        return zoomBoxWidth >= 0 ? zoomBoxWidth : -zoomBoxWidth;
+    }
+
+
+
+    @Override
+    public void paint(Graphics g) {
+        super.paint(g);
+
+        if(zoomBoxStartX != -1 && zoomBoxStartY != -1 && zoomBoxWidth != -1 && 
zoomBoxHeight != -1) {
+            Graphics2D g2 = (Graphics2D) g.create();
+
+            Composite old = g2.getComposite();
+            
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
+            g2.setColor(Color.BLUE);
+
+//            g2.drawRect(zoomBoxStartX, zoomBoxStartY, zoomBoxWidth, 
zoomBoxHeight);
+//            g2.setBackground(Color.BLUE);
+            g2.fillRect(getBoxX(), getBoxY(), getBoxWidth(), getBoxHeight());
+            g2.setComposite(old);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/sequence/Arrow.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/sequence/Arrow.java 
b/geode-core/src/test/java/org/apache/sequence/Arrow.java
deleted file mode 100644
index 4274aa9..0000000
--- a/geode-core/src/test/java/org/apache/sequence/Arrow.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.sequence;
-
-import java.awt.*;
-import java.awt.geom.GeneralPath;
-
-/**
- * Created by IntelliJ IDEA.
- * User: dsmith
- * Date: Nov 12, 2010
- * Time: 12:02:20 PM
- * To change this template use File | Settings | File Templates.
- */
-public class Arrow {
-    private static int ARROW_WIDTH=10;
-    private static int CIRCLE_WIDTH=6;
-    private static int LABEL_OFFSET=10;
-
-    private final String label;
-    private final LifelineState startingState;
-    private final LifelineState endingState;
-
-    public Arrow(String label, LifelineState startingState, LifelineState 
endingState) {
-        this.label = label;
-        this.startingState = startingState;
-        this.endingState = endingState;
-    }
-
-
-    public void paint(Graphics2D g) {
-        Rectangle boundary = g.getClipBounds();
-        int y = endingState.getStartY();
-
-        //don't paint if we're not in the clip area
-        if(y + ARROW_WIDTH < boundary.getMinY() || y - ARROW_WIDTH > 
boundary.getMaxY()) {
-            return;
-        }
-
-        //TODO - we need to clip by X coordinate as well.
-        
-        boolean isReflexsive = getStartingLine() == getEndingLine();
-        if(isReflexsive) {
-            paintReflexive(g);
-        } else {
-            paintNormal(g);
-        }
-    }
-    
-    private Lifeline getStartingLine() {
-        return startingState.getLine();
-    }
-    
-    private Lifeline getEndingLine() {
-        return endingState.getLine();
-    }
-
-    private void paintReflexive(Graphics2D g) {
-        Lifeline startingLine = getStartingLine();
-        int x = startingLine.getX();
-        int y = endingState.getStartY();
-
-        g.drawArc(x + startingLine.getWidth() - ARROW_WIDTH / 2, y - 
ARROW_WIDTH, ARROW_WIDTH, ARROW_WIDTH, 90, -180);
-        g.drawString(label, x + startingLine.getWidth() + LABEL_OFFSET, y);
-//        GeneralPath path = new GeneralPath();
-//        path.moveTo(x, y - ARROW_WIDTH);
-//        path.quadTo(x, y - ARROW_WIDTH);
-    }
-
-    private void paintNormal(Graphics2D g) {
-        Lifeline startingLine = getStartingLine();
-        Lifeline endingLine = getEndingLine();
-        int x1 = startingLine.getX();
-        int x2 = endingLine.getX();
-        int y = endingState.getStartY();
-
-        if(x2 > x1) {
-            int startX  = x1 + startingLine.getWidth();
-            int endX = x2;
-
-            GeneralPath path = new GeneralPath();
-            path.moveTo(startX, y);
-            path.lineTo(endX, y);
-            path.lineTo(endX - ARROW_WIDTH, y - ARROW_WIDTH);
-            path.moveTo(endX, y);
-            path.lineTo(endX - ARROW_WIDTH, y + ARROW_WIDTH);
-            g.draw(path);
-            g.fillArc(startX, y - CIRCLE_WIDTH/2, CIRCLE_WIDTH, CIRCLE_WIDTH, 
0, 360);
-            g.drawString(label, startX + LABEL_OFFSET, y - LABEL_OFFSET);
-        } else {
-            int startX  = x1;
-            int endX = x2 + endingLine.getWidth();
-
-            GeneralPath path = new GeneralPath();
-            path.moveTo(startX, y);
-            path.lineTo(endX, y);
-            path.lineTo(endX + ARROW_WIDTH, y - ARROW_WIDTH);
-            path.moveTo(endX, y);
-            path.lineTo(endX + ARROW_WIDTH, y + ARROW_WIDTH);
-            g.draw(path);
-            int labelWidth = g.getFontMetrics().stringWidth(label);
-            g.fillArc(startX - CIRCLE_WIDTH/2, y - CIRCLE_WIDTH/2, 
CIRCLE_WIDTH, CIRCLE_WIDTH, 0, 360);
-            g.drawString(label, startX - LABEL_OFFSET - labelWidth, y - 
LABEL_OFFSET);
-        }
-    }
-
-    public LifelineState getStartingState() {
-      return startingState;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/sequence/Lifeline.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/sequence/Lifeline.java 
b/geode-core/src/test/java/org/apache/sequence/Lifeline.java
deleted file mode 100644
index f5de6ac..0000000
--- a/geode-core/src/test/java/org/apache/sequence/Lifeline.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.sequence;
-
-import java.awt.*;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Created by IntelliJ IDEA.
- * User: dsmith
- * Date: Oct 29, 2010
- * Time: 3:59:02 PM
- * To change this template use File | Settings | File Templates.
- */
-public class Lifeline {
-    private List<LifelineState> states;
-    private final String name;
-    private final Comparable diagramName;
-    private int x;
-    private int width;
-
-    public String getName() {
-        return name;
-    }
-
-    public int getX() {
-        return x;
-    }
-
-    public int getWidth() {
-        return width;
-    }
-
-    public void addState(LifelineState state) {
-        this.states.add(state);
-    }
-    
-    public Lifeline(Comparable diagramName, String name) {
-      this.name = name;
-      this.states = new ArrayList<LifelineState>();
-      this.diagramName = diagramName;
-    }
-
-    public void resize(int x, int lineWidth, long Ybase, double Yscale) {
-        for(LifelineState state : states) {
-            state.resize(Yscale, Ybase);
-        }
-
-        this.x = x;
-        width = lineWidth;
-    }
-
-    public void paint(Graphics2D g, StateColorMap colorMap) {
-        Rectangle boundary = g.getClipBounds();
-        if(x > boundary.getMaxX() || x + width < boundary.getMinX()) {
-            //no need to paint if this line isn't displayed
-            return;
-        }
-        //TODO - we need to clip these to the visible states
-        for(LifelineState state : states) {
-            state.paint(g, colorMap);
-        }
-    }
-
-    public List<LifelineState> getStates() {
-        return states;
-    }
-
-    public LifelineState getStateAt(int y) {
-        for(LifelineState state : states) {
-            if(state.getStartY() < y && state.getStartY() + state.getHeight() 
> y) {
-                return state;
-            }
-        }
-        return null;
-    }
-
-    public Comparable getDiagramName() {
-      return diagramName;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/sequence/LifelineState.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/sequence/LifelineState.java 
b/geode-core/src/test/java/org/apache/sequence/LifelineState.java
deleted file mode 100644
index 2f39c46..0000000
--- a/geode-core/src/test/java/org/apache/sequence/LifelineState.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.sequence;
-
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.swing.JLabel;
-
-/**
- * Created by IntelliJ IDEA.
- * User: dsmith
- * Date: Oct 29, 2010
- * Time: 3:45:07 PM
- * To change this template use File | Settings | File Templates.
- */
-public class LifelineState {
-    private final long startTime;
-    private final long endTime;
-    private final String stateName;
-    private int startY;
-    private int height;
-    private final Lifeline line;
-    private final Set<Arrow> inboundArrows = new HashSet<Arrow>();
-    private static final int ARC_SIZE = 10;
-
-    public int getStartY() {
-        return startY;
-    }
-
-    public int getHeight() {
-        return height;
-    }
-
-
-    public LifelineState(Lifeline line, String stateName, long startTime, long 
endTime) {
-        this.line = line;
-        this.stateName = stateName;
-        this.startTime = startTime;
-        this.endTime = endTime;
-    }
-
-    public void paint(Graphics2D g, StateColorMap colorMap) {
-        Rectangle bounds = g.getClipBounds();
-        if(startY > bounds.getMaxY()  || startY+height <bounds.getMinY()) {
-            return;
-        }
-        
-        int x = line.getX();
-        int width  = line.getWidth();
-
-        Color color = colorMap.getColor(stateName);
-        g.setColor(color);
-        g.fillRoundRect(x, startY, width, height, ARC_SIZE, ARC_SIZE);
-        g.setColor(Color.BLACK);
-    }
-    
-    public void highlight(Graphics2D g) {
-      Rectangle bounds = g.getClipBounds();
-      if(startY > bounds.getMaxY()  || startY+height <bounds.getMinY()) {
-          return;
-      }
-      
-      int x = line.getX();
-      int width  = line.getWidth();
-
-      g.drawRoundRect(x, startY, width, height, ARC_SIZE, ARC_SIZE);
-    }
-
-    public void resize(double scale, long base) {
-        startY = (int)  ((startTime - base) * scale);
-        height = (int) ((endTime - startTime) * scale);
-    }
-
-    public Component getPopup() {
-        return new JLabel("<html>Object: " + line.getDiagramName() + 
"<br>Member: " + line.getName() + "<br>State: " + stateName + "<br>Time:" + new 
Date(startTime) + "</html>");
-    }
-
-    public Lifeline getLine() {
-      return line;
-    }
-
-    public void addInboundArrow(Arrow arrow) {
-      inboundArrows.add(arrow);
-    }
-
-    public Set<Arrow> getInboundArrows() {
-      return inboundArrows;
-    }
-    
-    @Override
-    public String toString() {
-      return line.getName() + "@" + startTime + ":" + stateName;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/5ba853da/geode-core/src/test/java/org/apache/sequence/LineMapper.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/sequence/LineMapper.java 
b/geode-core/src/test/java/org/apache/sequence/LineMapper.java
deleted file mode 100644
index d9c7e08..0000000
--- a/geode-core/src/test/java/org/apache/sequence/LineMapper.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.sequence;
-
-/**
- * An interface for mapping a lifeline name to a shorter version of the same
- * line. This could also consolodate multiple lifelines onto a single line.
- * 
- * The most common case for this is that a lifeline represents a VM that is
- * restarted several times. Eg time, the line name changes, but we want to put
- * all of the states for that "logical" vm on the same line.
- *
- */
-public interface LineMapper {
-  
-  /**
-   * Return the short name for this lifeline.
-   */
-  public String getShortNameForLine(String lineName);
-
-}

Reply via email to