/*******************************************************************************
 * Copyright (c) 2015 Christian Pontesegger and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Christian Pontesegger - initial API and implementation
 *******************************************************************************/
package org.eclipse.ease.modules.unittest.ui.views;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.ease.debugging.IScriptDebugFrame;
import org.eclipse.ease.modules.platform.UIModule;
import org.eclipse.ease.modules.unittest.ITestListener;
import org.eclipse.ease.modules.unittest.components.Test;
import org.eclipse.ease.modules.unittest.components.TestComposite;
import org.eclipse.ease.modules.unittest.components.TestFile;
import org.eclipse.ease.modules.unittest.components.TestResult;
import org.eclipse.ease.modules.unittest.components.TestStatus;
import org.eclipse.ease.modules.unittest.components.TestSuite;
import org.eclipse.ease.modules.unittest.components.TestSuiteModel;
import org.eclipse.ease.modules.unittest.ui.Activator;
import org.eclipse.ease.modules.unittest.ui.sourceprovider.TestSuiteSource;
import org.eclipse.ease.ui.console.ScriptConsole;
import org.eclipse.ease.ui.tools.DecoratedLabelProvider;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.layout.TreeColumnLayout;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleListener;
import org.eclipse.ui.handlers.CollapseAllHandler;
import org.eclipse.ui.handlers.ExpandAllHandler;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.texteditor.ITextEditor;

public class UnitTestView extends ViewPart implements ITestListener, IConsoleListener {
	public static final String VIEW_ID = "org.eclipse.ease.views.unittest";

	public static final String TEST_STATUS_PROPERTY = "test status";

	private static class Statistics {
		private final Map<Object, Integer> mCounters = new HashMap<>();

		public synchronized void updateCounter(final Object identifier, final int value) {
			if (mCounters.containsKey(identifier))
				mCounters.put(identifier, mCounters.get(identifier) + value);
			else
				mCounters.put(identifier, value);
		}

		public void reset() {
			mCounters.clear();
		}

		public synchronized int getCounter(final Object identifier) {
			if (mCounters.containsKey(identifier))
				return mCounters.get(identifier);

			return 0;
		}
	}

	private static final String XML_CURRENT_SUITE = "currentSuite";

	private static final Object STATISTICS_TESTFILES_FINISHED = "testFiles";

	private static final Object STATISTICS_TEST_ERROR = "test errors";

	private static final Object STATISTICS_TEST_FAILURE = "test failures";

	private static final Object STATISTICS_TEST_VALID = "valid tests";

	private static final Object STATISTICS_TESTFILE_COUNT = "testFile count";

	private static final Object STATISTICS_TEST_FINISHED = "test count";

	private ProgressBar fProgressBar;
	private TreeViewer fFileTreeViewer;
	private TreeViewer fTestTreeViewer;
	private SashForm sashForm;

	private int[] fSashWeights = new int[] { 70, 30 };

	private IMemento mMemento;

	private CollapseAllHandler mCollapseAllHandler;

	private ExpandAllHandler mExpandAllHandler;

	private Label lblTimeLeftText;

	private LocalResourceManager fResourceManager;

	private final UpdateUI fUIUpdater = new UpdateUI();
	private final Statistics fStatistics = new Statistics();

	private Label lblErrorCount;
	private Label lblFailureCount;

	private SuiteRuntimeInformation fRuntimeInformation = null;
	private Label lblTimeLeft;
	private ScriptConsole fConsole = null;

	public UnitTestView() {
	}

	@Override
	public void init(final IViewSite site, final IMemento memento) throws PartInitException {
		mMemento = memento;
		super.init(site, memento);
	}

	@Override
	public void createPartControl(final Composite parent) {
		parent.setLayout(new GridLayout(1, false));

		final Composite composite = new Composite(parent, SWT.NONE);
		composite.setLayout(new GridLayout(8, false));
		composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		fResourceManager = new LocalResourceManager(JFaceResources.getResources(), composite);

		final Label lblErrorIcon = new Label(composite, SWT.NONE);
		final GridData gdLblErrorIcon = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gdLblErrorIcon.horizontalIndent = 50;
		lblErrorIcon.setLayoutData(gdLblErrorIcon);
		lblErrorIcon.setImage(fResourceManager.createImage(Activator.getImageDescriptor(Activator.ICON_ERROR)));

		final Label lblErrors = new Label(composite, SWT.NONE);
		lblErrors.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblErrors.setAlignment(SWT.CENTER);
		lblErrors.setText("Errors:");

		lblErrorCount = new Label(composite, SWT.NONE);
		final GridData gd_lblErrorCount = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1);
		gd_lblErrorCount.horizontalIndent = 20;
		lblErrorCount.setLayoutData(gd_lblErrorCount);

