diff --git a/src/main/java/kieker/gui/model/DataSource.java b/src/main/java/kieker/gui/model/DataSource.java
index 514215aaf2d57ea72629fbd3233069640a54abbe..f752127dccfef9219c9e15102bbc5222e43b4b26 100644
--- a/src/main/java/kieker/gui/model/DataSource.java
+++ b/src/main/java/kieker/gui/model/DataSource.java
@@ -19,7 +19,11 @@ package kieker.gui.model;
 import java.io.File;
 import java.util.Collections;
 import java.util.List;
+import java.util.Observable;
 
+import kieker.gui.model.domain.AggregatedExecutionEntry;
+import kieker.gui.model.domain.ExecutionEntry;
+import kieker.gui.model.domain.RecordEntry;
 import kieker.gui.model.importer.ImportAnalysisConfiguration;
 import teetime.framework.Analysis;
 
@@ -28,12 +32,19 @@ import teetime.framework.Analysis;
  *
  * @author Nils Christian Ehmke
  */
-public final class DataSource {
+public final class DataSource extends Observable {
 
+	private static final DataSource INSTANCE = new DataSource();
 	private List<RecordEntry> records = Collections.emptyList();
 	private List<ExecutionEntry> traces = Collections.emptyList();
 	private List<AggregatedExecutionEntry> aggregatedTraces;
 
+	private DataSource() {}
+
+	public static DataSource getInstance() {
+		return DataSource.INSTANCE;
+	}
+
 	public void loadMonitoringLogFromFS(final String directory) {
 		// Load and analyze the monitoring logs from the given directory
 		final File importDirectory = new File(directory);
@@ -46,6 +57,9 @@ public final class DataSource {
 		this.records = analysisConfiguration.getRecordsList();
 		this.traces = analysisConfiguration.getTracesList();
 		this.aggregatedTraces = analysisConfiguration.getAggregatedTraces();
+
+		this.setChanged();
+		this.notifyObservers();
 	}
 
 	public List<RecordEntry> getRecords() {
diff --git a/src/main/java/kieker/gui/model/AggregatedExecutionEntry.java b/src/main/java/kieker/gui/model/domain/AggregatedExecutionEntry.java
similarity index 98%
rename from src/main/java/kieker/gui/model/AggregatedExecutionEntry.java
rename to src/main/java/kieker/gui/model/domain/AggregatedExecutionEntry.java
index 9fcf9db20322f3c2d943e126e0c0f7f39c591c60..8c2534ced8ab28621ea8389e22976ad6bbfc81e2 100644
--- a/src/main/java/kieker/gui/model/AggregatedExecutionEntry.java
+++ b/src/main/java/kieker/gui/model/domain/AggregatedExecutionEntry.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  ***************************************************************************/
 
-package kieker.gui.model;
+package kieker.gui.model.domain;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/src/main/java/kieker/gui/model/ExecutionEntry.java b/src/main/java/kieker/gui/model/domain/ExecutionEntry.java
similarity index 99%
rename from src/main/java/kieker/gui/model/ExecutionEntry.java
rename to src/main/java/kieker/gui/model/domain/ExecutionEntry.java
index 598e7d6844b6891d0d21428f47365869fb2c4a86..e3fb7e1e4a79a0fe09c17ce2ab9262aea4315ad2 100644
--- a/src/main/java/kieker/gui/model/ExecutionEntry.java
+++ b/src/main/java/kieker/gui/model/domain/ExecutionEntry.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  ***************************************************************************/
 
-package kieker.gui.model;
+package kieker.gui.model.domain;
 
 import java.util.ArrayList;
 import java.util.Iterator;
diff --git a/src/main/java/kieker/gui/model/RecordEntry.java b/src/main/java/kieker/gui/model/domain/RecordEntry.java
similarity index 97%
rename from src/main/java/kieker/gui/model/RecordEntry.java
rename to src/main/java/kieker/gui/model/domain/RecordEntry.java
index a4914d32a5e222916430a4e57da17bcee93eb628..987f8997a942af2965a776123f4a6bcbf62b3481 100644
--- a/src/main/java/kieker/gui/model/RecordEntry.java
+++ b/src/main/java/kieker/gui/model/domain/RecordEntry.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  ***************************************************************************/
 
-package kieker.gui.model;
+package kieker.gui.model.domain;
 
 /**
  * A simplified representation of a monitoring record.
diff --git a/src/main/java/kieker/gui/model/importer/ImportAnalysisConfiguration.java b/src/main/java/kieker/gui/model/importer/ImportAnalysisConfiguration.java
index cf73b0e7d9c3bcff36bba77ec558837cadd6cf2a..ec13cd44650bf6de86625f58f4e07fcf0a09b494 100644
--- a/src/main/java/kieker/gui/model/importer/ImportAnalysisConfiguration.java
+++ b/src/main/java/kieker/gui/model/importer/ImportAnalysisConfiguration.java
@@ -22,9 +22,9 @@ import java.util.Vector;
 
 import kieker.common.record.IMonitoringRecord;
 import kieker.common.record.flow.IFlowRecord;
-import kieker.gui.model.AggregatedExecutionEntry;
-import kieker.gui.model.ExecutionEntry;
-import kieker.gui.model.RecordEntry;
+import kieker.gui.model.domain.AggregatedExecutionEntry;
+import kieker.gui.model.domain.ExecutionEntry;
+import kieker.gui.model.domain.RecordEntry;
 import kieker.gui.model.importer.filter.Cloner;
 import kieker.gui.model.importer.filter.RecordSimplificator;
 import kieker.gui.model.importer.filter.TraceAggregator;
diff --git a/src/main/java/kieker/gui/model/importer/filter/RecordSimplificator.java b/src/main/java/kieker/gui/model/importer/filter/RecordSimplificator.java
index 28ad9c64c9f347253c2510cd0ec14d2a771f912e..0ee3602c3c0e3eb53aca9b7c7827437b41c0202e 100644
--- a/src/main/java/kieker/gui/model/importer/filter/RecordSimplificator.java
+++ b/src/main/java/kieker/gui/model/importer/filter/RecordSimplificator.java
@@ -17,7 +17,7 @@
 package kieker.gui.model.importer.filter;
 
 import kieker.common.record.IMonitoringRecord;
-import kieker.gui.model.RecordEntry;
+import kieker.gui.model.domain.RecordEntry;
 import teetime.framework.AbstractConsumerStage;
 import teetime.framework.OutputPort;
 
diff --git a/src/main/java/kieker/gui/model/importer/filter/TraceAggregator.java b/src/main/java/kieker/gui/model/importer/filter/TraceAggregator.java
index 97dab84b3d4b5424bd9c0cd74ec72fc52fac424b..609422c6f0d21cfc5954642e9c6ddc3182db1533 100644
--- a/src/main/java/kieker/gui/model/importer/filter/TraceAggregator.java
+++ b/src/main/java/kieker/gui/model/importer/filter/TraceAggregator.java
@@ -19,8 +19,8 @@ package kieker.gui.model.importer.filter;
 import java.util.HashMap;
 import java.util.Map;
 
-import kieker.gui.model.AggregatedExecutionEntry;
-import kieker.gui.model.ExecutionEntry;
+import kieker.gui.model.domain.AggregatedExecutionEntry;
+import kieker.gui.model.domain.ExecutionEntry;
 import teetime.framework.AbstractConsumerStage;
 import teetime.framework.OutputPort;
 
diff --git a/src/main/java/kieker/gui/model/importer/filter/TraceReconstructor.java b/src/main/java/kieker/gui/model/importer/filter/TraceReconstructor.java
index 42454d887c2429318acd2979116a735591927bbe..c7058aafe344c14ffcf4124f3d6661b067a31ce4 100644
--- a/src/main/java/kieker/gui/model/importer/filter/TraceReconstructor.java
+++ b/src/main/java/kieker/gui/model/importer/filter/TraceReconstructor.java
@@ -27,7 +27,7 @@ import kieker.common.record.flow.trace.operation.AbstractOperationEvent;
 import kieker.common.record.flow.trace.operation.AfterOperationEvent;
 import kieker.common.record.flow.trace.operation.AfterOperationFailedEvent;
 import kieker.common.record.flow.trace.operation.BeforeOperationEvent;
-import kieker.gui.model.ExecutionEntry;
+import kieker.gui.model.domain.ExecutionEntry;
 import teetime.framework.AbstractConsumerStage;
 import teetime.framework.OutputPort;
 
diff --git a/src/main/java/kieker/gui/view/ClearTreeObserver.java b/src/main/java/kieker/gui/view/ClearTreeObserver.java
deleted file mode 100644
index f446fd55a7636256b33a564dc053f9df0b694ce7..0000000000000000000000000000000000000000
--- a/src/main/java/kieker/gui/view/ClearTreeObserver.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package kieker.gui.view;
-
-import java.util.Observable;
-import java.util.Observer;
-
-import org.eclipse.swt.widgets.Tree;
-
-/**
- * An observer clearing an instance of {@link Tree}.
- *
- * @author Nils Christian Ehmke
- */
-public final class ClearTreeObserver implements Observer {
-
-	private final Tree tree;
-
-	public ClearTreeObserver(final Tree tree) {
-		this.tree = tree;
-	}
-
-	@Override
-	public void update(final Observable observable, final Object obj) {
-		this.tree.clearAll(true);
-	}
-
-}
diff --git a/src/main/java/kieker/gui/view/ExecutionTraceTreeSelectionListener.java b/src/main/java/kieker/gui/view/ExecutionTraceTreeSelectionListener.java
deleted file mode 100644
index 170ec8d7d5280319b7f425c3ae9f0363e3e17c59..0000000000000000000000000000000000000000
--- a/src/main/java/kieker/gui/view/ExecutionTraceTreeSelectionListener.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package kieker.gui.view;
-
-import kieker.gui.model.ExecutionEntry;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.widgets.Display;
-
-class ExecutionTraceTreeSelectionListener implements SelectionListener {
-
-	/**
-	 * 
-	 */
-	private final MainWindow mainWindow;
-
-	/**
-	 * @param mainWindow
-	 */
-	ExecutionTraceTreeSelectionListener(MainWindow mainWindow) {
-		this.mainWindow = mainWindow;
-	}
-
-	@Override
-	public void widgetSelected(final SelectionEvent e) {
-		final Object data = e.item.getData();
-		if (data instanceof ExecutionEntry) {
-			this.mainWindow.lblNa_1.setText(Long.toString(((ExecutionEntry) data).getTraceID()));
-			this.mainWindow.lblNa_3.setText(Long.toString(((ExecutionEntry) data).getDuration()));
-
-			this.mainWindow.lblNa_4.setText(((ExecutionEntry) data).getContainer());
-			this.mainWindow.lblNa_5.setText(((ExecutionEntry) data).getComponent());
-			this.mainWindow.lblNa_6.setText(((ExecutionEntry) data).getOperation());
-			this.mainWindow.lblNa_7.setText(Integer.toString(((ExecutionEntry) data).getStackDepth()));
-
-			if (((ExecutionEntry) data).isFailed()) {
-				this.mainWindow.lblNa_2.setText("Yes (" + ((ExecutionEntry) data).getFailedCause() + ")");
-				this.mainWindow.lblNa_2.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
-				this.mainWindow.lblFailed.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
-			} else {
-				this.mainWindow.lblNa_2.setText("No");
-				this.mainWindow.lblNa_2.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
-				this.mainWindow.lblFailed.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
-			}
-
-			this.mainWindow.lblNa_1.pack();
-			this.mainWindow.lblNa_2.pack();
-			this.mainWindow.lblNa_3.pack();
-			this.mainWindow.lblNa_4.pack();
-			this.mainWindow.lblNa_5.pack();
-			this.mainWindow.lblNa_6.pack();
-			this.mainWindow.lblNa_7.pack();
-		}
-	}
-
-	@Override
-	public void widgetDefaultSelected(final SelectionEvent e) {
-
-	}
-
-}
\ No newline at end of file
diff --git a/src/main/java/kieker/gui/view/ExplorerTreeSelectionAdapter.java b/src/main/java/kieker/gui/view/ExplorerTreeSelectionAdapter.java
deleted file mode 100644
index 0f2a8e123802994c72ac0ade4ef9e5786cf8a09c..0000000000000000000000000000000000000000
--- a/src/main/java/kieker/gui/view/ExplorerTreeSelectionAdapter.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package kieker.gui.view;
-
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.widgets.Widget;
-
-public final class ExplorerTreeSelectionAdapter extends SelectionAdapter {
-
-	private final MainWindow mainWindow;
-
-	public ExplorerTreeSelectionAdapter(final MainWindow mainWindow) {
-		this.mainWindow = mainWindow;
-	}
-
-	@Override
-	public void widgetSelected(final SelectionEvent e) {
-		final Widget selectedWidget = e.item;
-
-		if (this.mainWindow.recordsTreeItem == selectedWidget) {
-			this.mainWindow.showRecords();
-		} else if (this.mainWindow.executionTracesTreeItem == selectedWidget) {
-			this.mainWindow.showExecutionTraces();
-		} else if (this.mainWindow.trtmAggregatedExecutionTraces == selectedWidget) {
-			this.mainWindow.showAggregatedExecutionTraces();
-		} else {
-			this.mainWindow.setVisibleMainComponent(null);
-			this.mainWindow.lblNa.setText("");
-		}
-	}
-
-}
diff --git a/src/main/java/kieker/gui/view/MainWindow.java b/src/main/java/kieker/gui/view/MainWindow.java
index 987baa90119c14394ecd192f9c97375a02b2d6c6..c21dd4f7ef8f039e4ef5d575849dc54ae0889bf9 100644
--- a/src/main/java/kieker/gui/view/MainWindow.java
+++ b/src/main/java/kieker/gui/view/MainWindow.java
@@ -17,12 +17,20 @@
 package kieker.gui.view;
 
 import java.util.List;
+import java.util.Observable;
+import java.util.Observer;
 
-import kieker.gui.model.AggregatedExecutionEntry;
 import kieker.gui.model.DataSource;
-import kieker.gui.model.ExecutionEntry;
 import kieker.gui.model.Properties;
-import kieker.gui.model.RecordEntry;
+import kieker.gui.model.domain.AggregatedExecutionEntry;
+import kieker.gui.model.domain.ExecutionEntry;
+import kieker.gui.model.domain.RecordEntry;
+import kieker.gui.view.util.AggregatedExecutionTracesTreeSetDataListener;
+import kieker.gui.view.util.ExecutionTracesTreeSetDataListener;
+import kieker.gui.view.util.RecordEntryTimestampComparator;
+import kieker.gui.view.util.RecordEntryTypeComparator;
+import kieker.gui.view.util.RecordsTableSetDataListener;
+import kieker.gui.view.util.TableColumnSortListener;
 
 import org.eclipse.jface.viewers.TableViewer;
 import org.eclipse.jface.viewers.TreeViewer;
@@ -46,6 +54,7 @@ import org.eclipse.swt.widgets.TableColumn;
 import org.eclipse.swt.widgets.Tree;
 import org.eclipse.swt.widgets.TreeColumn;
 import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swt.widgets.Widget;
 import org.eclipse.wb.swt.SWTResourceManager;
 
 /**
@@ -53,7 +62,7 @@ import org.eclipse.wb.swt.SWTResourceManager;
  *
  * @author Nils Christian Ehmke
  */
-public class MainWindow {
+public final class MainWindow {
 
 	protected Shell shell;
 	private Composite mainComposite;
@@ -75,7 +84,7 @@ public class MainWindow {
 	private Menu helpMenu;
 	private MenuItem aboutMenuItem;
 	private Tree explorerTree;
-	private Tree executionTracesTree;
+	private Tree tracesTree;
 	private TreeColumn tracesTreeContainerColumn;
 	private TreeColumn treeColumn_8;
 	private TreeColumn treeColumn_10;
@@ -89,7 +98,6 @@ public class MainWindow {
 	private MenuItem mntmLongOperationParameters;
 	private TableColumn recordsTableTypeColumn;
 	private SashForm explorerForm;
-	final DataSource model = new DataSource();
 	private TreeColumn trclmnPercent;
 	Label lblNa;
 	private SashForm executionTracesForm;
@@ -109,7 +117,7 @@ public class MainWindow {
 	private Label lblStackDepth;
 	Label lblNa_7;
 	private SashForm sashForm;
-	private Tree tree_1;
+	private Tree aggregatedTracesTree;
 	private TreeColumn treeColumn;
 	private TreeColumn treeColumn_1;
 	private TreeColumn treeColumn_2;
@@ -135,7 +143,8 @@ public class MainWindow {
 	public void open() {
 		final Display display = Display.getDefault();
 		this.createContents();
-		this.model.loadMonitoringLogFromFS("testdata");
+		this.addLogic();
+		DataSource.getInstance().loadMonitoringLogFromFS("testdata");
 		this.shell.open();
 		this.shell.layout();
 		while (!this.shell.isDisposed()) {
@@ -175,7 +184,6 @@ public class MainWindow {
 		this.executionTracesTreeItem.setExpanded(true);
 		this.explorerTreeItem.setExpanded(true);
 
-		this.explorerTree.addSelectionListener(new ExplorerTreeSelectionAdapter(this));
 		this.explorerForm.setWeights(new int[] { 3 });
 
 		this.mainComposite = new Composite(this.outerForm, SWT.NONE);
@@ -185,52 +193,45 @@ public class MainWindow {
 		this.recordsTableViewer = new TableViewer(this.mainComposite, SWT.BORDER | SWT.FULL_SELECTION | SWT.VIRTUAL);
 		this.recordsTable = this.recordsTableViewer.getTable();
 		this.recordsTable.setHeaderVisible(true);
-		this.recordsTable.addListener(SWT.SetData, new RecordsTableSetDataListener());
 
 		this.recordsTableTimestampColumn = new TableColumn(this.recordsTable, SWT.NONE);
 		this.recordsTableTimestampColumn.setWidth(100);
 		this.recordsTableTimestampColumn.setText("Timestamp");
-		this.recordsTableTimestampColumn.addListener(SWT.Selection, new RecordsTableTimestampSortListener());
 
 		this.recordsTableTypeColumn = new TableColumn(this.recordsTable, SWT.NONE);
 		this.recordsTableTypeColumn.setWidth(100);
 		this.recordsTableTypeColumn.setText("Type");
-		this.recordsTableTypeColumn.addListener(SWT.Selection, new RecordsTableTypeSortListener());
 
 		this.recordsTableRecordColumn = new TableColumn(this.recordsTable, SWT.NONE);
 		this.recordsTableRecordColumn.setWidth(100);
 		this.recordsTableRecordColumn.setText("Record");
-		this.recordsTableRecordColumn.addListener(SWT.Selection, new RecordsTableTimestampSortListener());
 
 		this.executionTracesForm = new SashForm(this.mainComposite, SWT.VERTICAL);
 
-		this.executionTracesTree = new Tree(this.executionTracesForm, SWT.BORDER | SWT.FULL_SELECTION | SWT.VIRTUAL);
-		this.executionTracesTree.setHeaderVisible(true);
-		this.executionTracesTree.addListener(SWT.SetData, new ExecutionTracesTreeSetDataListener());
-		this.executionTracesTree.addSelectionListener(new ExecutionTraceTreeSelectionListener(this));
-		Properties.getInstance().addObserver(new ClearTreeObserver(this.executionTracesTree));
+		this.tracesTree = new Tree(this.executionTracesForm, SWT.BORDER | SWT.FULL_SELECTION | SWT.VIRTUAL);
+		this.tracesTree.setHeaderVisible(true);
 
-		this.tracesTreeContainerColumn = new TreeColumn(this.executionTracesTree, SWT.NONE);
+		this.tracesTreeContainerColumn = new TreeColumn(this.tracesTree, SWT.NONE);
 		this.tracesTreeContainerColumn.setWidth(100);
 		this.tracesTreeContainerColumn.setText("Execution Container");
 
-		this.treeColumn_8 = new TreeColumn(this.executionTracesTree, SWT.NONE);
+		this.treeColumn_8 = new TreeColumn(this.tracesTree, SWT.NONE);
 		this.treeColumn_8.setWidth(100);
 		this.treeColumn_8.setText("Component");
 
-		this.treeColumn_10 = new TreeColumn(this.executionTracesTree, SWT.NONE);
+		this.treeColumn_10 = new TreeColumn(this.tracesTree, SWT.NONE);
 		this.treeColumn_10.setWidth(100);
 		this.treeColumn_10.setText("Operation");
 
-		this.treeColumn_11 = new TreeColumn(this.executionTracesTree, SWT.NONE);
+		this.treeColumn_11 = new TreeColumn(this.tracesTree, SWT.NONE);
 		this.treeColumn_11.setWidth(100);
 		this.treeColumn_11.setText("Duration");
 
-		this.trclmnPercent = new TreeColumn(this.executionTracesTree, SWT.NONE);
+		this.trclmnPercent = new TreeColumn(this.tracesTree, SWT.NONE);
 		this.trclmnPercent.setWidth(100);
 		this.trclmnPercent.setText("Percent");
 
-		this.treeColumn_16 = new TreeColumn(this.executionTracesTree, SWT.NONE);
+		this.treeColumn_16 = new TreeColumn(this.tracesTree, SWT.NONE);
 		this.treeColumn_16.setWidth(100);
 		this.treeColumn_16.setText("Trace ID");
 
@@ -298,24 +299,22 @@ public class MainWindow {
 
 		this.sashForm = new SashForm(this.mainComposite, SWT.VERTICAL);
 
-		this.tree_1 = new Tree(this.sashForm, SWT.BORDER | SWT.FULL_SELECTION | SWT.VIRTUAL);
-		this.tree_1.setHeaderVisible(true);
-		this.tree_1.addListener(SWT.SetData, new AggregatedExecutionTracesTreeSetDataListener());
-		Properties.getInstance().addObserver(new ClearTreeObserver(this.tree_1));
+		this.aggregatedTracesTree = new Tree(this.sashForm, SWT.BORDER | SWT.FULL_SELECTION | SWT.VIRTUAL);
+		this.aggregatedTracesTree.setHeaderVisible(true);
 
-		this.treeColumn = new TreeColumn(this.tree_1, SWT.NONE);
+		this.treeColumn = new TreeColumn(this.aggregatedTracesTree, SWT.NONE);
 		this.treeColumn.setWidth(100);
 		this.treeColumn.setText("Execution Container");
 
-		this.treeColumn_1 = new TreeColumn(this.tree_1, SWT.NONE);
+		this.treeColumn_1 = new TreeColumn(this.aggregatedTracesTree, SWT.NONE);
 		this.treeColumn_1.setWidth(100);
 		this.treeColumn_1.setText("Component");
 
-		this.treeColumn_2 = new TreeColumn(this.tree_1, SWT.NONE);
+		this.treeColumn_2 = new TreeColumn(this.aggregatedTracesTree, SWT.NONE);
 		this.treeColumn_2.setWidth(100);
 		this.treeColumn_2.setText("Operation");
 
-		this.trclmnCalls = new TreeColumn(this.tree_1, SWT.NONE);
+		this.trclmnCalls = new TreeColumn(this.aggregatedTracesTree, SWT.NONE);
 		this.trclmnCalls.setWidth(100);
 		this.trclmnCalls.setText("# Calls");
 
@@ -377,12 +376,6 @@ public class MainWindow {
 		this.fileMenuItem.setMenu(this.fileMenu);
 
 		this.openMonitoringLogMenuItem = new MenuItem(this.fileMenu, SWT.NONE);
-		this.openMonitoringLogMenuItem.addSelectionListener(new SelectionAdapter() {
-			@Override
-			public void widgetSelected(final SelectionEvent e) {
-				MainWindow.this.showOpenMonitoringLogDialog();
-			}
-		});
 		this.openMonitoringLogMenuItem.setText("Open Monitoring Log");
 
 		new MenuItem(this.fileMenu, SWT.SEPARATOR);
@@ -398,137 +391,226 @@ public class MainWindow {
 
 		this.mntmShortOperationParameters = new MenuItem(this.menu, SWT.RADIO);
 		this.mntmShortOperationParameters.setSelection(true);
+		this.mntmShortOperationParameters.setText("Short Operation Parameters");
+
+		this.mntmLongOperationParameters = new MenuItem(this.menu, SWT.RADIO);
+		this.mntmLongOperationParameters.setText("Long Operation Parameters");
+
+		new MenuItem(this.menu, SWT.SEPARATOR);
+
+		this.mntmShortComponentNames = new MenuItem(this.menu, SWT.RADIO);
+		this.mntmShortComponentNames.setText("Short Component Names");
+
+		this.mntmLongComponentNames = new MenuItem(this.menu, SWT.RADIO);
+		this.mntmLongComponentNames.setSelection(true);
+		this.mntmLongComponentNames.setText("Long Component Names");
+
+		this.helpMenuItem = new MenuItem(this.menuBar, SWT.CASCADE);
+		this.helpMenuItem.setText("Help");
+
+		this.helpMenu = new Menu(this.helpMenuItem);
+		this.helpMenuItem.setMenu(this.helpMenu);
+
+		this.aboutMenuItem = new MenuItem(this.helpMenu, SWT.NONE);
+		this.aboutMenuItem.setText("About...");
+
+		this.lblNa = new Label(this.shell, SWT.NONE);
+		this.lblNa.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
+	}
+
+	private void addLogic() {
+		DataSource.getInstance().addObserver(new Observer() {
+
+			@Override
+			public void update(final Observable o, final Object arg) {
+				MainWindow.this.reloadFromModel();
+			}
+
+		});
+
+		this.openMonitoringLogMenuItem.addSelectionListener(new SelectionAdapter() {
+
+			@Override
+			public void widgetSelected(final SelectionEvent e) {
+				MainWindow.this.showOpenMonitoringLogDialog();
+			}
+
+		});
+
 		this.mntmShortOperationParameters.addSelectionListener(new SelectionAdapter() {
+
 			@Override
 			public void widgetSelected(final SelectionEvent e) {
 				Properties.getInstance().setShortOperationParameters(true);
 			}
+
 		});
-		this.mntmShortOperationParameters.setText("Short Operation Parameters");
 
-		this.mntmLongOperationParameters = new MenuItem(this.menu, SWT.RADIO);
 		this.mntmLongOperationParameters.addSelectionListener(new SelectionAdapter() {
+
 			@Override
 			public void widgetSelected(final SelectionEvent e) {
 				Properties.getInstance().setShortOperationParameters(false);
 			}
-		});
-		this.mntmLongOperationParameters.setText("Long Operation Parameters");
 
-		new MenuItem(this.menu, SWT.SEPARATOR);
+		});
 
-		this.mntmShortComponentNames = new MenuItem(this.menu, SWT.RADIO);
 		this.mntmShortComponentNames.addSelectionListener(new SelectionAdapter() {
+
 			@Override
 			public void widgetSelected(final SelectionEvent e) {
 				Properties.getInstance().setShortComponentNames(true);
 			}
+
 		});
-		this.mntmShortComponentNames.setText("Short Component Names");
 
-		this.mntmLongComponentNames = new MenuItem(this.menu, SWT.RADIO);
 		this.mntmLongComponentNames.addSelectionListener(new SelectionAdapter() {
+
 			@Override
 			public void widgetSelected(final SelectionEvent e) {
 				Properties.getInstance().setShortComponentNames(false);
 			}
+
 		});
-		this.mntmLongComponentNames.setSelection(true);
-		this.mntmLongComponentNames.setText("Long Component Names");
 
-		this.helpMenuItem = new MenuItem(this.menuBar, SWT.CASCADE);
-		this.helpMenuItem.setText("Help");
+		Properties.getInstance().addObserver(new Observer() {
 
-		this.helpMenu = new Menu(this.helpMenuItem);
-		this.helpMenuItem.setMenu(this.helpMenu);
+			@Override
+			public void update(final Observable o, final Object arg) {
+				MainWindow.this.aggregatedTracesTree.clearAll(true);
+				MainWindow.this.tracesTree.clearAll(true);
+			}
 
-		this.aboutMenuItem = new MenuItem(this.helpMenu, SWT.NONE);
-		this.aboutMenuItem.setText("About...");
+		});
 
-		this.lblNa = new Label(this.shell, SWT.NONE);
-		this.lblNa.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
-	}
+		this.recordsTable.addListener(SWT.SetData, new RecordsTableSetDataListener());
+		this.aggregatedTracesTree.addListener(SWT.SetData, new AggregatedExecutionTracesTreeSetDataListener());
+		this.tracesTree.addListener(SWT.SetData, new ExecutionTracesTreeSetDataListener());
 
-	protected void showSystemModel() {
-		// Show the tree
+		this.recordsTableTimestampColumn.addListener(SWT.Selection, new TableColumnSortListener<RecordEntry>(new RecordEntryTimestampComparator()));
+		this.recordsTableTypeColumn.addListener(SWT.Selection, new TableColumnSortListener<RecordEntry>(new RecordEntryTypeComparator()));
+		this.recordsTableRecordColumn.addListener(SWT.Selection, new TableColumnSortListener<RecordEntry>(new RecordEntryTimestampComparator()));
+
+		this.explorerTree.addSelectionListener(new SelectionAdapter() {
+
+			@Override
+			public void widgetSelected(final SelectionEvent e) {
+				final Widget selectedWidget = e.item;
+				MainWindow.this.handleExplorerSelection(selectedWidget);
+			}
+		});
+
+		this.tracesTree.addSelectionListener(new SelectionAdapter() {
+
+			@Override
+			public void widgetSelected(final SelectionEvent e) {
+				final Object data = e.item.getData();
+				if (data instanceof ExecutionEntry) {
+					MainWindow.this.handleTracesSelection((ExecutionEntry) data);
+				}
+			}
 
+		});
 	}
 
-	protected void showAggregatedExecutionTraces() {
+	private void showAggregatedExecutionTraces() {
 		// Show the tree
 		this.setVisibleMainComponent(this.sashForm);
 
-		// Reload the data from the model...
-		final List<AggregatedExecutionEntry> traces = this.model.getAggregatedTrace();
-
-		// ...and write it into the tree
-		this.tree_1.setItemCount(traces.size());
-		this.tree_1.setData(traces);
-		this.lblNa.setText(Integer.toString(traces.size()) + " Aggregated Traces");
-		this.lblNa.pack();
-
 		// Resize the columns
-		for (final TreeColumn column : this.tree_1.getColumns()) {
+		for (final TreeColumn column : this.aggregatedTracesTree.getColumns()) {
 			column.pack();
 		}
 	}
 
-	protected void showAggregatedExecutionTracesByContainer() {
-
-	}
-
-	protected void showAggregatedExecutionTracesByComponent() {
-
-	}
-
-	protected void showExecutionTraces() {
+	private void showExecutionTraces() {
 		// Show the tree
 		this.setVisibleMainComponent(this.executionTracesForm);
 
-		// Reload the data from the model...
-		final List<ExecutionEntry> traces = this.model.getTraces();
-
-		// ...and write it into the tree
-		this.executionTracesTree.setItemCount(traces.size());
-		this.executionTracesTree.setData(traces);
-		this.lblNa.setText(Integer.toString(traces.size()) + " Traces");
-		this.lblNa.pack();
-
 		// Resize the columns
-		for (final TreeColumn column : this.executionTracesTree.getColumns()) {
+		for (final TreeColumn column : this.tracesTree.getColumns()) {
 			column.pack();
 		}
 	}
 
-	protected void showRecords() {
+	private void showRecords() {
 		// Show the table
 		this.setVisibleMainComponent(this.recordsTable);
 
-		// Reload the data from the model...
-		final List<RecordEntry> records = this.model.getRecords();
-
-		// ...and write it into the table
-		this.recordsTable.setItemCount(records.size());
-		this.recordsTable.setData(records);
-		this.lblNa.setText(Integer.toString(records.size()) + " Records");
-		this.lblNa.pack();
-
 		// Resize the columns
 		for (final TableColumn column : this.recordsTable.getColumns()) {
 			column.pack();
 		}
 	}
 
-	protected void showOpenMonitoringLogDialog() {
+	private void handleExplorerSelection(final Widget selectedWidget) {
+		if (MainWindow.this.recordsTreeItem == selectedWidget) {
+			MainWindow.this.showRecords();
+		} else if (MainWindow.this.executionTracesTreeItem == selectedWidget) {
+			MainWindow.this.showExecutionTraces();
+		} else if (MainWindow.this.trtmAggregatedExecutionTraces == selectedWidget) {
+			MainWindow.this.showAggregatedExecutionTraces();
+		} else {
+			MainWindow.this.setVisibleMainComponent(null);
+			MainWindow.this.lblNa.setText("");
+		}
+	}
+
+	private void handleTracesSelection(final ExecutionEntry data) {
+		this.lblNa_1.setText(Long.toString(data.getTraceID()));
+		this.lblNa_3.setText(Long.toString(data.getDuration()));
+
+		this.lblNa_4.setText(data.getContainer());
+		this.lblNa_5.setText(data.getComponent());
+		this.lblNa_6.setText(data.getOperation());
+		this.lblNa_7.setText(Integer.toString(data.getStackDepth()));
+
+		if (data.isFailed()) {
+			this.lblNa_2.setText("Yes (" + data.getFailedCause() + ")");
+			this.lblNa_2.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
+			this.lblFailed.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
+		} else {
+			this.lblNa_2.setText("No");
+			this.lblNa_2.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
+			this.lblFailed.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
+		}
+
+		this.lblNa_1.pack();
+		this.lblNa_2.pack();
+		this.lblNa_3.pack();
+		this.lblNa_4.pack();
+		this.lblNa_5.pack();
+		this.lblNa_6.pack();
+		this.lblNa_7.pack();
+	}
+
+	private void reloadFromModel() {
+		// Reload the data from the model...
+		final List<RecordEntry> records = DataSource.getInstance().getRecords();
+		final List<ExecutionEntry> traces = DataSource.getInstance().getTraces();
+		final List<AggregatedExecutionEntry> aggregatedTraces = DataSource.getInstance().getAggregatedTrace();
+
+		// ...and write it into the corresponding widgets
+		MainWindow.this.recordsTable.setItemCount(records.size());
+		MainWindow.this.recordsTable.setData(records);
+
+		MainWindow.this.tracesTree.setItemCount(traces.size());
+		MainWindow.this.tracesTree.setData(traces);
+
+		MainWindow.this.aggregatedTracesTree.setItemCount(aggregatedTraces.size());
+		MainWindow.this.aggregatedTracesTree.setData(aggregatedTraces);
+	}
+
+	private void showOpenMonitoringLogDialog() {
 		final DirectoryDialog dialog = new DirectoryDialog(this.shell);
 		final String selectedDirectory = dialog.open();
 
 		if (null != selectedDirectory) {
-			this.model.loadMonitoringLogFromFS(selectedDirectory);
+			DataSource.getInstance().loadMonitoringLogFromFS(selectedDirectory);
 		}
 	}
 
-	void setVisibleMainComponent(final Control component) {
+	private void setVisibleMainComponent(final Control component) {
 		final StackLayout layout = (StackLayout) this.mainComposite.getLayout();
 		layout.topControl = component;
 
diff --git a/src/main/java/kieker/gui/view/RecordEntryTimestampComparator.java b/src/main/java/kieker/gui/view/RecordEntryTimestampComparator.java
deleted file mode 100644
index 459271526ce2a43e7e3882b3cb8d4767338f082a..0000000000000000000000000000000000000000
--- a/src/main/java/kieker/gui/view/RecordEntryTimestampComparator.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package kieker.gui.view;
-
-import java.util.Comparator;
-
-import kieker.gui.model.RecordEntry;
-
-import org.eclipse.swt.SWT;
-
-class RecordEntryTimestampComparator implements Comparator<RecordEntry> {
-
-	private final int direction;
-
-	public RecordEntryTimestampComparator(final int direction) {
-		this.direction = direction;
-	}
-
-	@Override
-	public int compare(final RecordEntry o1, final RecordEntry o2) {
-		int result = Long.compare(o1.getTimestamp(), o2.getTimestamp());
-		if (this.direction == SWT.UP) {
-			result = -result;
-		}
-		return result;
-	}
-
-}
\ No newline at end of file
diff --git a/src/main/java/kieker/gui/view/RecordEntryTypeComparator.java b/src/main/java/kieker/gui/view/RecordEntryTypeComparator.java
deleted file mode 100644
index 28b80f211f5e75b691b5c4d48e453005c1a0eb19..0000000000000000000000000000000000000000
--- a/src/main/java/kieker/gui/view/RecordEntryTypeComparator.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package kieker.gui.view;
-
-import java.util.Comparator;
-
-import kieker.gui.model.RecordEntry;
-
-import org.eclipse.swt.SWT;
-
-class RecordEntryTypeComparator implements Comparator<RecordEntry> {
-
-	private final int direction;
-
-	public RecordEntryTypeComparator(final int direction) {
-		this.direction = direction;
-	}
-
-	@Override
-	public int compare(final RecordEntry o1, final RecordEntry o2) {
-		int result = o1.getType().compareTo(o2.getType());
-		if (this.direction == SWT.UP) {
-			result = -result;
-		}
-		return result;
-	}
-}
diff --git a/src/main/java/kieker/gui/view/RecordsTableTimestampSortListener.java b/src/main/java/kieker/gui/view/RecordsTableTimestampSortListener.java
deleted file mode 100644
index c5d9d414c21b4d0f73d4664e9492caa168ddc8e3..0000000000000000000000000000000000000000
--- a/src/main/java/kieker/gui/view/RecordsTableTimestampSortListener.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package kieker.gui.view;
-
-import java.util.Collections;
-import java.util.List;
-
-import kieker.gui.model.RecordEntry;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-
-class RecordsTableTimestampSortListener implements Listener {
-
-	@Override
-	public void handleEvent(final Event event) {
-		// Get the necessary information from the event
-		final TableColumn currentColumn = (TableColumn) event.widget;
-		final Table table = currentColumn.getParent();
-		final TableColumn sortColumn = table.getSortColumn();
-
-		// Determine new sort column and direction
-		int direction = table.getSortDirection();
-		if (sortColumn == currentColumn) {
-			direction = ((direction == SWT.UP) ? SWT.DOWN : SWT.UP);
-		} else {
-			table.setSortColumn(currentColumn);
-			direction = SWT.UP;
-		}
-
-		// Sort the data
-		final List<RecordEntry> records = (List<RecordEntry>) table.getData();
-		Collections.sort(records, new RecordEntryTimestampComparator(direction));
-
-		// Update the data displayed in the table
-		table.setSortDirection(direction);
-		table.clearAll();
-	}
-}
\ No newline at end of file
diff --git a/src/main/java/kieker/gui/view/util/AbstractDirectedComparator.java b/src/main/java/kieker/gui/view/util/AbstractDirectedComparator.java
new file mode 100644
index 0000000000000000000000000000000000000000..52a28e6495d6c61f58705e12ac1578c5c233ba65
--- /dev/null
+++ b/src/main/java/kieker/gui/view/util/AbstractDirectedComparator.java
@@ -0,0 +1,17 @@
+package kieker.gui.view.util;
+
+import java.util.Comparator;
+
+public abstract class AbstractDirectedComparator<T> implements Comparator<T> {
+
+	private int direction;
+
+	public int getDirection() {
+		return this.direction;
+	}
+
+	public void setDirection(final int direction) {
+		this.direction = direction;
+	}
+
+}
diff --git a/src/main/java/kieker/gui/view/AggregatedExecutionTracesTreeSetDataListener.java b/src/main/java/kieker/gui/view/util/AggregatedExecutionTracesTreeSetDataListener.java
similarity index 92%
rename from src/main/java/kieker/gui/view/AggregatedExecutionTracesTreeSetDataListener.java
rename to src/main/java/kieker/gui/view/util/AggregatedExecutionTracesTreeSetDataListener.java
index e1a354cb9eee0e4a09c5bc2daa92542907f4b420..8bc0982c90649b34163ff18628a0bf4ab534e687 100644
--- a/src/main/java/kieker/gui/view/AggregatedExecutionTracesTreeSetDataListener.java
+++ b/src/main/java/kieker/gui/view/util/AggregatedExecutionTracesTreeSetDataListener.java
@@ -1,9 +1,9 @@
-package kieker.gui.view;
+package kieker.gui.view.util;
 
 import java.util.List;
 
-import kieker.gui.model.AggregatedExecutionEntry;
 import kieker.gui.model.Properties;
+import kieker.gui.model.domain.AggregatedExecutionEntry;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.Color;
@@ -13,7 +13,7 @@ import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Tree;
 import org.eclipse.swt.widgets.TreeItem;
 
-class AggregatedExecutionTracesTreeSetDataListener implements Listener {
+public class AggregatedExecutionTracesTreeSetDataListener implements Listener {
 
 	@Override
 	public void handleEvent(final Event event) {
diff --git a/src/main/java/kieker/gui/view/ExecutionTracesTreeSetDataListener.java b/src/main/java/kieker/gui/view/util/ExecutionTracesTreeSetDataListener.java
similarity index 90%
rename from src/main/java/kieker/gui/view/ExecutionTracesTreeSetDataListener.java
rename to src/main/java/kieker/gui/view/util/ExecutionTracesTreeSetDataListener.java
index ca8bf61b8a7481956443a6ef665b15f3f09e8fff..51c04188fc72fc5585b746a229697e34001780df 100644
--- a/src/main/java/kieker/gui/view/ExecutionTracesTreeSetDataListener.java
+++ b/src/main/java/kieker/gui/view/util/ExecutionTracesTreeSetDataListener.java
@@ -1,9 +1,9 @@
-package kieker.gui.view;
+package kieker.gui.view.util;
 
 import java.util.List;
 
-import kieker.gui.model.ExecutionEntry;
 import kieker.gui.model.Properties;
+import kieker.gui.model.domain.ExecutionEntry;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.Color;
@@ -13,7 +13,7 @@ import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Tree;
 import org.eclipse.swt.widgets.TreeItem;
 
-class ExecutionTracesTreeSetDataListener implements Listener {
+public class ExecutionTracesTreeSetDataListener implements Listener {
 
 	@Override
 	public void handleEvent(final Event event) {
@@ -48,7 +48,7 @@ class ExecutionTracesTreeSetDataListener implements Listener {
 			operationString = operationString.substring(lastPointPos + 1);
 		}
 		item.setText(new String[] { executionEntry.getContainer(), componentName, operationString, Long.toString(executionEntry.getDuration()),
-				String.format("%.1f%%", executionEntry.getPercent()), traceID });
+			String.format("%.1f%%", executionEntry.getPercent()), traceID });
 
 		if (executionEntry.isFailed()) {
 			final Color colorRed = Display.getCurrent().getSystemColor(SWT.COLOR_RED);
@@ -58,4 +58,4 @@ class ExecutionTracesTreeSetDataListener implements Listener {
 		item.setData(executionEntry);
 		item.setItemCount(executionEntry.getChildren().size());
 	}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/kieker/gui/view/util/RecordEntryTimestampComparator.java b/src/main/java/kieker/gui/view/util/RecordEntryTimestampComparator.java
new file mode 100644
index 0000000000000000000000000000000000000000..2b03ff11bebc2f869f5b18f1fe6c2bdcbefe5d73
--- /dev/null
+++ b/src/main/java/kieker/gui/view/util/RecordEntryTimestampComparator.java
@@ -0,0 +1,18 @@
+package kieker.gui.view.util;
+
+import kieker.gui.model.domain.RecordEntry;
+
+import org.eclipse.swt.SWT;
+
+public class RecordEntryTimestampComparator extends AbstractDirectedComparator<RecordEntry> {
+
+	@Override
+	public int compare(final RecordEntry o1, final RecordEntry o2) {
+		int result = Long.compare(o1.getTimestamp(), o2.getTimestamp());
+		if (this.getDirection() == SWT.UP) {
+			result = -result;
+		}
+		return result;
+	}
+
+}
diff --git a/src/main/java/kieker/gui/view/util/RecordEntryTypeComparator.java b/src/main/java/kieker/gui/view/util/RecordEntryTypeComparator.java
new file mode 100644
index 0000000000000000000000000000000000000000..611a46f8f6e872e615c7cca3868afff31c03af42
--- /dev/null
+++ b/src/main/java/kieker/gui/view/util/RecordEntryTypeComparator.java
@@ -0,0 +1,18 @@
+package kieker.gui.view.util;
+
+import kieker.gui.model.domain.RecordEntry;
+
+import org.eclipse.swt.SWT;
+
+public class RecordEntryTypeComparator extends AbstractDirectedComparator<RecordEntry> {
+
+	@Override
+	public int compare(final RecordEntry o1, final RecordEntry o2) {
+		int result = o1.getType().compareTo(o2.getType());
+		if (this.getDirection() == SWT.UP) {
+			result = -result;
+		}
+		return result;
+	}
+
+}
diff --git a/src/main/java/kieker/gui/view/RecordsTableSetDataListener.java b/src/main/java/kieker/gui/view/util/RecordsTableSetDataListener.java
similarity index 86%
rename from src/main/java/kieker/gui/view/RecordsTableSetDataListener.java
rename to src/main/java/kieker/gui/view/util/RecordsTableSetDataListener.java
index 2bd108bac453c7b4d05dd9a7709af90a9ca171e0..797d90b4b196b9ce9e2af7ce7b06b5d99cf4ebb1 100644
--- a/src/main/java/kieker/gui/view/RecordsTableSetDataListener.java
+++ b/src/main/java/kieker/gui/view/util/RecordsTableSetDataListener.java
@@ -1,15 +1,15 @@
-package kieker.gui.view;
+package kieker.gui.view.util;
 
 import java.util.List;
 
-import kieker.gui.model.RecordEntry;
+import kieker.gui.model.domain.RecordEntry;
 
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Table;
 import org.eclipse.swt.widgets.TableItem;
 
-class RecordsTableSetDataListener implements Listener {
+public class RecordsTableSetDataListener implements Listener {
 
 	@Override
 	public void handleEvent(final Event event) {
diff --git a/src/main/java/kieker/gui/view/RecordsTableTypeSortListener.java b/src/main/java/kieker/gui/view/util/TableColumnSortListener.java
similarity index 68%
rename from src/main/java/kieker/gui/view/RecordsTableTypeSortListener.java
rename to src/main/java/kieker/gui/view/util/TableColumnSortListener.java
index 5f0135cd08779415c296734251669e217cd03128..11dca9254c438676e883e6b91d4ce4684db40139 100644
--- a/src/main/java/kieker/gui/view/RecordsTableTypeSortListener.java
+++ b/src/main/java/kieker/gui/view/util/TableColumnSortListener.java
@@ -1,17 +1,21 @@
-package kieker.gui.view;
+package kieker.gui.view.util;
 
 import java.util.Collections;
 import java.util.List;
 
-import kieker.gui.model.RecordEntry;
-
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Table;
 import org.eclipse.swt.widgets.TableColumn;
 
-class RecordsTableTypeSortListener implements Listener {
+public final class TableColumnSortListener<T> implements Listener {
+
+	private final AbstractDirectedComparator<T> comparator;
+
+	public TableColumnSortListener(final AbstractDirectedComparator<T> comparator) {
+		this.comparator = comparator;
+	}
 
 	@Override
 	public void handleEvent(final Event event) {
@@ -30,11 +34,13 @@ class RecordsTableTypeSortListener implements Listener {
 		}
 
 		// Sort the data
-		final List<RecordEntry> records = (List<RecordEntry>) table.getData();
-		Collections.sort(records, new RecordEntryTypeComparator(direction));
+		this.comparator.setDirection(direction);
+		final List<T> entries = (List<T>) table.getData();
+		Collections.sort(entries, this.comparator);
 
 		// Update the data displayed in the table
 		table.setSortDirection(direction);
 		table.clearAll();
 	}
+
 }