diff --git a/ThreadProfile.stp b/ThreadProfile.stp
index 4d7fe50..daab497 100644
--- a/ThreadProfile.stp
+++ b/ThreadProfile.stp
@@ -39,31 +39,30 @@ probe process(@1).function("*").call {
 		setup();
 		pid = pid();
 	}
+	if (! threadcounters[tid()] ) {
+		threadstacks[tid()] = probefunc();
+	}
 	threadcounters[tid()]++;
-	threadstacks[tid(),threadcounters[tid()]] = probefunc();
 }
 
 probe process(@1).function("*").return {
-    delete(threadstacks[tid(),threadcounters[tid()]]);
-    if (threadcounters[tid()] == 1) {
+	threadcounters[tid()]--;
+    if (! threadcounters[tid()]) {
     	delete(threadcounters[tid()]);
-    	delete(threadstacks[tid(),0]);
+    	delete(threadstacks[tid()]);
     }
-    else
-    	threadcounters[tid()]--;
 }
 
 
 # ------------------------------------------------------------------------
 # general gnuplot graphical report generation
 
-probe timer.ms(500) {
+probe timer.ms(100) {
   printf("--\n");
   printf("%d, %d, %d, %d, %d, %d, %d, %d\n", counter, qsq_util_reset("cpu"), qsq_util_reset("ioblock"), proc_mem_size() * mem_page_size(), proc_mem_data() * mem_page_size(), reads + writes, reads, writes);
   foreach (tid in threadcounters) {
-     printf("%d:%s\n", tid, threadstacks[tid, 1]);
+     printf("%d:%s\n", tid, threadstacks[tid]);
   }
-  printf("--\n");
   reads = 0;
   writes = 0;
   counter++;
diff --git a/bin/org/eclipse/linuxtools/threadprofiler/DataPoint.class b/bin/org/eclipse/linuxtools/threadprofiler/DataPoint.class
index a620579..9f26a69 100644
Binary files a/bin/org/eclipse/linuxtools/threadprofiler/DataPoint.class and b/bin/org/eclipse/linuxtools/threadprofiler/DataPoint.class differ
diff --git a/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.class b/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.class
index 2876d9d..a35972d 100644
Binary files a/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.class and b/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.class differ
diff --git a/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.class b/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.class
index 2015b3b..924310a 100644
Binary files a/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.class and b/bin/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.class differ
diff --git a/src/org/eclipse/linuxtools/threadprofiler/DataPoint.java b/src/org/eclipse/linuxtools/threadprofiler/DataPoint.java
index 8deb632..cac1b2d 100644
--- a/src/org/eclipse/linuxtools/threadprofiler/DataPoint.java
+++ b/src/org/eclipse/linuxtools/threadprofiler/DataPoint.java
@@ -1,10 +1,22 @@
 package org.eclipse.linuxtools.internal.threadprofiler;
 
 public class DataPoint {
+	
+	/** Indicates that this is a raw data point */
 	public static final int DATA_POINT = 0;
+	
+	/** Indicates that this is a point relative to the axis  */
 	public static final int AXIS_POINT = 1;
+	
+	/** Indicates that this is an absolute pixel point */
 	public static final int PIXEL_POINT = 2;
 	
+	/** Inactive, do not draw this point */
+	public static final int INACTIVE = 0;
+	
+	/** Active, draw this point */
+	public static final int ACTIVE = 1;
+	
 	private int[] values;
 	
 	private int type;
diff --git a/src/org/eclipse/linuxtools/threadprofiler/ThreadGraph.java b/src/org/eclipse/linuxtools/threadprofiler/ThreadGraph.java
index 9cc6ec7..f6c5dec 100644
--- a/src/org/eclipse/linuxtools/threadprofiler/ThreadGraph.java
+++ b/src/org/eclipse/linuxtools/threadprofiler/ThreadGraph.java
@@ -1,21 +1,74 @@
 package org.eclipse.linuxtools.internal.threadprofiler;
 
-public class ThreadGraph {
-	
-	private final String name;
-	private final int tid;
+import java.util.Iterator;
+
+import org.eclipse.linuxtools.internal.threadprofiler.graphs.GraphModel;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Composite;
+
+public class ThreadGraph extends GraphModel{
+
+	private int tid;
+	private DataPoint dp;
+	private boolean empty;
 	
-	public ThreadGraph(int tid, String name) {
-		this.name = name;
+	public ThreadGraph(String name, int x, int y, int type, String units, int tid) {
+		super(name, x, y, type, units);
 		this.tid = tid;
+		empty = false;
 	}
 	
 	public int getTid() {
 		return tid;
 	}
 	
-	public String getName() {
-		return name;
+	private void setEmpty(boolean val) {
+		empty = val;
+	}
+	
+	/**
+	 * Returns true if this graph has data points and they are all empty
+	 * 
+	 * @return
+	 */
+	public boolean isEmpty() {
+		return empty;
+	}
+	
+	@Override
+	public void drawOn(GC gc, Composite graphCanvas) {
+		int increment = (graphCanvas.getSize().x - this.getXOffset())/GraphModel.BUFFER_SIZE;
+
+		//Each thread should only have one buffer
+		Iterator<DataPoint> buffer = data.get(0).getIterator();
+		int xPos = this.getXOffset();
+		boolean em = true;
+		if (!buffer.hasNext())
+			em = false;
+		while (buffer.hasNext()) {
+			DataPoint p = buffer.next();
+			if (p.getType() == DataPoint.ACTIVE) {
+				em = false;
+				gc.drawLine(xPos, getYOffset(), xPos + increment, getYOffset());
+			}
+			xPos += increment;
+		}
+		
+		setEmpty(em);
+	}
+
+	public void prep(DataPoint dataPoint, int i) {
+		dp = dataPoint;
+	}
+	
+	public void tick() {
+		//TODO: This method if updating requires passing around a bulky datapoint variable
+		if (dp != null)
+			add(dp, 0);
+		else {
+			add(new DataPoint(0, 0, DataPoint.INACTIVE), 0);
+		}
+		dp = null;
 	}
 
 }
diff --git a/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.java b/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.java
index d9dac71..6fcd306 100644
--- a/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.java
+++ b/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerParser.java
@@ -33,21 +33,20 @@ public class ThreadProfilerParser extends SystemTapParser {
 		boolean changed = false;
 		try {
 			while ((line = buff.readLine()) != null) {
-				System.out.println("Parsed: " + line);
+//				System.out.println("Parsed: " + line);
 				changed = true;
-				if (line.equals("--"))
+				if (line.equals("--")) {
+					((ThreadProfilerView) view).closeThreads();
 					continue;
+				}
 				if (line.contains(", ")) {
 					String[] blargh = line.split(", ");
-					((ThreadProfilerView) view).addNextCPUPoint(counter, blargh);
-					((ThreadProfilerView) view).addNextMemoryPoint(counter++, blargh);
-					((ThreadProfilerView) view).addNextDiskPoint(counter++, blargh);
+					((ThreadProfilerView) view).addDataPoints(counter++, blargh);
 				} else {
 					String[] data = line.split(":");
 					int tid = Integer.parseInt(data[0]);
 					((ThreadProfilerView) view).addThread(tid, data[1]);
 				}
-				
 			}
 			if (changed) view.update();
 		} catch (NumberFormatException e) {
diff --git a/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.java b/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.java
index 2dbaaf7..40b7460 100644
--- a/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.java
+++ b/src/org/eclipse/linuxtools/threadprofiler/ThreadProfilerView.java
@@ -1,265 +1,297 @@
-package org.eclipse.linuxtools.internal.threadprofiler;
-
-import java.util.ArrayList;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.linuxtools.callgraph.core.SystemTapView;
-import org.eclipse.linuxtools.internal.threadprofiler.graphs.GraphModel;
-import org.eclipse.linuxtools.internal.threadprofiler.graphs.MultiGraph;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Canvas;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-
-public class ThreadProfilerView extends SystemTapView {
-	private static final int CPU_BUFFER = 0;
-	private static final int MEM_BUFFER = 1;
-	private static final int DISK_BUFFER = 2;
-	private ArrayList<GraphModel> graphs;
-	private ArrayList<ThreadGraph> threads;
-
-	private Composite graphCanvas;
-	private Canvas threadCanvas;
-	private final long REFRESH_TIME_MS = 700;
-	private final static int GRAPH_SEPARATION = 40;
-	private long time;
-	private int segments;
-
-	/*
-	 * We have two frames of reference: 
-	 * 
-	 *  1. Pixel frame (absolute frame)
-	 *  2. Axis frame (relative frame)
-	 *  
-	 *  The transformation from 1 to 2 is a coordinate shift and scale
-	 *  
-	 */
-	
-	
-	@Override
-	protected boolean createOpenAction() {
-		return false;
-	}
-
-	@Override
-	protected boolean createOpenDefaultAction() {
-		return false;
-	}
-
-	@Override
-	public IStatus initializeView(Display targetDisplay,
-			IProgressMonitor monitor) {
-		if (graphs == null)
-			graphs = new ArrayList<GraphModel>();
-		if (threads == null)
-			threads = new ArrayList<ThreadGraph>();
-		graphs.clear();
-		threads.clear();
-		segments = 0;
-
-		//Create dataSet for CPU
-		createNewDataSet("CPU", GraphModel.CONSTANT_Y, "%");
-		((MultiGraph) graphs.get(0)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
-		((MultiGraph) graphs.get(0)).addBuffer(GraphModel.BUFFER_SIZE, "IO Block");
-		
-		//Create dataSet for memory
-		createNewDataSet("Memory", GraphModel.FLEXIBLE_Y, "bytes");
-		((MultiGraph) graphs.get(1)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
-		((MultiGraph) graphs.get(1)).addBuffer(GraphModel.BUFFER_SIZE, "Data");
-		
-		//Create dataSet for disk usage
-		createNewDataSet("Disk", GraphModel.FLEXIBLE_Y, "bytes");
-		((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
-		((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Read");
-		((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Write");
-		((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_FILL);
-		((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_LINE);
-		((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_LINE);
-
-		time = System.currentTimeMillis();
-		
-		graphCanvas.addMouseListener(new MouseListener() {
-
-			@Override
-			public void mouseDoubleClick(MouseEvent e) {
-				updateMethod();
-			}
-
-			@Override
-			public void mouseDown(MouseEvent e) {
-				System.out.println("LOCATION: " + e.x + "," + e.y);
-			}
-
-			@Override
-			public void mouseUp(MouseEvent e) {
-				// TODO Auto-generated method stub
-				
-			}
-			
-		});
-		
-	    graphCanvas.addPaintListener(new PaintListener() {
-	        public void paintControl(PaintEvent e) {
-//	        	if (!graphs.get(0).isChanged())
-//	        		return;
-	        	
-	        	
-	        	for (int i = 0; i < graphs.size(); i ++) {
-	        		GraphModel graph = graphs.get(i);
-	        		GC gc = new GC(graphCanvas);
-	        		gc.setLineWidth(2);
-	        		graph.setHeight((int) (graphCanvas.getSize().y/(2.5*graphs.size())));
-	        		graph.setYAxisCoordinate((graph.getHeight() + GRAPH_SEPARATION) *(i + 1));
-	        		graph.drawOn(gc, graphCanvas);
-	        		gc.dispose();
-	        	}
-	        }
-	    }); 
-	    
-	    
-	    threadCanvas.addPaintListener(new PaintListener() {
-
-			@Override
-			public void paintControl(PaintEvent e) {
-				if (threads == null)
-					return;
-				int yOffset = 40;
-				
-	        	GC gc = new GC(threadCanvas);
-	        	gc.setLineWidth(4);
-        		gc.setForeground(new Color(Display.getCurrent(), 0, 0, 200));
-        		int increment = (graphCanvas.getSize().x - 40)/GraphModel.BUFFER_SIZE;
-
-				for (ThreadGraph tg : threads) {
-					gc.drawText(tg.getName(), 40, yOffset);
-					gc.drawLine(40, yOffset, 40 + increment*segments, yOffset);
-				}
-			}
-	    	
-	    });
-	    
-		return Status.OK_STATUS;
-	}
-
-	private void createNewDataSet(String name, int type, String units) {
-		GraphModel graph = new MultiGraph(name, 50, (GraphModel.DEFAULT_HEIGHT + GRAPH_SEPARATION) *(graphs.size() + 1), type, units);
-		graphs.add(graph);
-	}
-
-	@Override
-	public void setViewID() {
-		viewID = "org.eclipse.linuxtools.internal.threadprofiler.ThreadProfilerView";
-	}
-
-	@Override
-	public void updateMethod() {
-    	if (System.currentTimeMillis() - time < REFRESH_TIME_MS)
-    		return;
-    	time = System.currentTimeMillis();
-		graphCanvas.redraw();
-	}
-	
-	@Override
-	public void createPartControl(Composite parent) {
-		GridLayout gl = new GridLayout(1, true);
-		parent.setLayout(gl);
-		Color white = new Color(Display.getCurrent(), 255, 255, 255);
-    	
-		graphCanvas = new Composite(parent, SWT.BORDER);
-    	graphCanvas.setBackground(white);
-    	GridData gd = new GridData(GridData.FILL_BOTH);
-    	gd.grabExcessHorizontalSpace = true;
-    	graphCanvas.setLayoutData(gd);
-
-    	threadCanvas = new Canvas(parent, SWT.BORDER);
-    	threadCanvas.setBackground(white);
-    	gd = new GridData(GridData.FILL_BOTH);
-    	gd.grabExcessHorizontalSpace = true;
-    	threadCanvas.setLayoutData(gd);
-	}
-	
-	@Override
-	public void setFocus() {
-		//Do nothing
-	}
-	
-
-	public void addNextCPUPoint(int counter, String[] blargh) {
-		if (blargh.length < 2)
-			return;
-		this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[1]), 1), CPU_BUFFER, 0);
-		
-		if (blargh.length < 3)
-			return;
-		this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[2]), 1), CPU_BUFFER, 1);
-	}
-	
-	public void addNextMemoryPoint(int counter, String[] blargh) {
-		if (blargh.length < 4)
-			return;
-		this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[3]), 1), MEM_BUFFER, 0);		
-		if (blargh.length < 5)
-			return;
-		this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[4]), 1), MEM_BUFFER, 1);
-	}
-	
-	public void addNextDiskPoint(int counter, String[] blargh) {
-		if (blargh.length < 6)
-			return;
-		addPoint(new DataPoint(counter, Integer.parseInt(blargh[5]), 1), DISK_BUFFER, 0);
-		
-		if (blargh.length < 7)
-			return;
-		addPoint(new DataPoint(counter, Integer.parseInt(blargh[6]), 1), DISK_BUFFER, 1);
-		
-		if (blargh.length < 8)
-			return;
-		addPoint(new DataPoint(counter, Integer.parseInt(blargh[7]), 1), DISK_BUFFER, 2);
-	}
-	
-	private void addPoint(DataPoint point, int dataSet, int subIndex) {
-		if (graphs.size() < 1)
-			return;
-		if (segments < GraphModel.BUFFER_SIZE)
-			segments++;
-		graphs.get(dataSet).add(point, subIndex);
-	}
-
-	public void addThread(int tid, String line) {
-		if (!threadExists(tid)) {
-			ThreadGraph tg = new ThreadGraph(tid, line);
-			threads.add(tg);
-		}
-	}
-	
-	/**
-	 * Returns true if a thread with the given tid exists
-	 * 
-	 * @param tid
-	 * @return
-	 */
-	private boolean threadExists(int tid) {
-		boolean exists = false;
-		for (ThreadGraph g : threads) {
-			if (g.getTid() == tid) {
-				exists = true;
-				break;
-			}
-		}
-		return exists;
-	}
-
-
+package org.eclipse.linuxtools.internal.threadprofiler;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.linuxtools.callgraph.core.SystemTapView;
+import org.eclipse.linuxtools.internal.threadprofiler.graphs.GraphModel;
+import org.eclipse.linuxtools.internal.threadprofiler.graphs.MultiGraph;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+public class ThreadProfilerView extends SystemTapView {
+	private static final int CPU_BUFFER = 0;
+	private static final int MEM_BUFFER = 1;
+	private static final int DISK_BUFFER = 2;
+	
+	private static final int START_X_POS = 50;
+	private ArrayList<GraphModel> graphs;
+	private ArrayList<ThreadGraph> threads;
+
+	private Composite graphCanvas;
+	private Canvas threadCanvas;
+	private final static int GRAPH_SEPARATION = 40;
+	private int segments;
+
+	/*
+	 * We have two frames of reference: 
+	 * 
+	 *  1. Pixel frame (absolute frame)
+	 *  2. Axis frame (relative frame)
+	 *  
+	 *  The transformation from 1 to 2 is a coordinate shift and scale
+	 *  
+	 */
+	
+	
+	@Override
+	protected boolean createOpenAction() {
+		return false;
+	}
+
+	@Override
+	protected boolean createOpenDefaultAction() {
+		return false;
+	}
+
+	@Override
+	public IStatus initializeView(Display targetDisplay,
+			IProgressMonitor monitor) {
+		if (graphs == null)
+			graphs = new ArrayList<GraphModel>();
+		if (threads == null)
+			threads = new ArrayList<ThreadGraph>();
+		graphs.clear();
+		threads.clear();
+		segments = 0;
+
+		//Create dataSet for CPU
+		createNewDataSet("CPU", GraphModel.CONSTANT_Y, "%");
+		((MultiGraph) graphs.get(0)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
+		((MultiGraph) graphs.get(0)).addBuffer(GraphModel.BUFFER_SIZE, "IO Block");
+		
+		//Create dataSet for memory
+		createNewDataSet("Memory", GraphModel.FLEXIBLE_Y, "bytes");
+		((MultiGraph) graphs.get(1)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
+		((MultiGraph) graphs.get(1)).addBuffer(GraphModel.BUFFER_SIZE, "Data");
+		
+		//Create dataSet for disk usage
+		createNewDataSet("Disk", GraphModel.FLEXIBLE_Y, "bytes");
+		((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Total");
+		((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Read");
+		((MultiGraph) graphs.get(2)).addBuffer(GraphModel.BUFFER_SIZE, "Write");
+		((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_FILL);
+		((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_LINE);
+		((MultiGraph) graphs.get(2)).addStyle(MultiGraph.GRAPH_STYLE_LINE);
+
+		graphCanvas.addMouseListener(new MouseListener() {
+
+			@Override
+			public void mouseDoubleClick(MouseEvent e) {
+				updateMethod();
+			}
+
+			@Override
+			public void mouseDown(MouseEvent e) {
+				System.out.println("LOCATION: " + e.x + "," + e.y);
+			}
+
+			@Override
+			public void mouseUp(MouseEvent e) {
+				// TODO Auto-generated method stub
+				
+			}
+			
+		});
+		
+	    graphCanvas.addPaintListener(new PaintListener() {
+	        public void paintControl(PaintEvent e) {
+	        	//TODO: If the script is running and the graph is not changed, 
+	        	//there is no need to update yet.
+	        	for (int i = 0; i < graphs.size(); i ++) {
+	        		GraphModel graph = graphs.get(i);
+	        		GC gc = new GC(graphCanvas);
+	        		gc.setLineWidth(2);
+	        		graph.setHeight((int) (graphCanvas.getSize().y/(2.5*graphs.size())));
+	        		graph.setYAxisCoordinate((graph.getHeight() + GRAPH_SEPARATION) *(i + 1));
+	        		graph.drawOn(gc, graphCanvas);
+	        		gc.dispose();
+	        	}
+	        }
+	    }); 
+	    
+	    
+	    threadCanvas.addPaintListener(new PaintListener() {
+	    	
+
+			@Override
+			public void paintControl(PaintEvent e) {
+				if (threads == null)
+					return;
+				int yOffset = GRAPH_SEPARATION;
+				
+	        	GC gc = new GC(threadCanvas);
+	        	Color fg = new Color(Display.getCurrent(), 0, 0, 200);
+        		gc.setForeground(fg);
+
+        		int counter = 0;
+        		ArrayList<ThreadGraph> toRemove = new ArrayList<ThreadGraph>();
+				for (ThreadGraph tg : threads) {
+					counter++;
+					tg.setYAxisCoordinate(counter*yOffset);
+					gc.setLineWidth(2);
+					tg.drawOn(gc, graphCanvas); 
+					gc.setLineWidth(0);
+					gc.drawText(tg.getTitle(), START_X_POS, counter*yOffset, true);
+					if (tg.isEmpty())
+						toRemove.add(tg);
+				}
+				//TODO: O(N^2) operation
+				threads.removeAll(toRemove);
+				fg.dispose();
+				gc.dispose();
+			}
+	    });
+	    
+		return Status.OK_STATUS;
+	}
+
+	private void createNewDataSet(String name, int type, String units) {
+		GraphModel graph = new MultiGraph(name, START_X_POS, (GraphModel.DEFAULT_HEIGHT + GRAPH_SEPARATION) *(graphs.size() + 1), type, units);
+		graphs.add(graph);
+	}
+
+	@Override
+	public void setViewID() {
+		viewID = "org.eclipse.linuxtools.internal.threadprofiler.ThreadProfilerView";
+	}
+
+	@Override
+	public void updateMethod() {
+		graphCanvas.redraw();
+		threadCanvas.redraw();
+	}
+	
+	@Override
+	public void createPartControl(Composite parent) {
+		GridLayout gl = new GridLayout(1, true);
+		parent.setLayout(gl);
+		Color white = new Color(Display.getCurrent(), 255, 255, 255);
+    	
+    	ScrolledComposite graphComp =new ScrolledComposite(parent, SWT.BORDER | SWT.V_SCROLL);
+    	graphComp.setLayout (new GridLayout(1, true));
+    	graphComp.setBackground(white);
+    	GridData gd = new GridData(GridData.FILL_BOTH);
+    	gd.grabExcessHorizontalSpace = true;
+    	graphComp.setLayoutData(gd);
+    	
+		graphCanvas = new Canvas(graphComp, SWT.BORDER | SWT.V_SCROLL);
+    	graphCanvas.setBackground(white);
+    	gd = new GridData(GridData.FILL_BOTH);
+    	gd.grabExcessHorizontalSpace = true;
+    	graphCanvas.setLayoutData(gd);
+    	
+    	ScrolledComposite threadComp =new ScrolledComposite(parent, SWT.BORDER | SWT.V_SCROLL);
+    	threadComp.setLayout (new GridLayout(1, true));
+    	threadComp.setBackground(white);
+    	gd = new GridData(GridData.FILL_BOTH);
+    	gd.grabExcessHorizontalSpace = true;
+    	threadComp.setLayoutData(gd);
+    	
+    	threadCanvas = new Canvas(graphComp, SWT.BORDER | SWT.V_SCROLL);
+    	threadCanvas.setBackground(white);
+    	gd = new GridData(GridData.FILL_BOTH);
+    	gd.grabExcessHorizontalSpace = true;
+    	threadCanvas.setLayoutData(gd);
+	}
+	
+	@Override
+	public void setFocus() {
+		//Do nothing
+	}
+	
+
+	
+	public void addDataPoints(int counter, String[] blargh) {
+		if (segments < GraphModel.BUFFER_SIZE)
+			segments++;
+		if (blargh.length < 2)
+			return;
+		this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[1]), 1), CPU_BUFFER, 0);
+		
+		if (blargh.length < 3)
+			return;
+		this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[2]), 1), CPU_BUFFER, 1);
+		
+		if (blargh.length < 4)
+			return;
+		this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[3]), 1), MEM_BUFFER, 0);
+		
+		if (blargh.length < 5)
+			return;
+		this.addPoint(new DataPoint(counter, Integer.parseInt(blargh[4]), 1), MEM_BUFFER, 1);
+		
+		if (blargh.length < 6)
+			return;
+		addPoint(new DataPoint(counter, Integer.parseInt(blargh[5]), 1), DISK_BUFFER, 0);
+		
+		if (blargh.length < 7)
+			return;
+		addPoint(new DataPoint(counter, Integer.parseInt(blargh[6]), 1), DISK_BUFFER, 1);
+		
+		if (blargh.length < 8)
+			return;
+		addPoint(new DataPoint(counter, Integer.parseInt(blargh[7]), 1), DISK_BUFFER, 2);
+	}
+	
+	
+	private void addPoint(DataPoint point, int dataSet, int subIndex) {
+		if (graphs.size() < 1)
+			return;
+		graphs.get(dataSet).add(point, subIndex);
+	}
+
+	public void addThread(int tid, String line) {
+		int i = threadExists(tid);
+		if (i < 0) {
+			ThreadGraph tg = new ThreadGraph(line, START_X_POS, GRAPH_SEPARATION, 0, "", tid);
+			for (int j = 0; j < segments; j++) {
+				//Fill with empty segments
+				tg.add(new DataPoint(0, 0, DataPoint.INACTIVE), 0);
+			}
+				threads.add(tg);
+			i = threads.size() - 1;
+		}
+		threads.get(i).prep(new DataPoint(0, 0, DataPoint.ACTIVE), 0);
+	}
+	
+
+	public void closeThreads() {
+		// TODO Auto-generated method stub
+		for (ThreadGraph tg : threads) {
+			tg.tick();
+		}
+	}		
+	
+	/**
+	 * Returns true if a thread with the given tid exists
+	 * 
+	 * @param tid
+	 * @return
+	 */
+	private int threadExists(int tid) {
+		for (int i = 0; i < threads.size(); i++) {
+			if (threads.get(i).getTid() == tid) {
+				return i;
+			}
+		}
+		return -1;
+	}
+
+
+
 }
\ No newline at end of file
diff --git a/src/org/eclipse/linuxtools/threadprofiler/graphs/GraphModel.java b/src/org/eclipse/linuxtools/threadprofiler/graphs/GraphModel.java
index 5bf0531..1b07e18 100644
--- a/src/org/eclipse/linuxtools/threadprofiler/graphs/GraphModel.java
+++ b/src/org/eclipse/linuxtools/threadprofiler/graphs/GraphModel.java
@@ -1,226 +1,229 @@
-package org.eclipse.linuxtools.internal.threadprofiler.graphs;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.eclipse.linuxtools.internal.threadprofiler.CircularPointBuffer;
-import org.eclipse.linuxtools.internal.threadprofiler.CoordinateSystem;
-import org.eclipse.linuxtools.internal.threadprofiler.DataPoint;
-import org.eclipse.linuxtools.internal.threadprofiler.GraphAxis;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.widgets.Canvas;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-
-public abstract class GraphModel {
-	
-	//Constant Y scale
-	public static final int CONSTANT_Y = 0;
-	//Change Y scale as the maximum y point increases
-	public static final int FLEXIBLE_Y = 1;
-	//Maximum buffer size
-	public static final int BUFFER_SIZE = 30;
-	//Default height
-	public static final int DEFAULT_HEIGHT = 100;
-	
-	private final CoordinateSystem coordinates;
-	private final DataPoint startPoint;
-	private final int graphType;
-	private final String title;
-	private final String units;
-	private boolean changed;
-	protected final ArrayList<CircularPointBuffer> data;
-	
-	private int height;
-	
-	private int maxY;
-	//Height in pixels
-	
-	public GraphModel(String name, int x, int y, int type, String units) {
-		graphType = type;
-		changed = false;
-		data = new ArrayList<CircularPointBuffer>();
-		title = name;
-		this.units = units;
-		height = DEFAULT_HEIGHT;
-		maxY = 100;
-		coordinates = new CoordinateSystem(x, y);
-		coordinates.setYScale(0.2);
-		coordinates.getAxis().setTopLabel(DEFAULT_HEIGHT + units);
-		
-		startPoint = new DataPoint(coordinates.getXOffset(), coordinates.getYOffset(), 1);
-	}
-	
-	public void setMaxY(int max) {
-		maxY = max;
-	}
-	
-	public int getXOffset() {
-		return (int) coordinates.getAxisToPixel().entries[0][2];
-	}
-	
-	public int getYOffset() {
-		return (int) coordinates.getAxisToPixel().entries[1][2];
-	}
-
-
-	/**
-	 * 
-	 * @return
-	 * 			  First available point buffer if any is available, else null
-	 */
-	public Iterator<DataPoint> getPointBuffer() {
-		if (data.size() > 1)
-			return getPointBuffer(0);
-		return null;
-	}
-	
-	public Iterator<DataPoint> getPointBuffer(int index) {
-		return data.get(index).getIterator();
-	}
-
-	public GraphAxis getAxis() {
-		return coordinates.getAxis();
-	}
-	
-	public DataPoint getStartPoint() {
-		return startPoint;
-	}
-
-	public void add(DataPoint point, int subIndex) {
-		if (subIndex >= data.size()) {
-			data.add(new CircularPointBuffer(BUFFER_SIZE));
-		}
-		if (graphType == FLEXIBLE_Y) {
-			if (point.getY() > maxY ) {
-				maxY = point.getY();
-				coordinates.getAxis().setTopLabel(maxY + " " + units);
-				if ( point.getY() > height) {
-					double newScale = (double) height/maxY;
-					coordinates.setYScale(newScale);
-				}
-			}
-		}
-		data.get(subIndex).add(point);
-		setChanged(true);
-	}
-	
-	public DataPoint transform(DataPoint toTransform) {
-		return coordinates.dataToPixel(toTransform);
-	}
-
-	public boolean isChanged() {
-		return changed;
-	}
-	
-	public void setChanged(boolean val) {
-		changed = val;
-	}
-
-	public String getTitle() {
-		return title;
-	}
-
-	public int getHeight() {
-		return height;
-	}
-	
-	public void setHeight(int value) {
-		if (height == value)
-			return;
-		height = value;
-		double newScale = (double) height/maxY;
-		coordinates.setYScale(newScale);
-	}
-
-
-	public void setYAxisCoordinate(int value) {
-		coordinates.setYAxisCoordinate(value);
-		startPoint.setY(value);
-	}
-	
-	public void setXAxisCoordinate(int value) {
-		coordinates.setXAxisCoordinate(value);
-		startPoint.setX(value);
-	}
-
-
-	public CoordinateSystem getCoordinates() {
-		return coordinates;
-	}
-
-	/**
-	 * The main draw function -- implement this method to change
-	 * the way things are graphed
-	 * 
-	 * @param gc
-	 * @param graphCanvas
-	 */
-	public abstract void drawOn(GC gc, Composite graphCanvas);
-
-	
-	protected void drawLine(GC gc, DataPoint p1, DataPoint p2) {
-		gc.drawLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
-	}
-	
-	/**
-	 * 
-	 * @return
-	 * 			  Number of data buffers in this model
-	 */
-	public int getBufferCount() {
-		return data.size();
-	}
-	
-	/**
-	 * Draws the x-axis and sets up the graph's title.
-	 * Also draws graduations for the x-axis
-	 * 
-	 * @param gc
-	 * @param width
-	 */
-	protected void drawAxis(GC gc, int width) {
-		gc.setLineWidth(2);
-		gc.drawLine(getXOffset(), getYOffset(), width, getYOffset());
-		int xSeg = getXOffset();
-		int increment = width/BUFFER_SIZE;
-		while (xSeg < width) {
-			gc.drawLine(xSeg, getYOffset(), xSeg, getYOffset() - getHeight());
-			xSeg += increment;
-		}
-		gc.setForeground(new Color(Display.getCurrent(), 10, 10, 10));
-		gc.drawText(getTitle(), getXOffset(), getYOffset() + 5, true);
-//		gc.drawText(this.getCoordinates().getAxis().getTopLabel(), this.getXOffset(), this.getYOffset() - this.getHeight(), true);
-	}
-	
-	protected void drawFillPolygons(GC gc, Composite graphCanvas, Iterator<DataPoint> nextPointBuffer) {
-		DataPoint pp = this.getStartPoint();
-		int xSeg = this.getXOffset();
-		int increment = (graphCanvas.getSize().x - this.getXOffset())/GraphModel.BUFFER_SIZE;
-		
-		gc.setLineWidth(0);
-		while (nextPointBuffer.hasNext()) {
-			gc.setAlpha(170);
-			DataPoint nextPoint = new DataPoint(xSeg, this.transform(nextPointBuffer.next()).getY(), 0);
-			//Use old point, new point, and the corresponding intersections with the x-axis to fill
-			gc.fillPolygon(new int[] {pp.getX(), pp.getY(), nextPoint.getX(), nextPoint.getY(), nextPoint.getX(), getStartPoint().getY(), pp.getX(), getStartPoint().getY()});
-			xSeg += increment;
-			pp = nextPoint;
-    	}
-	}
-	
-	protected void drawLines(GC gc, Composite graphCanvas, Iterator<DataPoint> nextPointBuffer) {
-		DataPoint pp = this.getStartPoint();
-		int xSeg = this.getXOffset();
-		int increment = (graphCanvas.getSize().x - this.getXOffset())/GraphModel.BUFFER_SIZE;
-		
-		while (nextPointBuffer.hasNext()) {
-			DataPoint nextPoint = new DataPoint(xSeg, this.transform(nextPointBuffer.next()).getY(), 0);
-			xSeg += increment;
-			drawLine(gc, pp, nextPoint);
-			pp = nextPoint;
-    	}
-	}
-
-}
+package org.eclipse.linuxtools.internal.threadprofiler.graphs;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.eclipse.linuxtools.internal.threadprofiler.CircularPointBuffer;
+import org.eclipse.linuxtools.internal.threadprofiler.CoordinateSystem;
+import org.eclipse.linuxtools.internal.threadprofiler.DataPoint;
+import org.eclipse.linuxtools.internal.threadprofiler.GraphAxis;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+public abstract class GraphModel {
+	
+	//Constant Y scale
+	public static final int CONSTANT_Y = 0;
+	//Change Y scale as the maximum y point increases
+	public static final int FLEXIBLE_Y = 1;
+	/** Maximum buffer size. This affects the number of data points*/
+	public static final int BUFFER_SIZE = 100;
+	//Default height
+	public static final int DEFAULT_HEIGHT = 100;
+	
+	/** Number of spaces between graduations on the axis */
+	private static final int GRADUATION_SEPARATION = 5;
+	
+	private final CoordinateSystem coordinates;
+	private final DataPoint startPoint;
+	private final int graphType;
+	private final String title;
+	private final String units;
+	private boolean changed;
+	protected final ArrayList<CircularPointBuffer> data;
+	
+	private int height;
+	
+	private int maxY;
+	//Height in pixels
+	
+	public GraphModel(String name, int x, int y, int type, String units) {
+		graphType = type;
+		changed = false;
+		data = new ArrayList<CircularPointBuffer>();
+		title = name;
+		this.units = units;
+		height = DEFAULT_HEIGHT;
+		maxY = 100;
+		coordinates = new CoordinateSystem(x, y);
+		coordinates.setYScale(0.2);
+		coordinates.getAxis().setTopLabel(DEFAULT_HEIGHT + units);
+		
+		startPoint = new DataPoint(coordinates.getXOffset(), coordinates.getYOffset(), 1);
+	}
+	
+	public void setMaxY(int max) {
+		maxY = max;
+	}
+	
+	public int getXOffset() {
+		return (int) coordinates.getAxisToPixel().entries[0][2];
+	}
+	
+	public int getYOffset() {
+		return (int) coordinates.getAxisToPixel().entries[1][2];
+	}
+
+
+	/**
+	 * 
+	 * @return
+	 * 			  First available point buffer if any is available, else null
+	 */
+	public Iterator<DataPoint> getPointBuffer() {
+		if (data.size() > 1)
+			return getPointBuffer(0);
+		return null;
+	}
+	
+	public Iterator<DataPoint> getPointBuffer(int index) {
+		return data.get(index).getIterator();
+	}
+
+	public GraphAxis getAxis() {
+		return coordinates.getAxis();
+	}
+	
+	public DataPoint getStartPoint() {
+		return startPoint;
+	}
+
+	public void add(DataPoint point, int subIndex) {
+		if (subIndex >= data.size()) {
+			data.add(new CircularPointBuffer(BUFFER_SIZE));
+		}
+		if (graphType == FLEXIBLE_Y) {
+			if (point.getY() > maxY ) {
+				maxY = point.getY();
+				coordinates.getAxis().setTopLabel(maxY + " " + units);
+				if ( point.getY() > height) {
+					double newScale = (double) height/maxY;
+					coordinates.setYScale(newScale);
+				}
+			}
+		}
+		data.get(subIndex).add(point);
+		setChanged(true);
+	}
+	
+	public DataPoint transform(DataPoint toTransform) {
+		return coordinates.dataToPixel(toTransform);
+	}
+
+	public boolean isChanged() {
+		return changed;
+	}
+	
+	public void setChanged(boolean val) {
+		changed = val;
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public int getHeight() {
+		return height;
+	}
+	
+	public void setHeight(int value) {
+		if (height == value)
+			return;
+		height = value;
+		double newScale = (double) height/maxY;
+		coordinates.setYScale(newScale);
+	}
+
+
+	public void setYAxisCoordinate(int value) {
+		coordinates.setYAxisCoordinate(value);
+		startPoint.setY(value);
+	}
+	
+	public void setXAxisCoordinate(int value) {
+		coordinates.setXAxisCoordinate(value);
+		startPoint.setX(value);
+	}
+
+
+	public CoordinateSystem getCoordinates() {
+		return coordinates;
+	}
+
+	/**
+	 * The main draw function -- implement this method to change
+	 * the way things are graphed
+	 * 
+	 * @param gc
+	 * @param graphCanvas
+	 */
+	public abstract void drawOn(GC gc, Composite graphCanvas);
+
+	
+	protected void drawLine(GC gc, DataPoint p1, DataPoint p2) {
+		gc.drawLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+	}
+	
+	/**
+	 * 
+	 * @return
+	 * 			  Number of data buffers in this model
+	 */
+	public int getBufferCount() {
+		return data.size();
+	}
+	
+	/**
+	 * Draws the x-axis and sets up the graph's title.
+	 * Also draws graduations for the x-axis
+	 * 
+	 * @param gc
+	 * @param width
+	 */
+	protected void drawAxis(GC gc, int width) {
+		gc.setLineWidth(2);
+		gc.drawLine(getXOffset(), getYOffset(), width, getYOffset());
+		int xSeg = getXOffset();
+		int increment = width/BUFFER_SIZE;
+		while (xSeg < width) {
+			gc.drawLine(xSeg, getYOffset(), xSeg, getYOffset() - getHeight());
+			xSeg += GRADUATION_SEPARATION * increment;
+		}
+		gc.setForeground(new Color(Display.getCurrent(), 10, 10, 10));
+		gc.drawText(getTitle(), getXOffset(), getYOffset() + 5, true);
+//		gc.drawText(this.getCoordinates().getAxis().getTopLabel(), this.getXOffset(), this.getYOffset() - this.getHeight(), true);
+	}
+	
+	protected void drawFillPolygons(GC gc, Composite graphCanvas, Iterator<DataPoint> nextPointBuffer) {
+		DataPoint pp = this.getStartPoint();
+		int xSeg = this.getXOffset();
+		int increment = (graphCanvas.getSize().x - this.getXOffset())/GraphModel.BUFFER_SIZE;
+		
+		gc.setLineWidth(0);
+		while (nextPointBuffer.hasNext()) {
+			gc.setAlpha(170);
+			DataPoint nextPoint = new DataPoint(xSeg, this.transform(nextPointBuffer.next()).getY(), 0);
+			//Use old point, new point, and the corresponding intersections with the x-axis to fill
+			gc.fillPolygon(new int[] {pp.getX(), pp.getY(), nextPoint.getX(), nextPoint.getY(), nextPoint.getX(), getStartPoint().getY(), pp.getX(), getStartPoint().getY()});
+			xSeg += increment;
+			pp = nextPoint;
+    	}
+	}
+	
+	protected void drawLines(GC gc, Composite graphCanvas, Iterator<DataPoint> nextPointBuffer) {
+		DataPoint pp = this.getStartPoint();
+		int xSeg = this.getXOffset();
+		int increment = (graphCanvas.getSize().x - this.getXOffset())/GraphModel.BUFFER_SIZE;
+		
+		while (nextPointBuffer.hasNext()) {
+			DataPoint nextPoint = new DataPoint(xSeg, this.transform(nextPointBuffer.next()).getY(), 0);
+			xSeg += increment;
+			drawLine(gc, pp, nextPoint);
+			pp = nextPoint;
+    	}
+	}
+
+}
diff --git a/src/org/eclipse/linuxtools/threadprofiler/graphs/MultiGraph.java b/src/org/eclipse/linuxtools/threadprofiler/graphs/MultiGraph.java
index ee3565e..5d958b2 100644
--- a/src/org/eclipse/linuxtools/threadprofiler/graphs/MultiGraph.java
+++ b/src/org/eclipse/linuxtools/threadprofiler/graphs/MultiGraph.java
@@ -80,6 +80,7 @@ public class MultiGraph extends GraphModel {
 					gc.setBackground(oldBg);
 				}
 				
+				gc.setLineWidth(0);
 				gc.drawText(getPointBuffer(i).toString(), xPos, yPos);
 				prev = getPointBuffer(i).toString();
 				xPos = xPos + separation(prev);