		final Label lblFailureIcon = new Label(composite, SWT.NONE);
		final GridData gdLblFailureIcon = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gdLblFailureIcon.horizontalIndent = 50;
		lblFailureIcon.setLayoutData(gdLblFailureIcon);
		lblFailureIcon.setImage(fResourceManager.createImage(Activator.getImageDescriptor(Activator.ICON_FAILURE)));

		final Label lblFailures = new Label(composite, SWT.NONE);
		lblFailures.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblFailures.setAlignment(SWT.CENTER);
		lblFailures.setText("Failures:");

		lblFailureCount = new Label(composite, SWT.NONE);
		final GridData gdLblFailureCount = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1);
		gdLblFailureCount.horizontalIndent = 20;
		lblFailureCount.setLayoutData(gdLblFailureCount);

		lblTimeLeftText = new Label(composite, SWT.NONE);
		final GridData gdLabel = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gdLabel.horizontalIndent = 50;
		lblTimeLeftText.setLayoutData(gdLabel);
		lblTimeLeftText.setText("Time left: ");
		lblTimeLeftText.setVisible(false);

		lblTimeLeft = new Label(composite, SWT.NONE);
		final GridData gdLblTimeLeft = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gdLblTimeLeft.horizontalIndent = 20;
		lblTimeLeft.setLayoutData(gdLblTimeLeft);
		lblTimeLeft.setVisible(false);

		fProgressBar = new ProgressBar(parent, SWT.NONE);
		fProgressBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		sashForm = new SashForm(parent, SWT.NONE);
		sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		sashForm.setOrientation(SWT.VERTICAL);

		fFileTreeViewer = new TreeViewer(sashForm, SWT.BORDER | SWT.MULTI);
		fFileTreeViewer.setContentProvider(new TestSuiteContentProvider());

		fFileTreeViewer.setComparator(new ViewerComparator() {
			@Override
			public final int category(final Object element) {
				if (element instanceof TestFile)
					return 1;

				return 0;
			}
		});

		// use a decorated label provider
		final LabelProvider provider = new TestSuiteLabelProvider(fResourceManager);
		fFileTreeViewer.setLabelProvider(new DecoratedLabelProvider(provider));

		fFileTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
			@Override
			public void doubleClick(final DoubleClickEvent event) {
				try {
					final Object element = ((IStructuredSelection) event.getSelection()).getFirstElement();
					if (element instanceof TestFile) {
						final Object file = ((TestFile) element).getFile();
						if (file instanceof IFile)
							UIModule.showEditor((IFile) ((TestFile) element).getFile());

					} else if (element instanceof TestSuite)
						UIModule.showEditor(((TestSuite) element).getModel().getFile());

				} catch (final Throwable e) {
					// TODO handle this exception (but for now, at least know it happened)
					throw new RuntimeException(e);

				}
			}
		});
		fFileTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {

			@Override
			public void selectionChanged(final SelectionChangedEvent event) {
				final ITreeSelection selection = (ITreeSelection) event.getSelection();
				final Object element = selection.getFirstElement();

				if (element instanceof TestComposite) {
					// test set selected
					fTestTreeViewer.setInput(element);

					if (sashForm.getWeights()[1] == 0)
						sashForm.setWeights(fSashWeights);

					fTestTreeViewer.refresh();

				} else {
					// test container selected, or no selection at all
					fTestTreeViewer.setInput(null);

					if (sashForm.getWeights()[1] != 0)
						fSashWeights = sashForm.getWeights();

					sashForm.setWeights(new int[] { 100, 0 });
				}
			}
		});

		// create tree viewer for tests
		fTestTreeViewer = createTestArea(sashForm);

		sashForm.setWeights(new int[] { 1, 1 });

		// add context menu support
		final MenuManager menuManager = new MenuManager();
		final Menu menu = menuManager.createContextMenu(fFileTreeViewer.getTree());
		fFileTreeViewer.getTree().setMenu(menu);
		getSite().registerContextMenu(menuManager, fFileTreeViewer);

		final MenuManager menuManager2 = new MenuManager();
		final Menu menu2 = menuManager2.createContextMenu(fFileTreeViewer.getTree());
		fTestTreeViewer.getTree().setMenu(menu2);
		getSite().registerContextMenu(menuManager2, fTestTreeViewer);

		// add collapseAll/expandAll handlers
		final IHandlerService handlerService = getSite().getService(IHandlerService.class);
		mCollapseAllHandler = new CollapseAllHandler(fFileTreeViewer);
		handlerService.activateHandler(CollapseAllHandler.COMMAND_ID, mCollapseAllHandler);
		mExpandAllHandler = new ExpandAllHandler(fFileTreeViewer);
		handlerService.activateHandler(ExpandAllHandler.COMMAND_ID, mExpandAllHandler);

		// menuManager.setRemoveAllWhenShown(true);

		// load last suite
		if (mMemento != null) {
			final IMemento currentSuiteNode = mMemento.getChild(XML_CURRENT_SUITE);
			if (currentSuiteNode != null) {
				final Path path = new Path(currentSuiteNode.getTextData());
				final IFile suiteFile = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
				try {
					loadSuite(new TestSuite(new TestSuiteModel(suiteFile)));
				} catch (final Exception e) {
					// loading failed, ignore
				}
			}
		}

		// register for console events
		ConsolePlugin.getDefault().getConsoleManager().addConsoleListener(UnitTestView.this);

		final MultiSelectionProvider selectionProvider = new MultiSelectionProvider();
		selectionProvider.addSelectionProvider(fFileTreeViewer);
		selectionProvider.addSelectionProvider(fTestTreeViewer);

		getSite().setSelectionProvider(selectionProvider);
	}

	private TreeViewer createTestArea(final Composite parent) {
		final Composite composite = new Composite(parent, SWT.NONE);
		final TreeColumnLayout layout = new TreeColumnLayout();
		composite.setLayout(layout);

		final TreeViewer viewer = new TreeViewer(composite, SWT.BORDER | SWT.FULL_SELECTION);
		viewer.addDoubleClickListener(new IDoubleClickListener() {

			@Override
			public void doubleClick(final DoubleClickEvent event) {
				final Object element = ((IStructuredSelection) event.getSelection()).getFirstElement();
				if (element instanceof Test) {

					List<IScriptDebugFrame> trace;
					final List<TestResult> messages = ((Test) element).getMessages();
					if ((messages != null) && (!messages.isEmpty()))
						trace = messages.get(0).getStackTrace();
					else
						trace = ((Test) element).getTestLocation();

					if (trace != null) {
						// open trace location
						for (final IScriptDebugFrame traceElement : trace) {
							final Object file = traceElement.getScript().getFile();
							if (file instanceof IFile) {
								if (((IFile) file).exists()) {
									try {
										final int line = Math.max(traceElement.getLineNumber(), 1);
										final ITextEditor textEditor = (ITextEditor) UIModule.showEditor((IFile) file);
										final IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
										try {
											textEditor.selectAndReveal(document.getLineOffset(line - 1), document.getLineLength(line - 1));
										} catch (final BadLocationException e) {
											// TODO implement
											throw new RuntimeException(e);
										}
									} catch (final Throwable e) {
										// TODO handle this exception (but for now, at least know it happened)
										throw new RuntimeException(e);

									}

									break;
								}
							}
						}

					} else {
						// we do not have a trace, open test set
						final Object input = viewer.getInput();
						if (input instanceof TestFile) {

							try {
								final Object file = ((TestFile) input).getFile();
								if (file instanceof IFile)
									UIModule.showEditor((IFile) ((TestFile) input).getFile());

							} catch (final Throwable e) {
								// TODO handle this exception (but for now, at least know it happened)
								throw new RuntimeException(e);

							}
						}
					}
				}
			}
		});

		viewer.getTree().setHeaderVisible(true);
		viewer.getTree().setLinesVisible(true);

		viewer.setContentProvider(new TestFileContentProvider());

		final TreeViewerColumn testColumn = new TreeViewerColumn(viewer, SWT.NONE);
		testColumn.getColumn().setWidth(100);
		testColumn.getColumn().setText("Test");
		layout.setColumnData(testColumn.getColumn(), new ColumnWeightData(30, 50, true));
		testColumn.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(final Object element) {
				if (element instanceof Test)
					return ((Test) element).getTitle();

				if (element instanceof Entry<?, ?>)
					// metadata
					return ((Entry<?, ?>) element).getKey().toString();

				return "";
			}

			@Override
			public Image getImage(final Object element) {

				if (element instanceof Entry<?, ?>)
					// metadata
					return fResourceManager.createImage(Activator.getImageDescriptor(Activator.ICON_METADATA));

				TestStatus status = null;
				if (element instanceof Test)
					status = ((Test) element).getStatus();
				else if (element instanceof TestResult)
					status = ((TestResult) element).getStatus();

				if (status != null) {
					switch (status) {
					case PASS:
						return fResourceManager.createImage(Activator.getImageDescriptor(Activator.ICON_PASS));
					case ERROR:
						return fResourceManager.createImage(Activator.getImageDescriptor(Activator.ICON_ERROR));
					case FAILURE:
						return fResourceManager.createImage(Activator.getImageDescriptor(Activator.ICON_FAILURE));
					case RUNNING:
						return fResourceManager.createImage(Activator.getImageDescriptor(Activator.ICON_RUNNING));
					default:
						return super.getImage(element);
					}
				}

				return super.getImage(element);
			}

			@Override
			public String getToolTipText(final Object element) {
				if (element instanceof Test) {
					if ((((Test) element).getDescription() != null) && (!((Test) element).getDescription().isEmpty()))
						return ((Test) element).getDescription();
				}

				return super.getToolTipText(element);
			}
		});

		final TreeViewerColumn messageColumn = new TreeViewerColumn(viewer, SWT.NONE);
		messageColumn.getColumn().setWidth(100);
		messageColumn.getColumn().setText("Message");
		layout.setColumnData(messageColumn.getColumn(), new ColumnWeightData(70, 50, true));
		messageColumn.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(final Object element) {
				if (element instanceof Test) {
					final TestResult message = ((Test) element).getSeverestMessage();
					if (message != null)
						return message.getDescription();

					return ((Test) element).getDescription();
				}

				if (element instanceof Entry<?, ?>)
					// metadata
					return ((Entry<?, ?>) element).getValue().toString();

				return super.getText(element);
			}
		});

		ColumnViewerToolTipSupport.enableFor(viewer, ToolTip.NO_RECREATE);

		return viewer;
	}

	@Override
	public void setFocus() {
		// nothing to do
	}

	public TreeViewer getFileTreeViewer() {
		return fFileTreeViewer;
	}

	private class UpdateUI extends UIJob {

		private final List<Object> fElements = new ArrayList<>();

		public UpdateUI() {
			super("Update Script Unit View");
		}

		public void addElement(final Object element) {
			synchronized (fElements) {
				if (fElements.isEmpty()) {
					// we might have added the same element again, so we cannot check for size() == 1 afterwards
					fElements.add(element);
					schedule(300);
				} else
					fElements.add(element);
			}
		}

		@Override
		public IStatus runInUIThread(final IProgressMonitor monitor) {
			// create a local copy of elements so we can continue tests without waiting for the UI updater
			ArrayList<Object> localElements;
			synchronized (fElements) {
				localElements = new ArrayList<>(fElements);
				fElements.clear();
			}

			// update tree elements
			for (final Object element : localElements) {
				TestComposite affectedComposite = null;
				if (element instanceof Test)
					affectedComposite = ((Test) element).getParent();

				else if (element instanceof TestComposite)
					affectedComposite = (TestComposite) element;

				while (affectedComposite != null) {
					// update tree element and all its parents (no folders)
					fFileTreeViewer.update(affectedComposite, new String[] { TEST_STATUS_PROPERTY });
					affectedComposite = affectedComposite.getParent();
				}
			}

			// update table
			if (fTestTreeViewer.getInput() != null) {
				// update only if tableviewer is visible at all
				for (final Object element : localElements) {
					if (element instanceof Test) {
						final TestComposite testComposite = ((Test) element).getParent();

						if (fTestTreeViewer.getInput().equals(testComposite)) {
							fTestTreeViewer.refresh();
							// TODO scroll to last element

							// one refresh is enough for the whole table, so bail out
							break;
						}
					}
				}
			}

			// update statistics
			if (!fProgressBar.isDisposed()) {

				lblErrorCount.setText(Integer.toString(fStatistics.getCounter(STATISTICS_TEST_ERROR)));
				lblFailureCount.setText(Integer.toString(fStatistics.getCounter(STATISTICS_TEST_FAILURE)));
				lblFailureCount.getParent().layout();

				fProgressBar.setSelection(fStatistics.getCounter(STATISTICS_TESTFILES_FINISHED));
				lblTimeLeft.setText(getEstimatedTime());

				if ((fStatistics.getCounter(STATISTICS_TEST_ERROR) > 0) || (fStatistics.getCounter(STATISTICS_TEST_FAILURE) > 0))
					fProgressBar.setForeground(fResourceManager.createColor(new RGB(0xaa, 0, 0)));

				else if (fStatistics.getCounter(STATISTICS_TESTFILES_FINISHED) == fStatistics.getCounter(STATISTICS_TESTFILE_COUNT)) {
					if ((fStatistics.getCounter(STATISTICS_TEST_ERROR) == 0) && (fStatistics.getCounter(STATISTICS_TEST_FAILURE) == 0))
						fProgressBar.setForeground(fResourceManager.createColor(new RGB(0, 0xaa, 0)));
				}
			}

			synchronized (fElements) {
				if (!fElements.isEmpty())
					schedule(1000);
			}

			return Status.OK_STATUS;
		}

		private String getEstimatedTime() {
			if (getCurrentSuite().getStatus() != TestStatus.RUNNING) {
				lblTimeLeft.setVisible(false);
				lblTimeLeftText.setVisible(false);
				return "";
			}

			if (fRuntimeInformation != null) {
				final long time = fRuntimeInformation.getEstimatedTestTime();

				if (time < 0)
					return "calculating...";

				if (time < 60000)
					return new SimpleDateFormat("ss 'seconds'").format(time);

				if (time < 3600000)
					return new SimpleDateFormat("mm:ss").format(time);

				return new SimpleDateFormat("hh:mm:ss").format(time);
			}

			return "unknown";
		}
	}

	@Override
	public void notify(final Object testObject, final TestStatus status) {
		if ((testObject instanceof TestSuite) && (status == TestStatus.RUNNING)) {

			Display.getDefault().syncExec(new Runnable() {

				@Override
				public void run() {
					try {
						loadSuite((TestSuite) testObject);
					} catch (final Exception e) {
						// TODO handle this exception (but for now, at least know it happened)
						throw new RuntimeException(e);
					}

					fStatistics.reset();
					fStatistics.updateCounter(STATISTICS_TESTFILE_COUNT, ((TestSuite) testObject).getActiveTestCount());

					// initialize progress bar
					fProgressBar.setMaximum(fStatistics.getCounter(STATISTICS_TESTFILE_COUNT));
					fProgressBar.setSelection(0);
					fProgressBar.setForeground(null);

					// create console
					if (fConsole == null)
						fConsole = ScriptConsole.create(testObject.toString(), null);

					// clear & attach to suite
					fConsole.clearConsole();
					fConsole.activate();
					((TestSuite) testObject).setOutputStream(fConsole.getOutputStream());
					((TestSuite) testObject).setErrorStream(fConsole.getErrorStream());
					((TestSuite) testObject).setErrorStream(fConsole.getInputStream());

					// update estimated runtime
					lblTimeLeft.setVisible(true);
					lblTimeLeftText.setVisible(true);
				}
			});

		} else {
			// update statistics
			if ((status != TestStatus.RUNNING) && (status != TestStatus.NOT_RUN)) {
				// test finished

				if (testObject instanceof Test) {
					// do not track when this is a temporary tests in test count
					if (!((Test) testObject).isTransient())
						fStatistics.updateCounter(STATISTICS_TEST_FINISHED, 1);

					// do not track when this is a temporary test that passed
					if ((!((Test) testObject).isTransient()) || (!((Test) testObject).getMessages().isEmpty())) {

						switch (status) {
						case FAILURE:
							fStatistics.updateCounter(STATISTICS_TEST_FAILURE, 1);
							break;
						case ERROR:
							fStatistics.updateCounter(STATISTICS_TEST_ERROR, 1);
							break;
						case PASS:
							// do not track when global test file scope is valid
							fStatistics.updateCounter(STATISTICS_TEST_VALID, 1);
							break;
						default:
							// nothing to do
							break;
						}
					}

				} else if (testObject instanceof TestFile) {
					fStatistics.updateCounter(STATISTICS_TESTFILES_FINISHED, 1);
				}
			}
		}

		fUIUpdater.addElement(testObject);
	}

	public StructuredViewer getTableViewer() {
		return fTestTreeViewer;
	}

	@Override
	public void saveState(final IMemento memento) {
		final TestSuite suite = getCurrentSuite();

		if (suite != null) {
			final IFile file = suite.getModel().getFile();

			if ((file != null) && (file.exists())) {
				// we finally detected the current test suite
				memento.createChild(XML_CURRENT_SUITE).putTextData(file.getFullPath().toString());
			}
		}

		super.saveState(memento);
	}

	public TestSuite getCurrentSuite() {
		final Object input = fFileTreeViewer.getInput();
		if (input instanceof Object[]) {
			if (((Object[]) input).length > 0) {
				final Object suite = ((Object[]) input)[0];
				if (suite instanceof TestSuite)
					return (TestSuite) suite;
			}
		}

		return null;
	}

	/**
	 * Loads a suite file and populates the treeview. Needs to be called from UIThread.
	 *
	 * @param suite
	 *            testSuite
	 * @return
	 * @throws IOException
	 *             cannot read from suite file
	 * @throws CoreException
	 *             invalid data within suite file
	 */
	public void loadSuite(final TestSuite suite) throws IOException, CoreException {
		// save current suite
		final TestSuite currentSuite = getCurrentSuite();
		if (!suite.equals(currentSuite)) {
			if (currentSuite != null) {
				Activator.getDefault().addRecentFile(currentSuite.getModel().getFile());

				// save timing information
				if (fRuntimeInformation != null)
					fRuntimeInformation.save();

				// clear data to minimize memory footprint in eclipse caches
				currentSuite.reset();
			}

			fFileTreeViewer.setInput(new Object[] { suite });
			fRuntimeInformation = new SuiteRuntimeInformation(suite);

			// update source provider
			final TestSuiteSource instance = TestSuiteSource.getActiveInstance();
			if (instance != null)
				instance.setActiveSuite(suite);

			suite.addTestListener(this);

			// refresh console
			if (fConsole != null) {
				fConsole.terminate();
				fConsole = null;
			}
		}

		fFileTreeViewer.refresh();
		fFileTreeViewer.expandAll();
	}

	@Override
	public void dispose() {
		// unregister from console events
		ConsolePlugin.getDefault().getConsoleManager().removeConsoleListener(this);

		// dispose handlers
		mCollapseAllHandler.dispose();
		mExpandAllHandler.dispose();

		// save current suite
		final TestSuite currentSuite = getCurrentSuite();
		if (currentSuite != null)
			Activator.getDefault().addRecentFile(currentSuite.getModel().getFile());

		// save timing information
		if (fRuntimeInformation != null)
			fRuntimeInformation.save();

		// allow for garbage collection as eclipse does not clean up views correctly on clode
		fRuntimeInformation = null;
		final TestSuiteSource instance = TestSuiteSource.getActiveInstance();
		if (instance != null)
			instance.setActiveSuite(null);

		fFileTreeViewer.setInput(new Object[0]);

		// clear data to minimize memory footprint in eclipse caches
		if (currentSuite != null)
			currentSuite.reset();

		super.dispose();
	}

	@Override
	public void consolesAdded(final IConsole[] consoles) {
		// nothing to do
	}

	@Override
	public void consolesRemoved(final IConsole[] consoles) {
		for (final IConsole console : consoles) {
			if (console.equals(fConsole))
				fConsole = null;
		}
	}
}
